/*
Theme Name: Mangorivo
Theme URI: https://mangorivo.de
Description: Mangorivo child theme for Kadence. Design system, motion language and WooCommerce overrides for a curated product-discovery shop.
Author: Mangorivo
Template: kadence
Version: 0.1.0
Text Domain: mangorivo
*/

/* ==========================================================================
   1. TOKENS
   Palette taken from design/mainpage01.png: white/cream ground, deep forest
   green for headings and dark actions, mango orange for the primary call to
   action, pastel tints behind category art.
   ========================================================================== */

/* Palette aligned to design-tokens.json from the supplied asset kit. Two of its
   values are deliberately NOT adopted; both are recorded in
   design/REFERENCE-SPEC.md and repeated at the point of use below. */
:root {
  /* brand -- kit `ink` and `primary` */
  --mg-green: #0b2923;
  --mg-green-dk: #061d18;
  --mg-green-lt: #1b4036;
  --mg-orange: #ff8215;
  --mg-orange-dk: #ea6d00;
  --mg-orange-lt: #ffa252;

  /* neutrals -- kit `canvas`, `surface`, `soft`, `sage` */
  --mg-white: #ffffff;
  --mg-cream: #fffcf7;
  --mg-cream-2: #fff0dd;
  --mg-sage: #eaf2e8;
  --mg-ink: #0b2923;
  /* Darkened from #6e7b74. That value measured 4.42:1 on white and 4.19:1 on
     --mg-cream-2, i.e. it failed AA for small text on every surface the site
     actually uses it on -- newsletter copy, promo leads, card meta. Same hue,
     same role, just dark enough to be legal at 13px on all four of them --
     white, --mg-cream, --mg-cream-2 and the mint of .mg-promo--green, which
     is the tightest of the set.

     The asset kit specifies #69736D for this role. Measured against its own
     surfaces that reaches only 4.39:1 on `soft` and 4.30:1 on `sage`, so it
     fails AA for body text on two of the four surfaces the kit itself uses.
     This value clears all of them at 5.08-5.81:1 and stays. */
  --mg-muted: #5c6862;
  --mg-line: #ecece5;

  /* category tints, matching the concept's six tiles */
  --mg-tint-1: #eaf0f6;
  --mg-tint-2: #fdf3e3;
  --mg-tint-3: #fdeee6;
  --mg-tint-4: #e8f2f0;
  --mg-tint-5: #fdf0dd;
  --mg-tint-6: #e7f3e9;

  /* semantic — these are what components read, so the dark theme only has to
     repoint this block */
  --mg-page: var(--mg-white);
  --mg-surface: var(--mg-white);
  --mg-surface-2: var(--mg-cream);
  --mg-text: var(--mg-ink);
  --mg-text-2: var(--mg-muted);
  --mg-head: var(--mg-green);
  --mg-border: var(--mg-line);
  --mg-shadow-1: 0 1px 2px rgba(31, 42, 36, 0.05);
  --mg-shadow-2: 0 6px 18px -8px rgba(31, 42, 36, 0.16);
  --mg-shadow-3: 0 16px 38px -14px rgba(31, 42, 36, 0.26);

  /* radii */
  --mg-r-sm: 10px;
  --mg-r-md: 16px;
  --mg-r-lg: 22px;
  --mg-r-pill: 999px;
  --mg-ph-hi: rgba(255, 255, 255, 0.75);

  /* ------------------------------------------------------------------
     2. MOTION TOKENS
     The five tiers from the motion brief, as variables, so nothing on the
     site invents its own timing.
     ------------------------------------------------------------------ */
  --mg-t-micro: 150ms; /* buttons, icons, hover states       */
  --mg-t-ui: 280ms; /* cards, menus, search, dropdowns    */
  --mg-t-reveal: 780ms; /* scroll-triggered sections          */
  --mg-t-breathe: 500ms; /* image zoom under a hovered card    */
  --mg-t-hero: 800ms; /* initial visual entrance            */
  /* 400ms was long enough to be felt as latency rather than read as motion.
     A cross-document transition plays AFTER the new document is ready, so its
     duration is added to the server time on every navigation -- it is the one
     animation on the site that competes directly with page speed. */
  --mg-t-page: 220ms; /* page transitions                   */

  --mg-ease: cubic-bezier(0.22, 1, 0.36, 1);
  --mg-ease-soft: cubic-bezier(0.4, 0, 0.2, 1);
  --mg-ease-spring: cubic-bezier(0.34, 1.36, 0.64, 1);
}

/* ==========================================================================
   3. DARK THEME
   Three states: explicit dark, explicit light, and the un-stamped default
   where only prefers-color-scheme decides.
   ========================================================================== */

:root[data-theme="dark"] {
  --mg-page: #031e18;
  --mg-surface: #0a2921;
  --mg-surface-2: #173b2d;
  --mg-text: #fff8e9;
  --mg-text-2: #b3c3b8;
  --mg-head: #fff8e9;
  --mg-border: #285040;
  --mg-sage: #16382b;
  --mg-cream: #0a2921;
  --mg-cream-2: #173b2d;
  --mg-white: #0a2921;
  --mg-green: #a4d3b4;
  --mg-green-dk: #88bc9a;
  --mg-green-lt: #c2e4cd;
  --mg-orange: #ff8b19;
  --mg-orange-dk: #ffab5c;

  --mg-tint-1: #22383a;
  --mg-tint-2: #303b2f;
  --mg-tint-3: #3b332c;
  --mg-tint-4: #234039;
  --mg-tint-5: #3b392b;
  --mg-tint-6: #2c4233;

  --mg-shadow-1: 0 1px 2px rgba(0, 0, 0, 0.4);
  --mg-shadow-2: 0 6px 18px -8px rgba(0, 0, 0, 0.6);
  --mg-shadow-3: 0 16px 38px -14px rgba(0, 0, 0, 0.7);
  --mg-ph-hi: rgba(255, 255, 255, 0.07);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --mg-page: #031e18;
    --mg-surface: #0a2921;
    --mg-surface-2: #173b2d;
    --mg-text: #fff8e9;
    --mg-text-2: #b3c3b8;
    --mg-head: #fff8e9;
    --mg-border: #285040;
    --mg-sage: #16382b;
    --mg-cream: #0a2921;
    --mg-cream-2: #173b2d;
    --mg-white: #0a2921;
    --mg-green: #a4d3b4;
    --mg-green-dk: #88bc9a;
    --mg-green-lt: #c2e4cd;
    --mg-orange: #ff8b19;
    --mg-orange-dk: #ffab5c;

    --mg-tint-1: #22383a;
    --mg-tint-2: #303b2f;
    --mg-tint-3: #3b332c;
    --mg-tint-4: #234039;
    --mg-tint-5: #3b392b;
    --mg-tint-6: #2c4233;

    --mg-shadow-1: 0 1px 2px rgba(0, 0, 0, 0.4);
    --mg-shadow-2: 0 6px 18px -8px rgba(0, 0, 0, 0.6);
    --mg-shadow-3: 0 16px 38px -14px rgba(0, 0, 0, 0.7);
    --mg-ph-hi: rgba(255, 255, 255, 0.07);
  }
}

/* ==========================================================================
   4. BASE
   ========================================================================== */

body.mg {
  background: var(--mg-page);
  color: var(--mg-text);
  font-family: "Poppins", "Hanken Grotesk", system-ui, -apple-system, sans-serif;
  -webkit-font-smoothing: antialiased;
}

.mg h1,
.mg h2,
.mg h3,
.mg h4 {
  color: var(--mg-head);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.12;
  text-wrap: balance;
}

.mg-wrap {
  width: 100%;
  max-width: 1200px;
  margin-inline: auto;
  padding-inline: clamp(1rem, 4vw, 2rem);
}

.mg-section {
  padding-block: clamp(2rem, 5vw, 3.5rem);
}

.mg-sec-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: clamp(1rem, 2.5vw, 1.6rem);
}

.mg-sec-head h2 {
  font-size: clamp(1.35rem, 2.6vw, 1.85rem);
}

.mg-sec-head a {
  color: var(--mg-text-2);
  font-size: 0.88rem;
  font-weight: 500;
  text-decoration: none;
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
}

.mg-sec-head a:hover {
  color: var(--mg-green);
}

.mg-sec-head a svg {
  width: 14px;
  height: 14px;
  transition: transform var(--mg-t-ui) var(--mg-ease-spring);
}

.mg-sec-head a:hover svg {
  transform: translateX(4px);
}

/* ==========================================================================
   5. BUTTONS
   Note: white on #f5821f is ~2.9:1 and fails AA. Dark ink on the same orange
   is 5.4:1 and keeps the concept's bright accent, so the accent colour is
   preserved and only the label colour changes.
   ========================================================================== */

.mg-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  min-height: 46px;
  padding: 0.7rem 1.5rem;
  border: 0;
  border-radius: var(--mg-r-pill);
  font: inherit;
  font-weight: 600;
  font-size: 0.95rem;
  cursor: pointer;
  text-decoration: none;
  transition:
    background var(--mg-t-micro) var(--mg-ease-soft),
    color var(--mg-t-micro) var(--mg-ease-soft),
    transform var(--mg-t-micro) var(--mg-ease-soft),
    box-shadow var(--mg-t-ui) var(--mg-ease);
}

.mg-btn:active {
  transform: scale(0.97);
}

.mg-btn--accent {
  background: var(--mg-orange);
  color: #241505;
  box-shadow: 0 8px 20px -10px rgba(245, 130, 31, 0.9);
}

.mg-btn--accent:hover {
  background: var(--mg-orange-lt);
  color: #241505;
}

.mg-btn--green {
  background: var(--mg-green);
  color: #ffffff;
}

.mg-btn--green:hover {
  background: var(--mg-green-lt);
  color: #ffffff;
}

:root[data-theme="dark"] .mg-btn--green {
  color: #10170d;
}

.mg-btn svg {
  width: 16px;
  height: 16px;
  transition: transform var(--mg-t-ui) var(--mg-ease-spring);
}

.mg-btn:hover svg {
  transform: translateX(4px);
}

/* ==========================================================================
   6. MOTION PRIMITIVES
   ========================================================================== */

/* Scroll reveal. Default state is VISIBLE so content is never hidden from a
   crawler or a browser without IntersectionObserver. */
.mg-reveal {
  opacity: 1;
}

@media (prefers-reduced-motion: no-preference) {
  .mg-js .mg-reveal {
    opacity: 0;
    transform: translateY(20px);
    transition:
      opacity var(--mg-t-reveal) var(--mg-ease),
      transform var(--mg-t-reveal) var(--mg-ease);
    transition-delay: var(--mg-d, 0ms);
  }

  .mg-js .mg-reveal.is-in {
    opacity: 1;
    transform: none;
  }
}

/* Hero entrance.
   The hero IMAGE animates with transform only — never opacity — because an
   element at opacity:0 is not "painted" and would defer Largest Contentful
   Paint by the length of the animation. Copy may fade freely; it is not the
   LCP element. */
@media (prefers-reduced-motion: no-preference) {
  .mg-js .mg-hero__copy > * {
    opacity: 0;
    transform: translateY(18px);
    animation: mg-rise var(--mg-t-hero) var(--mg-ease) forwards;
    animation-delay: var(--mg-d, 0ms);
  }

  .mg-js .mg-hero__media {
    transform: translateX(26px);
    animation: mg-slide-in var(--mg-t-hero) var(--mg-ease) 260ms forwards;
  }
}

@keyframes mg-rise {
  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes mg-slide-in {
  to {
    transform: none;
  }
}

/* ==========================================================================
   7. HERO
   ========================================================================== */

.mg-hero {
  position: relative;
  border-radius: var(--mg-r-lg);
  overflow: hidden;
  background: var(--mg-cream);
  border: 1px solid var(--mg-line);
  box-shadow: var(--mg-shadow-1);
  margin-top: clamp(0.75rem, 2vw, 1.25rem);
}

.mg-hero__track {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}

.mg-hero__track::-webkit-scrollbar {
  display: none;
}

.mg-hero__slide {
  flex: 0 0 100%;
  scroll-snap-align: center;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
  align-items: center;
  gap: clamp(1rem, 3vw, 2rem);
  min-height: clamp(340px, 40vw, 440px);
}

.mg-hero__copy {
  padding: clamp(1.5rem, 4vw, 3.5rem);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.9rem;
}

.mg-hero__eyebrow {
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--mg-text-2);
}

.mg-hero__title {
  font-size: clamp(1.85rem, 4vw, 2.9rem);
  line-height: 1.06;
  letter-spacing: -0.035em;
  margin: 0;
}

.mg-hero__lead {
  color: var(--mg-text-2);
  font-size: clamp(0.95rem, 1.4vw, 1.05rem);
  line-height: 1.6;
  max-width: 34ch;
  margin: 0;
}

.mg-hero__media {
  position: relative;
  align-self: stretch;
  min-height: 240px;
  overflow: hidden;
  display: grid;
  place-items: center;
  padding: clamp(0.75rem, 2vw, 1.5rem);
  background: var(--mg-cream-2);
}

.mg-hero__media img,
.mg-hero__media .mg-ph {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}

/* Signature ambient motion: the "Rivo" nudge. Runs a small, finite number of
   times rather than looping forever — a permanent loop is the thing that
   becomes irritating and it contradicts the "no constant floating objects"
   rule in the brief. */
@media (prefers-reduced-motion: no-preference) {
  .mg-js .mg-hero__drift {
    animation: mg-drift 7s var(--mg-ease-soft) 1.8s 3;
  }
}

@keyframes mg-drift {
  0%,
  100% {
    transform: translateX(0);
  }
  8% {
    transform: translateX(4px);
  }
  16% {
    transform: translateX(0);
  }
}

.mg-hero__dots {
  position: relative;
  display: flex;
  justify-content: center;
  gap: 0.25rem;
  padding: 0.25rem 1rem 0.75rem;
  background: var(--mg-surface-2);
  z-index: 3;
}

.mg-hero__dot {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  min-height: 44px;
  padding: 0;
  border: 0;
  background: transparent;
  border-radius: var(--mg-r-sm);
  box-shadow: none;
  cursor: pointer;
}

.mg-hero__dot::before {
  content: "";
  width: 10px;
  height: 10px;
  border-radius: var(--mg-r-pill);
  background: var(--mg-text-2);
  transition: width var(--mg-t-micro) var(--mg-ease-soft);
}

.mg-hero__dot[aria-current="true"]::before {
  width: 28px;
  background: var(--mg-orange);
  outline: 1px solid var(--mg-accent-ink);
}

.mg-hero__dot:hover,
.mg-hero__dot:focus-visible {
  background: var(--mg-border);
  box-shadow: none;
}

.mg-hero__dot:focus-visible {
  outline: 2px solid var(--mg-head);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .mg-hero__dot::before {
    transition: none;
  }
}

@media (max-width: 820px) {
  .mg-hero__slide {
    grid-template-columns: 1fr;
    min-height: 0;
  }
  .mg-hero__media {
    order: -1;
    min-height: 180px;
    aspect-ratio: 16 / 8.5;
    padding: 0.5rem 1.25rem;
  }
  .mg-hero__copy {
    padding: 1.35rem 1.25rem 2.35rem;
  }
}

/* ==========================================================================
   8. CATEGORY TILES
   ========================================================================== */

.mg-cats {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: clamp(0.6rem, 1.4vw, 1rem);
}

.mg-cat {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  gap: 0.5rem;
  padding: 1.1rem 0.75rem 0.95rem;
  border-radius: var(--mg-r-md);
  background: var(--mg-tint-1);
  text-decoration: none;
  color: var(--mg-text);
  min-height: 150px;
  overflow: hidden;
  transition:
    transform var(--mg-t-ui) var(--mg-ease),
    box-shadow var(--mg-t-ui) var(--mg-ease),
    filter var(--mg-t-ui) var(--mg-ease-soft);
}

.mg-cat:nth-child(6n + 2) { background: var(--mg-tint-2); }
.mg-cat:nth-child(6n + 3) { background: var(--mg-tint-3); }
.mg-cat:nth-child(6n + 4) { background: var(--mg-tint-4); }
.mg-cat:nth-child(6n + 5) { background: var(--mg-tint-5); }
.mg-cat:nth-child(6n + 6) { background: var(--mg-tint-6); }

.mg-cat__art {
  flex: 1;
  display: grid;
  place-items: center;
  width: 100%;
}

.mg-cat__art img,
.mg-cat__art .mg-ph {
  max-height: 76px;
  width: auto;
  transition: transform var(--mg-t-ui) var(--mg-ease-spring);
}

.mg-cat__label {
  font-size: 0.86rem;
  font-weight: 600;
}

.mg-cat:hover,
.mg-cat:focus-visible {
  transform: translateY(-4px);
  box-shadow: var(--mg-shadow-2);
  filter: saturate(1.08);
}

.mg-cat:hover .mg-cat__art img,
.mg-cat:hover .mg-cat__art .mg-ph {
  transform: scale(1.05);
}

.mg-cat__arrow {
  position: absolute;
  right: 0.6rem;
  top: 0.6rem;
  width: 22px;
  height: 22px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--mg-surface);
  color: var(--mg-green);
  opacity: 0;
  transform: translateY(-4px);
  transition:
    opacity var(--mg-t-ui) var(--mg-ease),
    transform var(--mg-t-ui) var(--mg-ease);
}

.mg-cat:hover .mg-cat__arrow,
.mg-cat:focus-visible .mg-cat__arrow {
  opacity: 1;
  transform: none;
}

.mg-cat__arrow svg {
  width: 11px;
  height: 11px;
}

/* Mobile: horizontal rail with the next card peeking, per the brief. */
@media (max-width: 860px) {
  .mg-cats {
    display: flex;
    overflow-x: auto;
    scroll-snap-type: x proximity;
    scrollbar-width: none;
    gap: 0.6rem;
    margin-inline: calc(clamp(1rem, 4vw, 2rem) * -1);
    padding-inline: clamp(1rem, 4vw, 2rem);
  }
  .mg-cats::-webkit-scrollbar {
    display: none;
  }
  .mg-cat {
    flex: 0 0 36%;
    min-width: 122px;
    scroll-snap-align: start;
  }
}

/* ==========================================================================
   9. PRODUCT CARD — variant A (standard)
   ========================================================================== */

.mg-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(0.7rem, 1.6vw, 1.15rem);
}

@media (max-width: 1000px) {
  .mg-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (max-width: 720px) {
  .mg-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.mg-card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--mg-surface);
  border: 1px solid var(--mg-border);
  border-radius: var(--mg-r-md);
  overflow: hidden;
  transition:
    transform var(--mg-t-ui) var(--mg-ease),
    box-shadow var(--mg-t-ui) var(--mg-ease),
    border-color var(--mg-t-ui) var(--mg-ease);
}

.mg-card:hover,
.mg-card:focus-within {
  transform: translateY(-4px);
  box-shadow: var(--mg-shadow-3);
  border-color: transparent;
}

.mg-card__media {
  position: relative;
  aspect-ratio: 1;
  overflow: hidden;
  background: var(--mg-tint-2);
}

.mg-card__media img,
.mg-card__media .mg-ph {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform var(--mg-t-ui) var(--mg-ease);
}

.mg-card:hover .mg-card__media img,
.mg-card:hover .mg-card__media .mg-ph {
  transform: scale(1.04);
}

.mg-card__badge {
  position: absolute;
  top: 0.6rem;
  left: 0.6rem;
  z-index: 2;
  padding: 0.28rem 0.7rem;
  border-radius: var(--mg-r-pill);
  font-size: 0.68rem;
  font-weight: 700;
  background: var(--mg-orange);
  color: #241505;
}

.mg-card__badge--new {
  background: var(--mg-green);
  color: #ffffff;
}

:root[data-theme="dark"] .mg-card__badge--new {
  color: #10170d;
}

.mg-card__fav {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  z-index: 3;
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 50%;
  background: var(--mg-surface);
  color: var(--mg-text-2);
  cursor: pointer;
  box-shadow: var(--mg-shadow-1);
  transition:
    color var(--mg-t-micro) var(--mg-ease-soft),
    transform var(--mg-t-micro) var(--mg-ease-spring);
}

.mg-card__fav:hover {
  color: var(--mg-orange);
}

.mg-card__fav[aria-pressed="true"] {
  color: var(--mg-orange);
}

.mg-card__fav[aria-pressed="true"] svg {
  fill: currentColor;
}

.mg-card__fav:active {
  transform: scale(0.88);
}

.mg-card__fav svg {
  width: 17px;
  height: 17px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
}

.mg-card__body {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  padding: 0.85rem 0.9rem 1rem;
  flex: 1;
}

.mg-card__title {
  font-size: 0.92rem;
  font-weight: 600;
  line-height: 1.3;
  margin: 0;
  color: var(--mg-text);
}

.mg-card__title a {
  color: inherit;
  text-decoration: none;
}

/* The whole card is the tap target — essential on touch, where the hover
   quick-action never appears. */
.mg-card__title a::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
}

.mg-card__price {
  font-size: 1rem;
  font-weight: 700;
  color: var(--mg-head);
  margin-top: auto;
  padding-top: 0.4rem;
}

.mg-card__price del {
  font-size: 0.82em;
  font-weight: 400;
  color: var(--mg-text-2);
  margin-left: 0.35rem;
}

.mg-card__rating {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.76rem;
  color: var(--mg-text-2);
}

.mg-stars {
  display: inline-flex;
  gap: 1px;
  color: var(--mg-orange);
}

.mg-stars svg {
  width: 13px;
  height: 13px;
  fill: currentColor;
}

.mg-stars .off {
  fill: var(--mg-border);
}

/* Quick action, pointer devices only.
 *
 * This used to sit at the card's bottom edge, which put it directly on top of
 * the price -- the one number a buyer needs at the moment they reach for the
 * button. It now covers the image square instead: .mg-card__media is
 * aspect-ratio 1 and spans the full card width, so an overlay pinned to the
 * top at the same ratio matches the image exactly, and align-items:flex-end
 * drops the button onto the bottom of the photo. Title and price stay visible.
 *
 * It deliberately stays a sibling of .mg-card__media rather than a child: the
 * media carries the view-transition-name, and a child would be captured in the
 * morph snapshot on navigation. */
.mg-card__quick {
  position: absolute;
  inset: 0 0 auto 0;
  aspect-ratio: 1;
  display: flex;
  align-items: flex-end;
  padding: 0.6rem;
  z-index: 2;
  opacity: 0;
  /* An opacity-0 overlay still receives clicks. Without this the invisible
     layer would swallow taps meant for the card's stretched title link. */
  pointer-events: none;
  transform: translateY(8px);
  transition:
    opacity var(--mg-t-ui) var(--mg-ease),
    transform var(--mg-t-ui) var(--mg-ease);
}

.mg-card__quick .mg-btn {
  width: 100%;
  min-height: 40px;
  font-size: 0.85rem;
}

@media (hover: hover) and (pointer: fine) {
  .mg-card:hover .mg-card__quick,
  .mg-card:focus-within .mg-card__quick {
    opacity: 1;
    transform: none;
    pointer-events: auto;
  }
}

/* On touch the quick action can never be revealed, so it is shown inline
   instead of hidden behind a hover that does not exist. */
@media (hover: none), (pointer: coarse) {
  .mg-card__quick {
    position: static;
    aspect-ratio: auto;
    display: block;
    opacity: 1;
    pointer-events: auto;
    transform: none;
    padding: 0 0.9rem 0.9rem;
  }
}

/* ==========================================================================
   10. PRODUCT CARD — variant C (compact horizontal)
   ========================================================================== */

.mg-card--compact {
  flex-direction: row;
  align-items: stretch;
}

.mg-card--compact .mg-card__media {
  flex: 0 0 104px;
  aspect-ratio: 1;
}

.mg-card--compact .mg-card__body {
  justify-content: center;
  padding: 0.7rem 0.9rem;
}

.mg-card--compact .mg-card__quick {
  display: none;
}

/* ==========================================================================
   11. PROMO PANELS
   ========================================================================== */

.mg-promos {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(0.7rem, 1.6vw, 1.15rem);
}

@media (max-width: 860px) {
  .mg-promos {
    grid-template-columns: 1fr;
  }
}

.mg-promo {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  align-items: center;
  gap: 1rem;
  border-radius: var(--mg-r-lg);
  overflow: hidden;
  min-height: 250px;
  background: var(--mg-cream-2);
  text-decoration: none;
}

.mg-promo--green {
  background: #d9ecd6;
}

:root[data-theme="dark"] .mg-promo--green {
  background: var(--mg-tint-6);
}

.mg-promo__copy {
  padding: clamp(1.1rem, 2.6vw, 2rem);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.6rem;
}

.mg-promo__eyebrow {
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--mg-text-2);
}

.mg-promo__title {
  font-size: clamp(1.2rem, 2.2vw, 1.65rem);
  margin: 0;
}

.mg-promo__lead {
  font-size: 0.88rem;
  color: var(--mg-text-2);
  line-height: 1.55;
  margin: 0;
  max-width: 30ch;
}

.mg-promo__media {
  align-self: stretch;
  overflow: hidden;
}

.mg-promo__media img,
.mg-promo__media .mg-ph {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* A hover zoom, not a reveal. It borrowed the reveal token, so slowing
     reveals to 780ms would have dragged this to 780ms with them. */
  transition: transform var(--mg-t-breathe) var(--mg-ease);
}

.mg-promo:hover .mg-promo__media img,
.mg-promo:hover .mg-promo__media .mg-ph {
  transform: scale(1.03);
}

/* ==========================================================================
   12. TRUST BAR
   ========================================================================== */

.mg-trust {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1rem;
  padding: clamp(1.1rem, 2.4vw, 1.6rem);
  background: var(--mg-surface-2);
  border-radius: var(--mg-r-md);
}

@media (max-width: 780px) {
  .mg-trust {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1.2rem;
  }
}

.mg-trust__item {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 0.3rem;
  padding-inline: 0.5rem;
  border-right: 1px solid var(--mg-border);
}

.mg-trust__item:last-child {
  border-right: 0;
}

@media (max-width: 780px) {
  .mg-trust__item {
    border-right: 0;
  }
}

.mg-trust__item svg {
  width: 26px;
  height: 26px;
  fill: none;
  stroke: var(--mg-green);
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  margin-bottom: 0.2rem;
}

/* Icons draw themselves in when the row enters the viewport. */
@media (prefers-reduced-motion: no-preference) {
  .mg-js .mg-trust__item svg path,
  .mg-js .mg-trust__item svg circle,
  .mg-js .mg-trust__item svg rect {
    stroke-dasharray: var(--len, 120);
    stroke-dashoffset: var(--len, 120);
  }
  .mg-js .mg-trust.is-in .mg-trust__item svg path,
  .mg-js .mg-trust.is-in .mg-trust__item svg circle,
  .mg-js .mg-trust.is-in .mg-trust__item svg rect {
    animation: mg-draw 700ms var(--mg-ease) forwards;
    animation-delay: var(--mg-d, 0ms);
  }
}

@keyframes mg-draw {
  to {
    stroke-dashoffset: 0;
  }
}

.mg-trust__t {
  font-weight: 600;
  font-size: 0.86rem;
  color: var(--mg-text);
}

.mg-trust__s {
  font-size: 0.75rem;
  color: var(--mg-text-2);
}

/* ==========================================================================
   13. NEWSLETTER
   ========================================================================== */

.mg-news {
  position: relative;
  overflow: hidden;
  border-radius: var(--mg-r-lg);
  background: var(--mg-cream-2);
  padding: clamp(1.4rem, 3vw, 2.2rem);
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  align-items: center;
  gap: 1.2rem;
}

@media (max-width: 780px) {
  .mg-news {
    grid-template-columns: 1fr;
  }
}

.mg-news__t {
  font-size: clamp(1.1rem, 2vw, 1.4rem);
  margin: 0 0 0.3rem;
}

.mg-news__s {
  font-size: 0.85rem;
  color: var(--mg-text-2);
  margin: 0;
  max-width: 34ch;
}

.mg-news__form {
  display: flex;
  gap: 0.5rem;
  position: relative;
  z-index: 2;
}

.mg-news__form input {
  flex: 1;
  min-width: 0;
  min-height: 46px;
  padding: 0.6rem 1rem;
  border: 1px solid var(--mg-border);
  border-radius: var(--mg-r-pill);
  background: var(--mg-surface);
  color: var(--mg-text);
  font: inherit;
  font-size: 0.9rem;
  transition:
    border-color var(--mg-t-ui) var(--mg-ease-soft),
    box-shadow var(--mg-t-ui) var(--mg-ease-soft);
}

.mg-news__form input:focus {
  outline: none;
  border-color: var(--mg-orange);
  box-shadow: 0 0 0 4px rgba(245, 130, 31, 0.16);
}

.mg-news__blob {
  position: absolute;
  border-radius: 50%;
  pointer-events: none;
  opacity: 0.6;
}

.mg-news__blob--a {
  width: 150px;
  height: 150px;
  left: -50px;
  top: -40px;
  background: var(--mg-orange);
}

.mg-news__blob--b {
  width: 130px;
  height: 130px;
  right: -40px;
  bottom: -50px;
  background: #7fc08f;
}

/* ==========================================================================
   14. MOBILE BOTTOM NAVIGATION
   ========================================================================== */

.mg-bottomnav {
  display: none;
}

@media (max-width: 860px) {
  .mg-bottomnav {
    position: fixed;
    inset-inline: 0;
    bottom: 0;
    z-index: 500;
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    background: var(--mg-surface);
    border-top: 1px solid var(--mg-border);
    padding-bottom: env(safe-area-inset-bottom, 0);
    box-shadow: 0 -4px 20px -12px rgba(31, 42, 36, 0.4);
    transform: translateY(0);
    transition: transform var(--mg-t-ui) var(--mg-ease);
  }

  /* Hides on scroll down, returns on scroll up — per the brief. */
  .mg-bottomnav.is-hidden {
    transform: translateY(110%);
  }

  .mg-bottomnav a {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.15rem;
    min-height: 58px;
    color: var(--mg-text-2);
    text-decoration: none;
    font-size: 0.66rem;
    font-weight: 600;
    transition: color var(--mg-t-micro) var(--mg-ease-soft);
  }

  .mg-bottomnav a[aria-current="page"] {
    color: var(--mg-accent-ink);
  }

  .mg-bottomnav a[aria-current="page"]::before {
    content: "";
    position: absolute;
    top: 0;
    width: 26px;
    height: 3px;
    border-radius: 0 0 3px 3px;
    background: var(--mg-orange);
  }

  .mg-bottomnav svg {
    width: 20px;
    height: 20px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.7;
    stroke-linecap: round;
    stroke-linejoin: round;
  }

  .mg-bottomnav__count {
    position: absolute;
    top: 8px;
    right: calc(50% - 18px);
    min-width: 16px;
    height: 16px;
    padding-inline: 4px;
    border-radius: 9px;
    background: var(--mg-orange);
    color: #241505;
    font-size: 0.6rem;
    font-weight: 700;
    display: grid;
    place-items: center;
  }

  body.mg {
    padding-bottom: calc(58px + env(safe-area-inset-bottom, 0));
  }
}

/* ==========================================================================
   15. ADD-TO-CART FEEDBACK
   ========================================================================== */

.mg-fly {
  position: fixed;
  z-index: 900;
  width: 46px;
  height: 46px;
  border-radius: 50%;
  object-fit: cover;
  pointer-events: none;
  box-shadow: var(--mg-shadow-2);
}

@keyframes mg-count-pop {
  0% { transform: scale(1); }
  45% { transform: scale(1.18); }
  100% { transform: scale(1); }
}

.mg-count-pop {
  animation: mg-count-pop 340ms var(--mg-ease-spring);
}

/* Mobile confirmation sheet */
.mg-sheet {
  position: fixed;
  inset-inline: 0;
  bottom: 0;
  z-index: 600;
  transform: translateY(110%);
  transition: transform var(--mg-t-ui) var(--mg-ease);
  background: var(--mg-surface);
  border-radius: var(--mg-r-lg) var(--mg-r-lg) 0 0;
  box-shadow: 0 -10px 40px -16px rgba(31, 42, 36, 0.5);
  padding: 1rem 1.1rem calc(1rem + env(safe-area-inset-bottom, 0));
  display: flex;
  align-items: center;
  gap: 0.85rem;
}

.mg-sheet.is-open {
  transform: translateY(0);
}

@media (max-width: 860px) {
  .mg-sheet.is-open {
    transform: translateY(calc(-58px - env(safe-area-inset-bottom, 0)));
  }
}

.mg-sheet__img {
  width: 46px;
  height: 46px;
  border-radius: var(--mg-r-sm);
  object-fit: cover;
  flex: none;
  background: var(--mg-tint-2);
}

.mg-sheet__t {
  font-weight: 600;
  font-size: 0.88rem;
}

.mg-sheet__s {
  font-size: 0.78rem;
  color: var(--mg-text-2);
}

/* ==========================================================================
   16. SHARED-ELEMENT PAGE TRANSITION
   Cross-document View Transitions: the card image genuinely expands into the
   product-detail hero across a real page load. Browsers without support just
   navigate normally.
   ========================================================================== */

@media (prefers-reduced-motion: no-preference) {
  @view-transition {
    navigation: auto;
  }
}

::view-transition-group(*) {
  animation-duration: var(--mg-t-page);
  animation-timing-function: var(--mg-ease);
}

/* ==========================================================================
   17. PLACEHOLDER ART
   Stand-in for photography. Deliberately neutral so it does not compete with
   layout review — see the note in functions.php.
   ========================================================================== */

.mg-ph {
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  background:
    radial-gradient(120% 100% at 30% 15%, var(--mg-ph-hi), transparent 60%),
    var(--ph, var(--mg-tint-2));
}

.mg-ph span {
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(31, 42, 36, 0.35);
}

:root[data-theme="dark"] .mg-ph span {
  color: rgba(233, 239, 226, 0.35);
}

/* ==========================================================================
   18. UTILITIES
   ========================================================================== */

.mg-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.mg :focus-visible {
  outline: 3px solid var(--mg-orange);
  outline-offset: 3px;
  border-radius: 6px;
}

/* ==========================================================================
   19. THEME TOGGLE
   ========================================================================== */

.mg-themetoggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--mg-text-2);
  cursor: pointer;
  transition:
    color var(--mg-t-micro) var(--mg-ease-soft),
    background var(--mg-t-micro) var(--mg-ease-soft);
}

.mg-themetoggle:hover {
  color: var(--mg-orange);
  background: var(--mg-surface-2);
}

.mg-themetoggle svg {
  width: 19px;
  height: 19px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
}

/* Only one icon at a time, across all three theme states. */
.mg-i-moon {
  display: none;
}

:root[data-theme="dark"] .mg-i-sun {
  display: none;
}

:root[data-theme="dark"] .mg-i-moon {
  display: block;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .mg-i-sun {
    display: none;
  }
  :root:not([data-theme="light"]) .mg-i-moon {
    display: block;
  }
}

/* Sticky header condense, driven by motion.js */
.mg-condensed {
  box-shadow: var(--mg-shadow-2);
  backdrop-filter: blur(10px);
}

/* Affiliate disclosure on the product page */
.mg-disclosure {
  font-size: 0.82rem;
  line-height: 1.55;
  color: var(--mg-text-2);
  background: var(--mg-surface-2);
  border: 1px solid var(--mg-border);
  border-radius: var(--mg-r-sm);
  padding: 0.7rem 0.9rem;
  max-width: 56ch;
  margin: 1rem 0;
}

.mg-disclosure strong {
  color: var(--mg-orange-dk);
}

/* ==========================================================================
   20. PARENT-THEME BRIDGE
   Kadence renders the header and footer and styles them with its own
   variables, so they do not follow the tokens above. These rules hand the
   parent theme's chrome over to the Mangorivo palette — most importantly in
   dark mode, where an unstyled header stays white.
   ========================================================================== */

.mg #masthead,
.mg .site-header-wrap,
.mg .site-header-row,
.mg .site-main-header-wrap,
.mg .site-top-header-wrap,
.mg .site-bottom-header-wrap {
  background: var(--mg-surface) !important;
  border-color: var(--mg-border) !important;
}

.mg #colophon,
.mg .site-footer,
.mg .site-footer-wrap,
.mg .site-middle-footer-wrap,
.mg .site-top-footer-wrap,
.mg .site-bottom-footer-wrap {
  background: var(--mg-surface-2) !important;
  border-color: var(--mg-border) !important;
  color: var(--mg-text-2);
}

.mg #masthead a,
.mg .site-header-item a,
.mg .header-navigation a,
.mg #colophon a,
.mg .site-footer a {
  color: var(--mg-text);
}

.mg .header-navigation a:hover,
.mg .site-footer a:hover {
  color: var(--mg-orange);
}

.mg .site-title,
.mg .site-branding a {
  color: var(--mg-head) !important;
}

/* Kadence sets a page-background variable of its own. */
.mg,
.mg .content-bg,
.mg .site,
.mg #wrapper,
.mg .content-area,
.mg #primary {
  background: var(--mg-page) !important;
}

/* The toggle sits inside the nav list; the parent's link styles do not apply
   to a <button>, so it needs its own alignment. */
.mg .mg-theme-item {
  display: flex;
  align-items: center;
}

.mg .mg-theme-item::before,
.mg .mg-theme-item::after {
  content: none !important;
}

/* Menu links: replace the parent's underline with the growing orange rule
   from the motion brief. */
.mg .header-navigation .menu-item > a {
  position: relative;
}

.mg .header-navigation .menu-item > a::after {
  content: "";
  position: absolute;
  /* Kadence's nav links butt up against each other -- each carries 10.2px of
     inline padding and zero margin, so "Start" ends on the exact pixel "Shop"
     begins. A rule drawn edge to edge therefore touches its neighbour's and
     the two read as one continuous line. Insetting by the padding keeps each
     underline under its own label, with a clear gap between them. */
  left: 0.65rem;
  right: 0.65rem;
  bottom: 0.2rem;
  height: 2px;
  border-radius: 2px;
  background: var(--mg-orange);
  opacity: 0;
  transform: scaleX(0);
  transform-origin: left center;
  transition:
    transform var(--mg-t-ui) var(--mg-ease),
    opacity var(--mg-t-ui) var(--mg-ease);
}

/* Hover is a hint, not a claim. Drawing it at 40% means it can never be
   mistaken for the current page, which stays solid. */
.mg .header-navigation .menu-item > a:hover::after,
.mg .header-navigation .menu-item > a:focus-visible::after {
  opacity: 0.4;
  transform: scaleX(1);
}

/* The current page always wins, including while it is hovered. The :hover
   selectors above score (0,4,1), so the plain current rules would lose to them
   without these explicit hovered variants. */
.mg .header-navigation .current-menu-item > a::after,
.mg .header-navigation .current_page_item > a::after,
.mg .header-navigation .current-menu-ancestor > a::after,
.mg .header-navigation .current-menu-item > a:hover::after,
.mg .header-navigation .current_page_item > a:hover::after,
.mg .header-navigation .current-menu-ancestor > a:hover::after {
  opacity: 1;
  transform: scaleX(1);
}

/* A second, non-colour cue for the current page, so the distinction does not
   rest on the orange alone. */
.mg .header-navigation .current-menu-item > a,
.mg .header-navigation .current_page_item > a,
.mg .header-navigation .current-menu-ancestor > a {
  color: var(--mg-text);
  font-weight: 600;
}

@media (prefers-reduced-motion: reduce) {
  .mg .header-navigation .menu-item > a::after {
    transition: none;
  }
}

/* Kadence's navigation squashes inline SVGs to 4px; the icon needs its own
   explicit box inside the flex row. */
.mg .mg-themetoggle svg {
  width: 19px !important;
  height: 19px !important;
  flex: 0 0 19px;
}

/* ==========================================================================
   21. BRAND LOCKUP
   ========================================================================== */

.mg .mg-brand {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  text-decoration: none;
}

.mg .mg-brand svg {
  flex: 0 0 auto;
  transition: transform var(--mg-t-ui) var(--mg-ease-spring);
}

.mg .mg-brand:hover svg {
  transform: translateY(-2px) rotate(-3deg);
}

.mg .mg-brand__word {
  font-family: "Poppins", system-ui, sans-serif;
  font-weight: 700;
  font-size: 1.5rem;
  letter-spacing: -0.03em;
  color: var(--mg-head);
}

@media (max-width: 600px) {
  .mg .mg-brand__word {
    font-size: 1.2rem;
  }
}

/* The mark also stands in for the mascot in the newsletter band. */
.mg-news__mark {
  position: relative;
  z-index: 2;
  display: none;
}

@media (min-width: 781px) {
  .mg-news__mark {
    display: block;
  }
}

/* ==========================================================================
   22. LANGUAGE SWITCHER
   ========================================================================== */

.mg .mg-lang-item {
  display: flex;
  align-items: center;
}

.mg .mg-lang-item::before,
.mg .mg-lang-item::after {
  content: none !important;
}

.mg .mg-lang-item .trp-language-switcher {
  margin: 0;
  min-width: 0;
}

.mg .mg-lang-item .trp-language-switcher > div {
  background: transparent !important;
  border: 1px solid var(--mg-border) !important;
  border-radius: var(--mg-r-pill) !important;
  padding: 0.25rem 0.65rem !important;
  font-size: 0.8rem;
  color: var(--mg-text-2) !important;
}

.mg .mg-lang-item a,
.mg .mg-lang-item .trp-ls-shortcode-current-language a {
  color: var(--mg-text) !important;
  text-decoration: none;
}

.mg .mg-lang-item .trp-ls-shortcode-language {
  background: var(--mg-surface) !important;
  border-color: var(--mg-border) !important;
}

/* TranslatePress injects a floating switcher by default; the menu one is
   enough and the floater overlaps the mobile bottom navigation. */
#trp-floater-ls {
  display: none !important;
}

/* TranslatePress also injects a fixed floating switcher; the one in the menu
   is enough, and the floater sits over the mobile bottom navigation. */
.trp-language-switcher.trp-floating,
#trp-floater-ls {
  display: none !important;
}

/* Kadence prints the site title next to the custom logo; the lockup already
   contains the wordmark, so the plain title would read "Mangorivo" twice. */
.mg .site-title,
.mg .site-branding .site-title {
  display: none !important;
}

/* Keep the TranslatePress dropdown list anchored to its trigger. Without a
   positioned ancestor it escapes and lands over the page content. */
.mg .mg-lang-item,
.mg .mg-lang-item .trp-language-switcher {
  position: relative !important;
}

.mg .mg-lang-item .trp-ls-shortcode-language {
  position: absolute !important;
  top: 100% !important;
  right: 0 !important;
  left: auto !important;
  z-index: 400;
  min-width: 9rem;
  border-radius: var(--mg-r-sm) !important;
  box-shadow: var(--mg-shadow-2);
}

/* The floating switcher's actual class is trp-floating-switcher (not
   trp-floating). It sits fixed at the bottom-right, over the mobile bottom
   navigation, and duplicates the one already in the menu. */
.trp-floating-switcher,
.trp-language-switcher.trp-floating-switcher,
#trp-floater-ls {
  display: none !important;
}

/* Collapse the dropdown list until it is actually opened. */
.mg .mg-lang-item .trp-ls-shortcode-language {
  max-height: 0;
  overflow: hidden;
  opacity: 0;
  pointer-events: none;
  transition:
    opacity var(--mg-t-ui) var(--mg-ease),
    max-height var(--mg-t-ui) var(--mg-ease);
}

.mg .mg-lang-item:hover .trp-ls-shortcode-language,
.mg .mg-lang-item:focus-within .trp-ls-shortcode-language {
  max-height: 12rem;
  opacity: 1;
  pointer-events: auto;
}

/* ==========================================================================
   23. HEADER ACTIONS
   Search, account, cart, theme and language — the cluster the concept has on
   the right of the header.
   ========================================================================== */

.mg .mg-actions {
  display: flex !important;
  align-items: center;
  gap: 0.15rem;
  margin-left: 0.5rem;
  padding-left: 0.6rem;
  border-left: 1px solid var(--mg-border);
}

.mg .mg-actions::before,
.mg .mg-actions::after {
  content: none !important;
}

.mg .mg-iconbtn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--mg-text-2);
  cursor: pointer;
  transition:
    color var(--mg-t-micro) var(--mg-ease-soft),
    background var(--mg-t-micro) var(--mg-ease-soft);
}

.mg .mg-iconbtn:hover {
  color: var(--mg-orange);
  background: var(--mg-surface-2);
}

.mg .mg-iconbtn svg {
  width: 20px !important;
  height: 20px !important;
  flex: 0 0 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Cart badge */
.mg .mg-cart-count {
  position: absolute;
  top: 3px;
  right: 2px;
  min-width: 17px;
  height: 17px;
  padding-inline: 4px;
  border-radius: 9px;
  background: var(--mg-orange);
  color: #241505;
  font-size: 0.62rem;
  font-weight: 700;
  line-height: 17px;
  text-align: center;
}

.mg .mg-cart-count.is-zero {
  display: none;
}

/* Only one theme icon shows at a time, across all three theme states. */
.mg .mg-i-moon {
  display: none;
}

:root[data-theme="dark"] .mg .mg-i-sun,
:root[data-theme="dark"] .mg-i-sun {
  display: none;
}

:root[data-theme="dark"] .mg .mg-i-moon,
:root[data-theme="dark"] .mg-i-moon {
  display: block;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .mg-i-sun {
    display: none;
  }
  :root:not([data-theme="light"]) .mg-i-moon {
    display: block;
  }
}

/* ==========================================================================
   24. LANGUAGE SWITCHER (own markup)
   One button, one absolutely-positioned list. Opening it overlays the page
   instead of pushing it, and the button has a fixed width so switching
   DE <-> EN cannot reflow the header.
   ========================================================================== */

.mg .mg-lang {
  position: relative;
  margin-left: 0.15rem;
}

.mg .mg-lang__btn {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  /* Fixed width: "Deutsch" and "English" are different lengths, and letting
     the button resize shifted the whole nav on every language change. */
  width: 74px;
  height: 38px;
  padding: 0 0.5rem;
  border: 1px solid var(--mg-border);
  border-radius: var(--mg-r-pill);
  background: var(--mg-surface);
  color: var(--mg-text);
  font: inherit;
  font-size: 0.78rem;
  font-weight: 600;
  cursor: pointer;
  transition:
    border-color var(--mg-t-micro) var(--mg-ease-soft),
    background var(--mg-t-micro) var(--mg-ease-soft);
}

.mg .mg-lang__btn:hover {
  border-color: var(--mg-orange);
}

.mg .mg-flag {
  width: 18px;
  height: 13px;
  flex: 0 0 18px;
  border-radius: 2px;
}

.mg .mg-lang__cv {
  width: 10px;
  height: 7px;
  flex: 0 0 10px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform var(--mg-t-micro) var(--mg-ease);
}

.mg .mg-lang__btn[aria-expanded="true"] .mg-lang__cv {
  transform: rotate(180deg);
}

/* Absolutely positioned, so opening overlays rather than pushing content. */
.mg .mg-lang__list {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 600;
  min-width: 150px;
  margin: 0;
  padding: 0.25rem;
  list-style: none;
  background: var(--mg-surface);
  border: 1px solid var(--mg-border);
  border-radius: var(--mg-r-sm);
  box-shadow: var(--mg-shadow-3);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px);
  transition:
    opacity var(--mg-t-micro) var(--mg-ease),
    transform var(--mg-t-micro) var(--mg-ease),
    visibility var(--mg-t-micro);
}

.mg .mg-lang.is-open .mg-lang__list {
  opacity: 1;
  visibility: visible;
  transform: none;
}

.mg .mg-lang__list a {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.6rem;
  border-radius: 6px;
  font-size: 0.85rem;
  color: var(--mg-text) !important;
  text-decoration: none;
  white-space: nowrap;
}

.mg .mg-lang__list a:hover {
  background: var(--mg-surface-2);
}

.mg .mg-lang__list a[aria-current="true"] {
  color: var(--mg-orange) !important;
  font-weight: 600;
}

/* ==========================================================================
   25. EXPANDING SEARCH
   ========================================================================== */

.mg-search {
  position: fixed;
  inset-inline: 0;
  top: 0;
  z-index: 700;
  padding: clamp(0.75rem, 2vw, 1.1rem) clamp(1rem, 4vw, 2rem);
  background: var(--mg-surface);
  border-bottom: 1px solid var(--mg-border);
  box-shadow: var(--mg-shadow-2);
  transform: translateY(-110%);
  transition: transform var(--mg-t-ui) var(--mg-ease);
}

.mg-search.is-open {
  transform: none;
}

.mg-search__form {
  display: flex;
  gap: 0.5rem;
  max-width: 780px;
  margin-inline: auto;
}

.mg-search__form input {
  flex: 1;
  min-width: 0;
  min-height: 46px;
  padding: 0.6rem 1rem;
  border: 1px solid var(--mg-border);
  border-radius: var(--mg-r-pill);
  background: var(--mg-page);
  color: var(--mg-text);
  font: inherit;
  font-size: 0.95rem;
}

.mg-search__form input:focus {
  outline: none;
  border-color: var(--mg-orange);
}

@media (max-width: 860px) {
  .mg .mg-actions {
    margin-left: auto;
    border-left: 0;
    padding-left: 0;
  }
  .mg .mg-lang__btn {
    width: 62px;
  }
}

/* ==========================================================================
   26. SECTION RHYTHM
   The page uses space and section heads to create hierarchy. Repeated border
   boxes made every part of the homepage compete with the product cards.
   ========================================================================== */

.mg-panel {
  background: transparent;
  border: 0;
  border-radius: 0;
  padding: 0;
  box-shadow: none;
}

.mg-panel + .mg-panel {
  margin-top: 0;
}

/* Sections own the rhythm now that their contents are not boxed. */
.mg-main > .mg-section {
  padding-block: clamp(2rem, 5vw, 3.5rem);
}

.mg-main > section:first-of-type {
  padding-top: clamp(0.9rem, 2vw, 1.25rem);
}

.mg-main > section:last-of-type {
  padding-bottom: clamp(2rem, 4vw, 3rem);
}

/* Panels that carry their own colour do not need the surface treatment. */
.mg-panel--deals {
  background: var(--mg-cream-2);
  border-radius: var(--mg-r-lg);
  padding: clamp(1.1rem, 2.6vw, 1.9rem);
}

.mg-promos,
.mg-news {
  box-shadow: var(--mg-shadow-1);
}

.mg-trust {
  border: 1px solid var(--mg-border);
}

/* The hero keeps a matching edge so it belongs to the same family. */
.mg-hero {
  border: 1px solid var(--mg-border);
  box-shadow: var(--mg-shadow-1);
}

/* Category tiles get real images now; keep them contained. */
.mg-cat__art img {
  max-height: 76px;
  width: auto;
  object-fit: contain;
  mix-blend-mode: multiply;
}

:root[data-theme="dark"] .mg-cat__art img {
  mix-blend-mode: normal;
}

/* ==========================================================================
   27. MOBILE ACTION BAR
   The menu-based actions cluster lives inside Kadence's desktop navigation,
   which is hidden below 860px. This bar carries the same controls where they
   are actually reachable, without hiding them behind the hamburger.
   ========================================================================== */

.mg-mobilebar {
  display: none;
}

@media (max-width: 860px) {
  .mg .mg-actions {
    display: none !important;
  }

  .mg-mobilebar {
    display: flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.45rem clamp(1rem, 4vw, 2rem);
    background: var(--mg-surface);
    border-bottom: 1px solid var(--mg-border);
  }

  .mg-mobilebar__spacer {
    flex: 1;
  }

  .mg-mobilebar .mg-iconbtn {
    width: auto;
    min-width: 44px;
    height: 44px;
    gap: 0.4rem;
    padding-inline: 0.5rem;
    border-radius: var(--mg-r-pill);
  }

  .mg-mobilebar__label {
    font-size: 0.82rem;
    font-weight: 600;
  }

  .mg-mobilebar .mg-lang__btn {
    height: 44px;
  }

  /* Anchor the dropdown to this bar, not the page. */
  .mg-mobilebar .mg-lang__list {
    right: 0;
  }
}

/* The bottom navigation is rendered site-wide now; only reserve space for it
   where it is actually shown. */
@media (min-width: 861px) {
  body.mg {
    padding-bottom: 0;
  }
  .mg-bottomnav {
    display: none !important;
  }
}

/* ==========================================================================
   28. MOBILE DRAWER
   Kadence paints its off-canvas popup a hardcoded near-black (#090c10) in
   every theme. The bridge above recoloured the *links* from our tokens but
   never claimed the surface, so in light mode dark ink (#1f2a24) sat on a
   near-black ground — about 1.2:1, effectively unreadable.
   Own the surface and the text together, in both themes.
   ========================================================================== */

#mobile-drawer .drawer-inner,
.popup-drawer .drawer-inner,
#mobile-drawer .drawer-content,
.popup-drawer .drawer-content {
  background: var(--mg-surface) !important;
  color: var(--mg-text) !important;
}

/* The scrim behind the panel. */
#mobile-drawer .drawer-overlay,
.popup-drawer .drawer-overlay {
  background: rgba(31, 42, 36, 0.55) !important;
}

:root[data-theme="dark"] #mobile-drawer .drawer-overlay,
:root[data-theme="dark"] .popup-drawer .drawer-overlay {
  background: rgba(0, 0, 0, 0.65) !important;
}

/* Navigation links */
#mobile-drawer .mobile-navigation a,
.popup-drawer .mobile-navigation a,
#mobile-drawer .drawer-navigation a {
  color: var(--mg-text) !important;
  font-weight: 500;
  padding-block: 0.9rem;
  /* 44px minimum touch target, per the UX guidance. */
  min-height: 48px;
  display: flex;
  align-items: center;
}

#mobile-drawer .mobile-navigation a:hover,
.popup-drawer .mobile-navigation a:hover {
  color: var(--mg-orange) !important;
}

/* Kadence marks the current item with its own blue; use the brand accent. */
#mobile-drawer .mobile-navigation .current-menu-item > a,
#mobile-drawer .mobile-navigation .current_page_item > a,
.popup-drawer .mobile-navigation .current-menu-item > a {
  color: var(--mg-orange) !important;
  font-weight: 700;
}

/* Dividers between items */
#mobile-drawer .mobile-navigation li,
.popup-drawer .mobile-navigation li {
  border-bottom: 1px solid var(--mg-border) !important;
}

#mobile-drawer .mobile-navigation li:last-child,
.popup-drawer .mobile-navigation li:last-child {
  border-bottom: 0 !important;
}

/* Close button */
#mobile-drawer .drawer-toggle,
.popup-drawer .drawer-toggle,
#mobile-drawer .pop-close {
  color: var(--mg-text) !important;
}

#mobile-drawer .drawer-toggle .toggle-bar,
.popup-drawer .drawer-toggle .toggle-bar {
  background: var(--mg-text) !important;
}

#mobile-drawer .drawer-toggle:hover,
.popup-drawer .drawer-toggle:hover {
  color: var(--mg-orange) !important;
}

/* The header hamburger itself follows the palette too. */
.mg .menu-toggle-open .toggle-bar,
.mg .drawer-toggle .toggle-bar {
  background: var(--mg-text);
}

.mg .menu-toggle-open,
.mg .mobile-toggle-open-container .menu-toggle-open {
  color: var(--mg-text) !important;
}

/* The current item was orange-on-white at 2.59:1 — orange is a fine accent but
   cannot carry text on a light ground. Deep green for the label (about 10:1),
   with an orange bar as the marker, keeps the brand cue and stays legible. */
#mobile-drawer .mobile-navigation .current-menu-item > a,
#mobile-drawer .mobile-navigation .current_page_item > a,
#mobile-drawer .mobile-navigation .current-menu-ancestor > a,
.popup-drawer .mobile-navigation .current-menu-item > a {
  color: var(--mg-head) !important;
  font-weight: 700;
  position: relative;
  padding-left: 0.9rem !important;
}

#mobile-drawer .mobile-navigation .current-menu-item > a::before,
#mobile-drawer .mobile-navigation .current_page_item > a::before,
.popup-drawer .mobile-navigation .current-menu-item > a::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 4px;
  height: 1.15em;
  border-radius: 3px;
  background: var(--mg-orange);
}

/* Hover stays orange only where it is a transient state on a large target. */
#mobile-drawer .mobile-navigation a:hover,
.popup-drawer .mobile-navigation a:hover {
  color: var(--mg-head) !important;
  background: var(--mg-surface-2);
}

/* ==========================================================================
   29. COMPACT MOBILE HEADER
   Two stacked bars (80px header + 59px action bar = 139px) ate roughly a
   sixth of the viewport before any content. The actions are moved by JS into
   Kadence's mobile header row; these rules strip the bar's own chrome so it
   reads as part of that row rather than a second one.
   ========================================================================== */

@media (max-width: 860px) {
  /* Until the script has moved the bar into the header row it sits in the page
     flow, 49px tall, and moving it pulls the whole page up (layout shift 0.09).
     With JavaScript available it takes no space before it is placed; without
     JavaScript it stays a normal bar below the header. */
  html:not(.no-js) .mg-mobilebar:not(.is-inline) {
    position: absolute;
    block-size: 0;
    overflow: hidden;
    visibility: hidden;
    pointer-events: none;
  }

  .mg-mobilebar.is-inline {
    display: inline-flex;
    padding: 0;
    gap: 0.1rem;
    background: transparent;
    border-bottom: 0;
    margin-right: 0.15rem;
  }

  /* The row's hamburger side becomes a flex strip holding both. */
  .site-mobile-header-wrap .site-header-row-has-sides > *:last-child {
    display: flex !important;
    align-items: center;
    justify-content: flex-end;
    gap: 0.1rem;
  }

  /* Icon-only in the header; the label costs width we do not have at 375px. */
  .mg-mobilebar.is-inline .mg-mobilebar__label,
  .mg-mobilebar.is-inline .mg-mobilebar__spacer {
    display: none;
  }

  .mg-mobilebar.is-inline .mg-iconbtn {
    width: 40px;
    min-width: 40px;
    height: 40px;
    padding: 0;
  }

  .mg-mobilebar.is-inline .mg-lang__btn {
    height: 38px;
    width: 62px;
    padding-inline: 0.4rem;
  }

  /* Trim Kadence's generous mobile header padding. */
  .site-mobile-header-wrap .site-main-header-inner-wrap {
    min-height: 58px !important;
    padding-block: 0.3rem !important;
  }

  .mg .mg-brand svg {
    width: 32px !important;
    height: 32px !important;
  }

  .mg .mg-brand__word {
    font-size: 1.12rem;
  }

  /* Close the gap between the header and the first block. */
  .mg-main > section:first-of-type {
    padding-top: 0.6rem;
  }

  .mg-hero {
    margin-top: 0;
  }
}

/* ==========================================================================
   30. MOBILE HEADER OVERFLOW
   Kadence sizes the mobile header row as a two-column grid. Adding the action
   controls widened the right column to 188px, and 144 + 188 = 332px against a
   327px row — so the right column started exactly where the wordmark ended and
   ran 5px past the row edge, overlapping the logo.

   Flex instead of grid lets both sides size to their content and share the
   remaining space, so they can never overlap.
   ========================================================================== */

@media (max-width: 860px) {
  .site-mobile-header-wrap .site-header-row-has-sides,
  .site-mobile-header-wrap .site-main-header-inner-wrap {
    display: flex !important;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    grid-template-columns: none !important;
  }

  /* The logo side yields space; min-width:0 is what actually allows a flex
     item to shrink below its content width. */
  .site-mobile-header-wrap .site-header-main-section-left {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
  }

  .site-mobile-header-wrap .site-header-main-section-right {
    flex: 0 0 auto;
    min-width: 0;
  }

  .mg .site-mobile-header-wrap .mg-brand {
    min-width: 0;
  }

  .mg .site-mobile-header-wrap .mg-brand__word {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
  }
}

/* On the narrowest phones the language code costs more width than it earns;
   the flag alone still identifies the current language. */
@media (max-width: 430px) {
  .mg-mobilebar.is-inline .mg-lang__code {
    display: none;
  }

  .mg-mobilebar.is-inline .mg-lang__btn {
    width: 48px;
    padding-inline: 0.3rem;
  }

  .mg-mobilebar.is-inline {
    gap: 0;
  }

  .mg-mobilebar.is-inline .mg-iconbtn {
    width: 38px;
    min-width: 38px;
  }
}

/* The shrink chain broke at Kadence's intermediate wrappers: the left section
   shrank to 97px, but .site-header-item and .site-branding kept min-width:auto
   and stayed 144px wide, spilling the wordmark over the action icons. A flex
   item will not shrink below its content unless min-width is explicitly 0, and
   that has to hold for every node in the chain. */
@media (max-width: 860px) {
  .site-mobile-header-wrap .site-header-item,
  .site-mobile-header-wrap .site-branding,
  .site-mobile-header-wrap .mobile-site-branding {
    min-width: 0 !important;
    max-width: 100%;
    overflow: hidden;
  }

  .mg .site-mobile-header-wrap .mg-brand {
    max-width: 100%;
    overflow: hidden;
  }
}

/* Below ~360px there is genuinely not room for mark plus wordmark plus four
   controls. The mark alone carries the brand; hiding the word is cleaner than
   an ellipsis that would read "Mangor…". */
@media (max-width: 360px) {
  .mg .site-mobile-header-wrap .mg-brand__word {
    display: none;
  }
}

/* ==========================================================================
   31. WOOCOMMERCE BUTTONS AND QUANTITY STEPPER

   WooCommerce and Kadence ship their own button skin, which was winning here:
   the add-to-cart button rendered as #2b6cb0 blue in Poppins 400 -- neither
   the palette nor a weight with any authority. Everything below re-skins those
   buttons onto the theme accent, and turns the bare number field into a proper
   stepper.

   White on the accent orange is only 2.9:1 and fails AA, so the label colour
   is the dark ink #241505 (5.4:1) already used by .mg-btn--accent.
   ========================================================================== */

:root {
  --mg-icon-cart: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 3h2.4l.9 3.6M7 16h10l2.4-8.4H6.3'/%3E%3Ccircle cx='8' cy='19.5' r='1.6'/%3E%3Ccircle cx='17' cy='19.5' r='1.6'/%3E%3C/svg%3E");
  --mg-icon-lock: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='4' y='10.5' width='16' height='10' rx='2'/%3E%3Cpath d='M8 10.5V7a4 4 0 0 1 8 0v3.5'/%3E%3C/svg%3E");
}

/* Kadence paints its buttons from two inherited custom properties. Retargeting
   those is far more robust than out-specifying it: its own
   `.woocommerce button.button.alt` scores (0,3,1) and beat the (0,3,0) rules
   below, which is why the button stayed #2B6CB0 blue while the font and radius
   applied. Setting the tokens on body.mg lets every Kadence button -- including
   ones this theme never names -- resolve to the palette. */
body.mg {
  --global-palette-btn-bg: var(--mg-orange);
  --global-palette-btn-bg-hover: var(--mg-orange-lt);
  --global-palette-btn: #241505;
  --global-palette-btn-hover: #241505;

  /* Kadence's link accent was #2B6CB0, the blue seen on category and content
     links. It resolves to green rather than the accent orange for two reasons:
     orange text on the light background is about 2.9:1 and fails AA, and
     keeping orange exclusive to actions means a button never reads as a link.
     Both green variants clear AA against their own background. */
  --global-palette-highlight: var(--mg-green);
  --global-palette-highlight-alt: var(--mg-green-lt);
}

/* Kadence sets `color: inherit` here at (0,3,3), which greyed the category
   link out; this reclaims it at (0,4,3). */
.mg .woocommerce div.product .product_meta > span a,
.mg.woocommerce div.product .product_meta > span a {
  color: var(--mg-green);
}

.mg .woocommerce div.product .product_meta > span a:hover,
.mg.woocommerce div.product .product_meta > span a:hover {
  color: var(--mg-orange);
}

.mg .single_add_to_cart_button,
.mg .add_to_cart_button,
.mg .button.alt,
.mg .checkout-button,
.mg .woocommerce-Button,
.mg button.button,
.mg a.button,
.mg input.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.55rem;
  min-height: 48px;
  padding: 0.75rem 1.6rem;
  border: 0;
  border-radius: var(--mg-r-pill);
  background: var(--mg-orange);
  color: #241505;
  /* Gabarito carries far more character at button size than Poppins 400. */
  font-family: "Gabarito", "Poppins", system-ui, sans-serif;
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  line-height: 1.1;
  text-decoration: none;
  cursor: pointer;
  box-shadow: 0 8px 20px -10px rgba(245, 130, 31, 0.9);
  transition:
    background var(--mg-t-micro) var(--mg-ease-soft),
    color var(--mg-t-micro) var(--mg-ease-soft),
    transform var(--mg-t-micro) var(--mg-ease-soft),
    box-shadow var(--mg-t-ui) var(--mg-ease);
}

.mg .single_add_to_cart_button:hover,
.mg .add_to_cart_button:hover,
.mg .button.alt:hover,
.mg .checkout-button:hover,
.mg button.button:hover,
.mg a.button:hover,
.mg input.button:hover {
  background: var(--mg-orange-lt);
  color: #241505;
  transform: translateY(-2px);
  box-shadow: 0 14px 26px -12px rgba(245, 130, 31, 0.95);
}

.mg .single_add_to_cart_button:active,
.mg .add_to_cart_button:active,
.mg .button.alt:active,
.mg button.button:active,
.mg a.button:active {
  transform: translateY(0) scale(0.98);
}

.mg .single_add_to_cart_button:focus-visible,
.mg .add_to_cart_button:focus-visible,
.mg .button.alt:focus-visible,
.mg button.button:focus-visible,
.mg a.button:focus-visible,
.mg input.button:focus-visible {
  outline: 3px solid var(--mg-orange);
  outline-offset: 3px;
}

/* A quieter weight for secondary actions, so each view has one clear primary
   and the rest recede. */
.mg .button:not(.alt):not(.single_add_to_cart_button):not(.add_to_cart_button):not(.checkout-button) {
  background: transparent;
  color: var(--mg-text);
  border: 1.5px solid var(--mg-border);
  box-shadow: none;
}

.mg .button:not(.alt):not(.single_add_to_cart_button):not(.add_to_cart_button):not(.checkout-button):hover {
  background: var(--mg-surface-2);
  color: var(--mg-orange);
  border-color: var(--mg-orange);
  box-shadow: none;
}

/* Cart glyph on the add-to-cart actions. Drawn as a mask rather than inline
   SVG so it inherits the label colour and needs no template override --
   WooCommerce escapes the button text, so markup cannot be filtered in. */
.mg .single_add_to_cart_button::before,
.mg .add_to_cart_button::before {
  content: "";
  width: 1.15em;
  height: 1.15em;
  flex: 0 0 auto;
  background-color: currentColor;
  -webkit-mask: var(--mg-icon-cart) center / contain no-repeat;
  mask: var(--mg-icon-cart) center / contain no-repeat;
  transition: transform var(--mg-t-ui) var(--mg-ease-spring);
}

.mg .single_add_to_cart_button:hover::before,
.mg .add_to_cart_button:hover::before {
  transform: translateX(2px) scale(1.06);
}

.mg .checkout-button::before {
  content: "";
  width: 1.15em;
  height: 1.15em;
  flex: 0 0 auto;
  background-color: currentColor;
  -webkit-mask: var(--mg-icon-lock) center / contain no-repeat;
  mask: var(--mg-icon-lock) center / contain no-repeat;
}

/* WooCommerce emits its own glyph for these states; suppress ours so the two
   never stack. */
.mg .add_to_cart_button.loading::before,
.mg .add_to_cart_button.added::before {
  display: none;
}

/* --------------------------------------------------------------------------
   Quantity stepper
   -------------------------------------------------------------------------- */

.mg .quantity {
  display: inline-flex;
  align-items: stretch;
  isolation: isolate;
  border: 1.5px solid var(--mg-border);
  border-radius: var(--mg-r-pill);
  background: var(--mg-surface);
  overflow: hidden;
}

.mg .quantity:focus-within {
  border-color: var(--mg-orange);
}

.mg .mg-qty__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* 48px keeps both controls at the native touch-target guidance. As flex
     items they shrank to the icon width without an explicit basis. */
  flex: 0 0 48px;
  width: 48px;
  min-height: 48px;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--mg-text);
  cursor: pointer;
  transition:
    background var(--mg-t-micro) var(--mg-ease-soft),
    color var(--mg-t-micro) var(--mg-ease-soft),
    transform var(--mg-t-micro) var(--mg-ease-soft);
}

.mg .mg-qty__btn svg {
  width: 17px;
  height: 17px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.2;
  stroke-linecap: round;
}

.mg .mg-qty__btn:hover:not(:disabled) {
  background: var(--mg-surface-2);
  color: var(--mg-orange);
}

.mg .mg-qty__btn:active:not(:disabled) {
  transform: scale(0.92);
}

.mg .mg-qty__btn:focus-visible {
  outline: 3px solid var(--mg-orange);
  outline-offset: -3px;
}

.mg .mg-qty__btn:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}

/* The field previously rendered white-on-grey whatever the theme, which was
   glaring in dark mode. */
.mg .quantity input.qty {
  width: 3.2rem;
  min-height: 48px;
  padding: 0 0.25rem;
  border: 0;
  border-inline: 1.5px solid var(--mg-border);
  border-radius: 0;
  background: transparent;
  color: var(--mg-text);
  font-family: "Gabarito", "Poppins", system-ui, sans-serif;
  font-size: 1rem;
  font-weight: 700;
  text-align: center;
  -moz-appearance: textfield;
  appearance: textfield;
}

.mg .quantity input.qty:focus {
  outline: none;
}

/* The native spin arrows are redundant now, and too small to hit reliably. */
.mg .quantity input.qty::-webkit-outer-spin-button,
.mg .quantity input.qty::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

/* The value pulses briefly so a tap registers without having to watch the
   number itself. */
@keyframes mg-qty-bump {
  50% {
    transform: scale(1.22);
    color: var(--mg-orange);
  }
}

.mg .quantity input.qty.is-bumped {
  animation: mg-qty-bump 260ms var(--mg-ease-spring);
}

/* The product form reads as one control group rather than two loose objects. */
.mg form.cart {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
}

/* Product meta links were inheriting a default blue. */
.mg .product_meta a,
.mg .woocommerce-breadcrumb a,
.mg .posted_in a,
.mg .tagged_as a {
  color: var(--mg-orange);
  text-underline-offset: 3px;
}

.mg .product_meta a:hover,
.mg .woocommerce-breadcrumb a:hover {
  color: var(--mg-orange-lt);
}

@media (prefers-reduced-motion: reduce) {
  .mg .quantity input.qty.is-bumped {
    animation: none;
  }

  .mg .single_add_to_cart_button,
  .mg .add_to_cart_button,
  .mg .button.alt,
  .mg button.button,
  .mg a.button,
  .mg .mg-qty__btn {
    transition: none;
  }

  .mg .single_add_to_cart_button:hover,
  .mg .add_to_cart_button:hover,
  .mg .button.alt:hover,
  .mg .mg-qty__btn:active:not(:disabled) {
    transform: none;
  }
}

/* The theme's own buttons (product tiles, promos) share the display face and
   the cart glyph, so a WooCommerce button and a theme button are not two
   different objects on the same page. */
.mg .mg-btn {
  font-family: "Gabarito", "Poppins", system-ui, sans-serif;
  font-weight: 700;
  letter-spacing: 0.01em;
}

.mg .mg-add::before {
  content: "";
  width: 1.15em;
  height: 1.15em;
  flex: 0 0 auto;
  background-color: currentColor;
  -webkit-mask: var(--mg-icon-cart) center / contain no-repeat;
  mask: var(--mg-icon-cart) center / contain no-repeat;
  transition: transform var(--mg-t-ui) var(--mg-ease-spring);
}

.mg .mg-add:hover::before {
  transform: translateX(2px) scale(1.06);
}

@media (prefers-reduced-motion: reduce) {
  .mg .mg-add::before,
  .mg .mg-add:hover::before {
    transition: none;
    transform: none;
  }
}

/* ==========================================================================
   32. PRODUCT TABS AND REVIEWS

   This whole block shipped as raw WooCommerce/Kadence default: tab pills with
   a hardcoded white background (unreadable in dark mode), a review that was
   just an undecorated list item, a white comment box, and a submit button that
   escaped the palette because `#respond input#submit` carries an ID and beats
   any class selector.
   ========================================================================== */

:root {
  --mg-icon-star: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23000'%3E%3Cpath d='M12 2.6l2.9 5.9 6.5.95-4.7 4.58 1.1 6.47L12 17.44l-5.8 3.06 1.1-6.47-4.7-4.58 6.5-.95z'/%3E%3C/svg%3E");
}

/* --------------------------------------------------------------------------
   Tab bar
   -------------------------------------------------------------------------- */

.mg .woocommerce-tabs ul.wc-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
  margin: 0 0 1.75rem;
  padding: 0;
  border-bottom: 1px solid var(--mg-border);
  list-style: none;
}

/* Kadence draws these as white boxes with a 3px radius, which read as unfilled
   form fields against the dark page. */
.mg .woocommerce-tabs ul.wc-tabs li,
.mg .woocommerce-tabs ul.wc-tabs li.active {
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
}

.mg .woocommerce-tabs ul.wc-tabs li::before,
.mg .woocommerce-tabs ul.wc-tabs li::after {
  content: none;
  display: none;
}

.mg .woocommerce-tabs ul.wc-tabs li a {
  position: relative;
  display: block;
  padding: 0.85rem 1.25rem;
  border: 0;
  background: transparent;
  color: var(--mg-text-2);
  font-family: "Gabarito", "Poppins", system-ui, sans-serif;
  font-size: 1rem;
  font-weight: 600;
  text-decoration: none;
  transition:
    color var(--mg-t-micro) var(--mg-ease-soft),
    background var(--mg-t-micro) var(--mg-ease-soft);
}

/* Same rule as the main navigation: the marker sits under the label only, and
   hover stays at 40% so it never impersonates the selected tab. */
.mg .woocommerce-tabs ul.wc-tabs li a::after {
  content: "";
  position: absolute;
  left: 1.25rem;
  right: 1.25rem;
  bottom: -1px;
  height: 3px;
  border-radius: 3px 3px 0 0;
  background: var(--mg-orange);
  opacity: 0;
  transform: scaleX(0);
  transform-origin: left center;
  transition:
    transform var(--mg-t-ui) var(--mg-ease),
    opacity var(--mg-t-ui) var(--mg-ease);
}

.mg .woocommerce-tabs ul.wc-tabs li a:hover {
  color: var(--mg-text);
}

.mg .woocommerce-tabs ul.wc-tabs li a:hover::after {
  opacity: 0.4;
  transform: scaleX(1);
}

.mg .woocommerce-tabs ul.wc-tabs li.active a {
  color: var(--mg-head);
}

.mg .woocommerce-tabs ul.wc-tabs li.active a::after,
.mg .woocommerce-tabs ul.wc-tabs li.active a:hover::after {
  opacity: 1;
  transform: scaleX(1);
}

.mg .woocommerce-tabs ul.wc-tabs li a:focus-visible {
  outline: 3px solid var(--mg-orange);
  outline-offset: -3px;
  border-radius: var(--mg-r-sm);
}

/* --------------------------------------------------------------------------
   Reviews column
   -------------------------------------------------------------------------- */

.mg #reviews .woocommerce-Reviews-title,
.mg #reviews #reply-title {
  margin: 0 0 1.5rem;
  font-family: "Gabarito", "Poppins", system-ui, sans-serif;
  font-size: clamp(1.3rem, 2.4vw, 1.7rem);
  font-weight: 800;
  letter-spacing: -0.01em;
  color: var(--mg-head);
}

.mg #reviews ol.commentlist {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 1rem;
}

/* Each review becomes a card instead of a bare list item. */
.mg #reviews ol.commentlist li.review,
.mg #reviews ol.commentlist li.comment {
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  list-style: none;
}

.mg #reviews ol.commentlist li .comment_container {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 1rem;
  align-items: start;
  padding: 1.25rem 1.35rem;
  border: 1px solid var(--mg-border);
  border-radius: var(--mg-r-md);
  background: var(--mg-surface);
  transition:
    border-color var(--mg-t-ui) var(--mg-ease-soft),
    box-shadow var(--mg-t-ui) var(--mg-ease);
}

.mg #reviews ol.commentlist li .comment_container:hover {
  border-color: color-mix(in srgb, var(--mg-orange) 45%, var(--mg-border));
  box-shadow: var(--mg-shadow-2);
}

.mg #reviews ol.commentlist li img.avatar {
  position: static;
  width: 46px;
  height: 46px;
  margin: 0;
  padding: 0;
  border: 2px solid var(--mg-border);
  border-radius: 50%;
  background: var(--mg-surface-2);
  float: none;
}

.mg #reviews ol.commentlist li .comment-text {
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  min-width: 0;
}

.mg #reviews .comment-text .meta {
  margin: 0 0 0.6rem;
  font-size: 0.9rem;
  color: var(--mg-text-2);
}

.mg #reviews .comment-text .meta strong {
  display: inline;
  font-family: "Gabarito", "Poppins", system-ui, sans-serif;
  font-size: 1rem;
  font-weight: 700;
  color: var(--mg-head);
}

.mg #reviews .comment-text .description p:last-child {
  margin-bottom: 0;
}

/* The star row sits top-right of the card on wider cards, inline above the
   text when the card is narrow. */
.mg #reviews .comment-text .star-rating {
  float: right;
  margin: 0 0 0.5rem 1rem;
}

/* --------------------------------------------------------------------------
   Star ratings (display)
   WooCommerce renders these as text glyphs; recolouring is all that is needed,
   but the empty state must stay visible rather than vanish into the surface.
   -------------------------------------------------------------------------- */

.mg .star-rating {
  color: var(--mg-orange);
  letter-spacing: 2px;
}

.mg .star-rating::before {
  color: var(--mg-border);
}

/* --------------------------------------------------------------------------
   Review form
   -------------------------------------------------------------------------- */

.mg #review_form_wrapper .comment-respond,
.mg #reviews .comment-respond {
  padding: 1.5rem;
  border: 1px solid var(--mg-border);
  border-radius: var(--mg-r-md);
  background: var(--mg-surface);
}

.mg #reviews .comment-form label {
  display: block;
  margin-bottom: 0.4rem;
  font-size: 0.92rem;
  font-weight: 600;
  color: var(--mg-text);
}

.mg #reviews .comment-form .required {
  color: var(--mg-orange);
  text-decoration: none;
}

.mg #reviews .comment-form-comment,
.mg #reviews .comment-form-rating,
.mg #reviews .comment-form-author,
.mg #reviews .comment-form-email {
  margin-bottom: 1.1rem;
}

/* The comment box was white with dark text regardless of theme. */
.mg #reviews .comment-form textarea,
.mg #reviews .comment-form input[type="text"],
.mg #reviews .comment-form input[type="email"] {
  width: 100%;
  padding: 0.8rem 1rem;
  border: 1.5px solid var(--mg-border);
  border-radius: var(--mg-r-sm);
  background: var(--mg-page);
  color: var(--mg-text);
  font-family: inherit;
  font-size: 0.98rem;
  line-height: 1.6;
  transition:
    border-color var(--mg-t-micro) var(--mg-ease-soft),
    box-shadow var(--mg-t-micro) var(--mg-ease-soft);
}

.mg #reviews .comment-form textarea {
  min-height: 140px;
  resize: vertical;
}

.mg #reviews .comment-form textarea:focus,
.mg #reviews .comment-form input[type="text"]:focus,
.mg #reviews .comment-form input[type="email"]:focus {
  outline: none;
  border-color: var(--mg-orange);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--mg-orange) 25%, transparent);
}

/* --------------------------------------------------------------------------
   Star rating input
   WooCommerce ships these as 17px text links -- well under a usable target.
   -------------------------------------------------------------------------- */

.mg #reviews p.stars {
  display: flex;
  gap: 0.15rem;
  margin: 0;
}

.mg #reviews p.stars span {
  display: flex;
  gap: 0.15rem;
}

.mg #reviews p.stars a {
  position: relative;
  width: 40px;
  height: 40px;
  margin: 0;
  text-indent: -9999px;
  overflow: hidden;
  border-radius: var(--mg-r-sm);
}

.mg #reviews p.stars a::before,
.mg #reviews p.stars a::after {
  content: "";
  position: absolute;
  inset: 0;
  margin: auto;
  width: 26px;
  height: 26px;
  text-indent: 0;
  -webkit-mask: var(--mg-icon-star) center / contain no-repeat;
  mask: var(--mg-icon-star) center / contain no-repeat;
}

.mg #reviews p.stars a::before {
  background-color: var(--mg-border);
}

/* The filled star is layered over the empty one and revealed on hover or once
   a rating is chosen, so the control reads as a rating rather than five links. */
.mg #reviews p.stars a::after {
  background-color: var(--mg-orange);
  opacity: 0;
  transform: scale(0.8);
  transition:
    opacity var(--mg-t-micro) var(--mg-ease-soft),
    transform var(--mg-t-micro) var(--mg-ease-spring);
}

.mg #reviews p.stars:hover a::after,
.mg #reviews p.stars a.active::after,
.mg #reviews p.stars a.selected::after {
  opacity: 1;
  transform: scale(1);
}

/* Hovering star 3 should not leave stars 4 and 5 lit. */
.mg #reviews p.stars a:hover ~ a::after {
  opacity: 0;
  transform: scale(0.8);
}

.mg #reviews p.stars a:focus-visible {
  outline: 3px solid var(--mg-orange);
  outline-offset: 2px;
}

/* --------------------------------------------------------------------------
   Submit button
   `#respond input#submit` scores (1,0,1); no class selector can reach it, so
   the primary button style is restated here at ID strength.
   -------------------------------------------------------------------------- */

.mg #reviews #respond input#submit,
.mg #reviews #respond input#submit.submit {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  padding: 0.75rem 1.75rem;
  border: 0;
  border-radius: var(--mg-r-pill);
  background: var(--mg-orange);
  color: #241505;
  font-family: "Gabarito", "Poppins", system-ui, sans-serif;
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  cursor: pointer;
  box-shadow: 0 8px 20px -10px rgba(245, 130, 31, 0.9);
  transition:
    background var(--mg-t-micro) var(--mg-ease-soft),
    transform var(--mg-t-micro) var(--mg-ease-soft),
    box-shadow var(--mg-t-ui) var(--mg-ease);
}

.mg #reviews #respond input#submit:hover {
  background: var(--mg-orange-lt);
  transform: translateY(-2px);
  box-shadow: 0 14px 26px -12px rgba(245, 130, 31, 0.95);
}

.mg #reviews #respond input#submit:active {
  transform: translateY(0) scale(0.98);
}

.mg #reviews #respond input#submit:focus-visible {
  outline: 3px solid var(--mg-orange);
  outline-offset: 3px;
}

/* Germanized appends a purchase-verification note to each review. */
.mg #reviews .woocommerce-review__verified,
.mg #reviews .wc-gzd-review-authenticity {
  display: inline-block;
  margin-top: 0.6rem;
  font-size: 0.83rem;
  color: var(--mg-text-2);
}

/* --------------------------------------------------------------------------
   Layout
   -------------------------------------------------------------------------- */

@media (min-width: 900px) {
  .mg #reviews #comments {
    margin-bottom: 0;
  }
}

@media (max-width: 899px) {
  .mg #reviews .comment-text .star-rating {
    float: none;
    margin: 0 0 0.5rem;
  }

  .mg #reviews ol.commentlist li .comment_container {
    padding: 1.1rem;
    gap: 0.85rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  .mg .woocommerce-tabs ul.wc-tabs li a,
  .mg .woocommerce-tabs ul.wc-tabs li a::after,
  .mg #reviews p.stars a::after,
  .mg #reviews #respond input#submit,
  .mg #reviews ol.commentlist li .comment_container {
    transition: none;
  }

  .mg #reviews #respond input#submit:hover {
    transform: none;
  }
}

/* --------------------------------------------------------------------------
   32b. Reclaiming the tab bar and avatar from Kadence

   Kadence targets these with `.woocommerce div.product .woocommerce-tabs
   ul.tabs li` -- (0,4,3), which beat the (0,3,2) rules above and kept the tabs
   painted white. The avatar rule is worse still at (2,3,3), carrying two IDs.
   Body has both `mg` and `woocommerce`, so mirroring Kadence's own selector
   with `body.mg` prefixed adds exactly one class and wins, without resorting
   to !important.
   -------------------------------------------------------------------------- */

body.mg.woocommerce div.product .woocommerce-tabs ul.tabs {
  margin: 0 0 1.75rem;
  padding: 0;
  border: 0;
  border-bottom: 1px solid var(--mg-border);
  background: transparent;
  box-shadow: none;
}

body.mg.woocommerce div.product .woocommerce-tabs ul.tabs li,
body.mg.woocommerce div.product .woocommerce-tabs ul.tabs li.active {
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  background-color: transparent;
  box-shadow: none;
}

/* WooCommerce draws the classic curved tab shoulders with these. */
body.mg.woocommerce div.product .woocommerce-tabs ul.tabs li::before,
body.mg.woocommerce div.product .woocommerce-tabs ul.tabs li::after,
body.mg.woocommerce div.product .woocommerce-tabs ul.tabs li.active::before,
body.mg.woocommerce div.product .woocommerce-tabs ul.tabs li.active::after {
  content: none;
  display: none;
  border: 0;
  box-shadow: none;
}

body.mg.woocommerce div.product .woocommerce-tabs ul.tabs li a {
  color: var(--mg-text-2);
  font-family: "Gabarito", "Poppins", system-ui, sans-serif;
  font-weight: 600;
  text-shadow: none;
}

body.mg.woocommerce div.product .woocommerce-tabs ul.tabs li a:hover {
  color: var(--mg-text);
}

body.mg.woocommerce div.product .woocommerce-tabs ul.tabs li.active a {
  color: var(--mg-head);
  font-weight: 700;
}

body.mg.woocommerce #reviews #comments ol.commentlist li img.avatar {
  position: static;
  width: 46px;
  height: 46px;
  margin: 0;
  padding: 0;
  border: 2px solid var(--mg-border);
  border-radius: 50%;
  background: var(--mg-surface-2);
  box-shadow: none;
  float: none;
}

/* The default card is a bordered box with the avatar absolutely positioned
   into a reserved gutter; the grid above supplies the columns instead. */
body.mg.woocommerce #reviews #comments ol.commentlist li .comment-text {
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
}

/* ==========================================================================
   33. REVIEWS - DENSITY PASS

   Two corrections to section 32:

   1. The duplicate rule above the tabs was self-inflicted. Section 32b applied
      `border-bottom` to `ul.tabs` AND to `ul.tabs::before` in one selector
      list, and WooCommerce's ::before is a full-width line element -- so it
      drew its own border alongside the real one. The pseudo-element is
      switched off here and only the list keeps a border.

   2. The first pass was laid out on a generous scale that left the column
      mostly air. Every measurement below is tightened so the block reads as
      one composed unit rather than widely spaced fragments.
   ========================================================================== */

/* -- 1. The extra separator ------------------------------------------------ */

body.mg.woocommerce div.product .woocommerce-tabs ul.tabs::before,
body.mg.woocommerce div.product .woocommerce-tabs ul.tabs::after {
  content: none;
  display: none;
  border: 0;
}

body.mg.woocommerce div.product .woocommerce-tabs ul.tabs {
  margin: 0 0 1.15rem;
  border-bottom: 1px solid var(--mg-border);
}

/* Kadence also rules off the section above the tabs; with our own border that
   reads as a second line stacked on the first. */
body.mg.woocommerce div.product .woocommerce-tabs {
  /* The wrapper carries its own 1px #cbd5e0 rule from Kadence -- off-palette,
     and a second line stacked near the tab bar's own border. The bar's border
     is the divider; this one goes. */
  border-top: 0;
  border-bottom: 0;
  padding-top: 0;
}

/* -- 2. Density ------------------------------------------------------------ */

.mg .woocommerce-tabs ul.wc-tabs li a {
  padding: 0.55rem 0.95rem;
  font-size: 0.95rem;
}

.mg .woocommerce-tabs ul.wc-tabs li a::after {
  left: 0.95rem;
  right: 0.95rem;
}

.mg #reviews .woocommerce-Reviews-title,
.mg #reviews #reply-title {
  display: block;
  margin: 0 0 0.9rem;
  font-size: clamp(1.15rem, 1.9vw, 1.4rem);
  line-height: 1.25;
}

.mg #reviews ol.commentlist {
  gap: 0.55rem;
}

.mg #reviews ol.commentlist li .comment_container {
  gap: 0.8rem;
  padding: 0.9rem 1rem;
  border-radius: var(--mg-r-sm);
}

body.mg.woocommerce #reviews #comments ol.commentlist li img.avatar {
  width: 38px;
  height: 38px;
  border-width: 1px;
}

.mg #reviews .comment-text .meta {
  margin: 0 0 0.3rem;
  font-size: 0.86rem;
  line-height: 1.35;
}

.mg #reviews .comment-text .meta strong {
  font-size: 0.95rem;
}

.mg #reviews .comment-text .description p {
  margin: 0 0 0.35rem;
  font-size: 0.95rem;
  line-height: 1.55;
}

.mg #reviews .comment-text .description p:last-child {
  margin-bottom: 0;
}

/* Germanized's authenticity note is secondary information and was taking a
   full text line at body size. */
.mg #reviews .wc-gzd-review-authenticity,
.mg #reviews .wc-gzd-review-authenticity-status,
.mg #reviews p.wc-gzd-additional-info {
  margin: 0.45rem 0 0;
  font-size: 0.8rem;
  line-height: 1.4;
  color: var(--mg-text-2);
}

.mg #reviews .comment-text .star-rating {
  margin: 0 0 0.35rem 1rem;
  font-size: 0.95em;
}

/* -- Form ------------------------------------------------------------------ */

.mg #review_form_wrapper .comment-respond,
.mg #reviews .comment-respond {
  padding: 1.1rem 1.15rem;
  border: 1px solid var(--mg-border);
  border-radius: var(--mg-r-sm);
  background: var(--mg-surface);
}

.mg #reviews .comment-form-comment,
.mg #reviews .comment-form-rating,
.mg #reviews .comment-form-author,
.mg #reviews .comment-form-email,
.mg #reviews .comment-form-cookies-consent {
  margin-bottom: 0.75rem;
}

.mg #reviews .comment-form label {
  margin-bottom: 0.25rem;
  font-size: 0.88rem;
}

.mg #reviews .comment-form textarea {
  min-height: 104px;
  padding: 0.65rem 0.85rem;
  font-size: 0.95rem;
  line-height: 1.55;
}

.mg #reviews .comment-form input[type="text"],
.mg #reviews .comment-form input[type="email"] {
  padding: 0.6rem 0.85rem;
  font-size: 0.95rem;
}

.mg #reviews .comment-form .form-submit {
  margin: 0.9rem 0 0;
}

.mg #reviews #respond input#submit,
.mg #reviews #respond input#submit.submit {
  min-height: 44px;
  padding: 0.6rem 1.5rem;
  font-size: 0.95rem;
}

/* The five targets stay comfortably tappable but no longer sprawl. */
.mg #reviews p.stars {
  gap: 0;
  margin: 0;
}

.mg #reviews p.stars span {
  gap: 0;
}

.mg #reviews p.stars a {
  width: 34px;
  height: 34px;
}

.mg #reviews p.stars a::before,
.mg #reviews p.stars a::after {
  width: 21px;
  height: 21px;
}

/* WooCommerce prints a paragraph of comment-policy text under the form. */
.mg #reviews .comment-form-cookies-consent label,
.mg #reviews .comment-notes {
  font-size: 0.83rem;
  line-height: 1.45;
  color: var(--mg-text-2);
}

.mg #reviews .comment-notes {
  margin: 0 0 0.75rem;
}

/* -- Column rhythm --------------------------------------------------------- */

@media (min-width: 900px) {
  .mg #reviews #comments,
  .mg #reviews #review_form_wrapper {
    margin-bottom: 0;
  }
}

@media (max-width: 899px) {
  .mg #reviews #review_form_wrapper {
    margin-top: 1.25rem;
  }

  .mg #reviews ol.commentlist li .comment_container {
    padding: 0.85rem 0.9rem;
  }
}


/* --------------------------------------------------------------------------
   33b. Three rules WooCommerce was still winning

   Measured, not guessed:
     .woocommerce div.product .woocommerce-tabs ul.tabs li a  (0,4,4)
     .woocommerce #reviews #comments h2                       (2,1,1)
     .woocommerce #review_form #respond                       (2,1,0)

   against section 33's (0,3,3), (1,2,0) and (1,2,0). The last one is why the
   form card had a border and a radius but no padding -- WooCommerce zeroes it
   with two IDs. Each rule below mirrors WooCommerce's own selector with
   `body.mg` added, which is the smallest increment that wins.
   -------------------------------------------------------------------------- */

body.mg.woocommerce div.product .woocommerce-tabs ul.tabs li a {
  padding: 0.55rem 0.95rem;
  font-size: 0.95rem;
}

body.mg.woocommerce div.product .woocommerce-tabs ul.tabs li a::after {
  left: 0.95rem;
  right: 0.95rem;
}

body.mg.woocommerce #reviews #comments h2,
body.mg.woocommerce #reviews #comments h2.woocommerce-Reviews-title {
  margin: 0 0 0.9rem;
  font-family: "Gabarito", "Poppins", system-ui, sans-serif;
  font-size: clamp(1.15rem, 1.9vw, 1.4rem);
  font-weight: 800;
  line-height: 1.25;
  letter-spacing: -0.01em;
  color: var(--mg-head);
}

body.mg.woocommerce #reviews #review_form #respond #reply-title,
body.mg.woocommerce #reviews #respond #reply-title {
  display: block;
  margin: 0 0 0.9rem;
  font-family: "Gabarito", "Poppins", system-ui, sans-serif;
  font-size: clamp(1.15rem, 1.9vw, 1.4rem);
  font-weight: 800;
  line-height: 1.25;
  letter-spacing: -0.01em;
  color: var(--mg-head);
}

body.mg.woocommerce #review_form #respond,
body.mg.woocommerce #reviews #respond {
  padding: 1.1rem 1.15rem;
  border: 1px solid var(--mg-border);
  border-radius: var(--mg-r-sm);
  background: var(--mg-surface);
}

/* The cancel-reply link rides along inside the heading and inherits its 800
   weight and size otherwise. */
body.mg.woocommerce #reviews #respond #reply-title small {
  display: inline;
  margin-left: 0.5rem;
  font-size: 0.8rem;
  font-weight: 500;
  letter-spacing: 0;
}

/* --------------------------------------------------------------------------
   33c. Form field rhythm

   Every field in the review form is a <p>, and Kadence's
   `.woocommerce #review_form #respond p` (2,1,1) applies its default 1.5em
   paragraph margin -- 25.5px between each. Section 33's (1,2,0) rule only won
   on .comment-form-rating, which is a <div> and so never matched the `p`
   selector. That single miss was most of the empty space in the column.
   -------------------------------------------------------------------------- */

body.mg.woocommerce #review_form #respond p,
body.mg.woocommerce #reviews #respond p {
  margin: 0 0 0.7rem;
}

body.mg.woocommerce #review_form #respond p.comment-notes,
body.mg.woocommerce #reviews #respond p.comment-notes {
  margin: 0 0 0.7rem;
}

/* No trailing gap under the button inside the card. */
body.mg.woocommerce #review_form #respond p.form-submit,
body.mg.woocommerce #reviews #respond p.form-submit {
  margin: 0.85rem 0 0;
}

body.mg.woocommerce #reviews #respond .comment-form-rating {
  margin: 0 0 0.7rem;
}

/* --------------------------------------------------------------------------
   33d. Card surfaces

   In light mode --mg-surface and --mg-page are both #ffffff, so the review and
   form cards were white on white and carried by a faint border alone.
   --mg-surface-2 is the palette cream (#fff7ef) in light and a lifted tone in
   dark, so both themes get a card that actually reads as one.
   -------------------------------------------------------------------------- */

.mg #reviews ol.commentlist li .comment_container {
  background: var(--mg-surface-2);
}

body.mg.woocommerce #review_form #respond,
body.mg.woocommerce #reviews #respond {
  background: var(--mg-surface-2);
}

/* Keeps the input distinct from the card it sits on, in both directions. */
.mg #reviews .comment-form textarea,
.mg #reviews .comment-form input[type="text"],
.mg #reviews .comment-form input[type="email"] {
  background: var(--mg-page);
}

/* ==========================================================================
   34. HEADER ACTION ICONS - ALIGNMENT

   The account and cart controls are <a> elements inside a nav <li>, so they
   were picking up Kadence's menu-link styling:

     .header-navigation li.menu-item > a                       (0,2,2)
     .main-navigation .primary-menu-container > ul > li > a    (0,4,3)  inline

   against .mg .mg-iconbtn at (0,2,0). That forced display:block, width:100%
   and 0.6em padding, which made the flex centring inert -- the glyph sat at
   the padding origin in a 60x40 box instead of the middle. The <button>
   versions kept flex but collapsed to 20px, since a flex item with a width
   and no shrink guard is free to shrink; they only looked right because
   shrinking is symmetrical.

   The selector below is (0,5,2): one more class than the inline rule, so it
   wins without !important.
   ========================================================================== */

body.mg .header-navigation li.menu-item.mg-actions .mg-iconbtn,
body.mg .header-navigation li.menu-item.mg-actions > a.mg-iconbtn,
body.mg .header-navigation li.menu-item.mg-actions > button.mg-iconbtn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* Fixed basis: the glyph box must not shrink, or the circle turns oval. */
  flex: 0 0 40px;
  width: 40px;
  min-width: 40px;
  height: 40px;
  padding: 0;
  border-radius: 50%;
  line-height: 1;
}

/* No `display` here: the theme toggle holds both a sun and a moon and hides
   one via .mg-i-sun / .mg-i-moon rules that this selector would outrank,
   leaving both glyphs rendered side by side in a 40px box. */
body.mg .header-navigation li.menu-item.mg-actions .mg-iconbtn svg {
  flex: 0 0 20px;
}

/* The underline marker is a text-link affordance and was being inherited from
   the main-navigation rules; under a circular icon button it reads as a stray
   orange bar rather than a state. */
body.mg .header-navigation li.menu-item.mg-actions .mg-iconbtn::after,
body.mg .header-navigation li.menu-item.mg-actions > a::after,
body.mg .header-navigation li.menu-item.mg-actions .mg-lang__btn::after {
  content: none;
  display: none;
}

/* ==========================================================================
   35. MILLSTONE PASS

   Ports the composition and motion language of the Crimson Mill visiting card
   onto the shop, without importing its palette. Crimson's role there -- one
   decisive accent -- is already filled here by --mg-orange, and wheat gold's
   warm-secondary role by the tint scale, so no new hue is introduced.

   Three things carry that template's character, in order of weight:
     1. a condensed uppercase label face, widely tracked,
     2. reveals that commit late and travel slowly,
     3. press feedback on everything tappable.

   Everything below is one of those three, or scenery that supports them.
   ========================================================================== */

:root {
  /* Oswald sets small uppercase labels only -- eyebrows, chips, badges, the
     ticker. Headlines stay Gabarito: swapping the display face outright would
     change the brand's voice, which is not a decision CSS should make. */
  --mg-font-label: "Oswald", "Gabarito", system-ui, sans-serif;

  /* The ticker band and the hero seal are the two new tinted surfaces. Both
     are declared as semantic tokens so the dark block only repoints these. */
  --mg-band: var(--mg-tint-5);
  --mg-band-text: var(--mg-green);
  --mg-band-line: rgba(31, 42, 36, 0.1);
  --mg-seal-bg: #fdefd2;
  --mg-seal-fg: #8a5a10;
  --mg-seal-ring: rgba(255, 255, 255, 0.85);

  /* Derived, not new: the same hue as --mg-orange taken dark enough to set
     10px text. The bright accent is a fill colour -- #d96d0e measures 3.2:1
     on cream, so an eyebrow painted in it fails AA outright. This is the same
     move the brand notes already make for --olive-dk, and for the same reason:
     the sampled set has nothing dark enough for small type. */
  --mg-accent-ink: #8f4a08;
}

:root[data-theme="dark"] {
  --mg-band: #21392f;
  --mg-band-text: #c9dccf;
  --mg-band-line: rgba(201, 220, 207, 0.15);
  --mg-seal-bg: #34290f;
  --mg-seal-fg: #f0cd7c;
  --mg-seal-ring: rgba(238, 234, 229, 0.22);
  --mg-accent-ink: var(--mg-orange-lt);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --mg-band: #21392f;
    --mg-band-text: #c9dccf;
    --mg-band-line: rgba(201, 220, 207, 0.15);
    --mg-seal-bg: #34290f;
    --mg-seal-fg: #f0cd7c;
    --mg-seal-ring: rgba(238, 234, 229, 0.22);
    --mg-accent-ink: var(--mg-orange-lt);
  }
}

/* --------------------------------------------------------------------------
   35a. The label face

   `.mg-label` is the shared recipe; the rest of this block is the list of
   places that adopt it. Wide tracking on uppercase is what makes the type read
   as stamped rather than merely small -- but German runs longer than English
   and stacks umlauts above the cap line, so tracking stays at 0.16em and
   line-height never drops below 1.1.
   -------------------------------------------------------------------------- */

.mg-label,
.mg-hero__eyebrow,
.mg-promo__eyebrow,
.mg-chip,
.mg-ticker,
.mg .mg-card__badge {
  font-family: var(--mg-font-label);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  line-height: 1.15;
  font-variant-ligatures: none;
}

/* Oswald's cap height runs tall for its point size, so the eyebrows need a
   touch less than they did in Poppins to hold the same optical weight. */
.mg-hero__eyebrow,
.mg-promo__eyebrow {
  font-size: 0.68rem;
  letter-spacing: 0.2em;
  color: var(--mg-accent-ink);
}

/* Trailing letter-spacing pushes the last glyph off-centre inside a pill or a
   badge. Half the tracking added back as right padding re-centres it. */
.mg .mg-card__badge {
  font-size: 0.64rem;
  padding-right: calc(0.7rem + 0.16em);
}

/* --------------------------------------------------------------------------
   35b. Hero chips

   A trust row under the lead. These are claims, so each one has to be true of
   the shop as it actually operates -- see front-page.php for the wording.
   -------------------------------------------------------------------------- */

.mg-hero__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin: 0;
  padding: 0;
  list-style: none;

  /* .mg-hero__copy is a flex column with `align-items: flex-start`, so every
     child is sized to its own content rather than to the column. Left alone,
     this list resolves to max-content, `flex-wrap` never has a narrow enough
     line box to act on, and the row pushes the whole page wider than the
     viewport on a phone. Stretching it back to the column restores wrapping. */
  align-self: stretch;
  max-width: 100%;
}

.mg-chip {
  font-size: 0.6rem;
  padding: 0.38rem 0.7rem;
  padding-right: calc(0.7rem + 0.16em);
  border-radius: var(--mg-r-pill);
  background: var(--mg-surface-2);
  border: 1px solid var(--mg-border);
  color: var(--mg-text);
  white-space: nowrap;
}

/* --------------------------------------------------------------------------
   35c. Hero seal

   A rotated tile stamped onto the slide image. It sits on the hero container
   rather than inside a slide so it is rendered once instead of three times,
   and it keeps a light ring so it separates from any photograph underneath.
   -------------------------------------------------------------------------- */

.mg-hero__seal {
  position: absolute;
  top: 0.9rem;
  right: 0.9rem;
  z-index: 4;
  width: 74px;
  height: 74px;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 0.15rem;
  border-radius: 20px;
  background: var(--mg-seal-bg);
  color: var(--mg-seal-fg);
  box-shadow:
    0 0 0 3px var(--mg-seal-ring),
    0 10px 22px -12px rgba(31, 42, 36, 0.7);
  transform: rotate(-8deg);
  pointer-events: none;
}

.mg-hero__seal svg {
  display: block;
  width: 30px;
  height: 30px;
}

/* Below the hero's stacking breakpoint the image moves above the copy and
   shortens, so the seal moves with it and loses a little size. */
@media (max-width: 820px) {
  .mg-hero__seal {
    width: 60px;
    height: 60px;
    border-radius: 16px;
    top: 0.6rem;
    right: 0.6rem;
  }
  .mg-hero__seal svg {
    width: 25px;
    height: 25px;
  }
}

@media (prefers-reduced-motion: no-preference) {
  .mg-js .mg-hero__seal {
    opacity: 0;
    transform: rotate(-8deg) scale(0.86);
    animation: mg-seal-in var(--mg-t-hero) var(--mg-ease-spring) 520ms forwards;
  }
}

@keyframes mg-seal-in {
  to {
    opacity: 1;
    transform: rotate(-8deg) scale(1);
  }
}

/* --------------------------------------------------------------------------
   35d. Ticker

   Two identical sets side by side; the track slides exactly -50% so the wrap
   lands on a seam that matches. `width: max-content` stops the sets from being
   squeezed to the container, which would break that alignment.

   motion.js adds `.is-idle` when the strip scrolls out of view. A marquee is a
   compositor animation that otherwise runs for the whole session, on every
   page, including behind a scrolled-past viewport.
   -------------------------------------------------------------------------- */

.mg-ticker {
  overflow: hidden;
  background: var(--mg-band);
  color: var(--mg-band-text);
  border-bottom: 1px solid var(--mg-band-line);
  font-size: 0.62rem;
}

.mg-ticker__track {
  display: flex;
  width: max-content;
  will-change: transform;
}

@media (prefers-reduced-motion: no-preference) {
  .mg-js .mg-ticker__track {
    animation: mg-marquee 38s linear infinite;
  }
  .mg-ticker:hover .mg-ticker__track,
  .mg-ticker:focus-within .mg-ticker__track,
  .mg-ticker.is-idle .mg-ticker__track {
    animation-play-state: paused;
  }
}

@keyframes mg-marquee {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(-50%);
  }
}

.mg-ticker__set {
  display: flex;
  align-items: center;
  margin: 0;
  padding: 0;
  list-style: none;
}

.mg-ticker__set li {
  display: flex;
  align-items: center;
  padding: 0.5rem 0;
}

/* The separator is drawn rather than typed so it never gets read aloud. */
.mg-ticker__set li::after {
  content: "";
  width: 4px;
  height: 4px;
  margin: 0 1.15rem;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.45;
}

/* --------------------------------------------------------------------------
   35e. Scroll rail

   A gradient stripe is decoration; a gradient stripe that reports how far down
   the page you are is a control. Driven entirely by `animation-timeline`, so
   it costs no script and no scroll listener. Where that is unsupported the
   fill simply stays at scaleX(0) and the rail is invisible -- which is the
   correct fallback for something that only ever conveys progress.
   -------------------------------------------------------------------------- */

.mg-rail {
  position: fixed;
  inset: 0 0 auto 0;
  height: 3px;
  z-index: 90;
  pointer-events: none;
}

.mg-rail__fill {
  display: block;
  height: 100%;
  width: 100%;
  transform: scaleX(0);
  transform-origin: 0 50%;
  background: linear-gradient(
    90deg,
    var(--mg-orange) 0%,
    var(--mg-orange-lt) 45%,
    var(--mg-green-lt) 100%
  );
}

@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    .mg-rail__fill {
      animation: mg-rail-grow linear forwards;
      animation-timeline: scroll(root block);
    }
  }
}

@keyframes mg-rail-grow {
  from {
    transform: scaleX(0);
  }
  to {
    transform: scaleX(1);
  }
}

/* --------------------------------------------------------------------------
   35f. Reveal timing

   Same observer, same curve -- only the numbers change. The template's cards
   commit later (14% visible instead of the first pixel) and travel for 800ms
   instead of 560ms, and that difference is most of why they read as composed
   rather than as nine separate animations. The threshold and root margin live
   in motion.js; the duration and distance are here.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: no-preference) {
  .mg-js .mg-reveal {
    transform: translateY(16px);
    transition:
      opacity 780ms var(--mg-ease),
      transform 780ms var(--mg-ease);
  }
}

/* --------------------------------------------------------------------------
   35g. Press feedback

   The single biggest felt difference on a touch screen, and it is four rules.
   Buttons take the full 0.96 the template uses; a product tile is many times
   larger, and the same factor on that area reads as the page lurching, so the
   cards settle at 0.985.
   -------------------------------------------------------------------------- */

.mg .mg-btn:active {
  transform: scale(0.96);
}

.mg .mg-card:active,
.mg .mg-cat:active,
.mg .mg-promo:active {
  transform: scale(0.985);
  transition-duration: var(--mg-t-micro);
}

@media (prefers-reduced-motion: reduce) {
  .mg .mg-btn:active,
  .mg .mg-card:active,
  .mg .mg-cat:active,
  .mg .mg-promo:active {
    transform: none;
  }
}

/* The showcase zoom: a touch further and appreciably slower than before, which
   is what makes it read as the image breathing rather than snapping. */
.mg .mg-card__media img,
.mg .mg-card__media .mg-ph {
  transition: transform var(--mg-t-breathe) var(--mg-ease);
}

.mg .mg-card:hover .mg-card__media img,
.mg .mg-card:hover .mg-card__media .mg-ph {
  transform: scale(1.06);
}

/* --------------------------------------------------------------------------
   35h. Newsletter as a split card

   The template's location card is a tinted information panel welded to a
   bordered action rail, horizontal on desktop and stacked on mobile. The
   newsletter block already had the right two children; it only needed the
   padding moved off the container and onto each half so the seam can show.
   -------------------------------------------------------------------------- */

.mg-news {
  padding: 0;
  gap: 0;
  align-items: stretch;
  border: 1px solid var(--mg-border);
}

.mg-news__panel {
  padding: clamp(1.4rem, 3vw, 2.2rem);
  background: linear-gradient(160deg, var(--mg-band), transparent 90%);
}

.mg-news__form {
  padding: clamp(1.4rem, 3vw, 2.2rem);
  background: var(--mg-surface);
  border-left: 1px solid var(--mg-border);
  align-items: center;
}

@media (max-width: 780px) {
  .mg-news__form {
    border-left: 0;
    border-top: 1px solid var(--mg-border);
  }
}

/* --------------------------------------------------------------------------
   35i. Focus

   Oswald labels and rotated tiles are new focus surfaces. One visible ring,
   drawn outside the element so it survives `overflow: hidden` parents.
   -------------------------------------------------------------------------- */

.mg .mg-ticker a:focus-visible,
.mg .mg-chip:focus-visible {
  outline: 3px solid var(--mg-orange);
  outline-offset: 3px;
}

/* --------------------------------------------------------------------------
   35j. Dark-mode overrides that only ever existed for the explicit toggle

   Pre-existing defect, surfaced while restyling the badges. Both of these had
   a `:root[data-theme="dark"]` rule flipping their label to near-black, but no
   `prefers-color-scheme` counterpart -- so a visitor who had never touched the
   toggle and simply runs their OS in dark mode saw white text on the light
   mint that --mg-green becomes in the dark palette. Measured at 2.2:1 against
   a 4.5:1 requirement.

   Specificity is (0,3,0), which also clears `.mg-btn--green:hover` at (0,2,0)
   so the label does not flip back to white on hover.
   -------------------------------------------------------------------------- */

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .mg-card__badge--new,
  :root:not([data-theme="light"]) .mg-btn--green,
  :root:not([data-theme="light"]) .mg-btn--green:hover {
    color: #10170d;
  }
}

/* --------------------------------------------------------------------------
   35k. Parent-theme chrome that never got the dark treatment

   Two more of the same defect as 35j, found by sweeping the product page
   rather than by looking: both hardcode a colour chosen for a light page and
   have no dark counterpart at all.

     Kadence breadcrumbs   #4a5568 slate on the dark page  -> 2.4:1
     WooCommerce .onsale   #fff on the mint --mg-green     -> 2.2:1

   The sale flash is the same object as .mg-card__badge, so it is given the
   same fill and the same label face rather than a second, unrelated style.

   Specificity mirrors each owner's own selector with `body.mg` prefixed, which
   is the smallest increment that wins: Kadence's is (0,2,1) and WooCommerce's
   `.woocommerce span.onsale` is (0,2,1); both of these are (0,3,1).
   -------------------------------------------------------------------------- */

body.mg .kadence-breadcrumbs a,
body.mg .kadence-breadcrumbs .bc-delimiter {
  color: var(--mg-text-2);
}

body.mg .kadence-breadcrumbs a:hover,
body.mg .kadence-breadcrumbs .kadence-bread-current {
  color: var(--mg-text);
}

body.mg.woocommerce span.onsale,
body.mg.woocommerce-page span.onsale {
  background: var(--mg-orange);
  color: #241505;
  font-family: var(--mg-font-label);
  font-weight: 600;
  font-size: 0.64rem;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  padding: 0.28rem 0.7rem;
  padding-right: calc(0.7rem + 0.16em);
  min-height: 0;
  line-height: 1.6;
  border-radius: var(--mg-r-pill);
}

/* --------------------------------------------------------------------------
   35l. The rest of the toggle-only dark rules

   Same defect as 35j and 35k, enumerated rather than spotted: every rule in
   the sheet written as `:root[data-theme="dark"] X` was compared against the
   selectors covered inside a `@media (prefers-color-scheme: dark)` block. Four
   were covered; these were not. All of them therefore applied only to a
   visitor who had pressed the theme toggle, and never to one whose operating
   system is simply set to dark -- which is the larger group, and the one whose
   very first page view is affected.

   The worst was .mg-promo--green: it kept its light mint panel while the text
   on it switched to the dark palette's near-white, so the gift promo rendered
   as pale text on pale mint. Contrast auditing missed it because the audit
   drives the toggle, which is exactly the state that was already correct.
   -------------------------------------------------------------------------- */

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .mg-promo--green {
    background: var(--mg-tint-6);
  }

  :root:not([data-theme="light"]) .mg-ph span {
    color: rgba(233, 239, 226, 0.35);
  }

  :root:not([data-theme="light"]) .mg-cat__art img {
    mix-blend-mode: normal;
  }

  /* Kadence sets the overlay inline, hence the !important carried over from
     the toggle rule this mirrors. */
  :root:not([data-theme="light"]) #mobile-drawer .drawer-overlay,
  :root:not([data-theme="light"]) .popup-drawer .drawer-overlay {
    background: rgba(0, 0, 0, 0.65) !important;
  }
}

/* ==========================================================================
   36. STAGGERED GROUP REVEALS

   `data-stagger` has been setting `--mg-d` on every child since the motion
   layer was written, but nothing ever read it. The reveal transition lived on
   the *group*, and a custom property set on a child cannot delay its parent --
   so `--mg-d` resolved to 0ms everywhere and every grid arrived as one solid
   block. Measured on the homepage before this change: six category tiles and
   eight cards, all with correct 0/60/120ms values set, all with a computed
   `transition-delay` of 0s.

   The wave is the whole point -- it is what separates a considered reveal from
   a fade -- so the group now stands still and hands the motion to its children.
   ========================================================================== */

/* An explicit `from` is required here. `mg-rise` is a to-only keyframe, so its
   implicit start is the element's own computed style; once the group is
   visible that is already the end state and it would animate nothing. */
@keyframes mg-stagger-in {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@media (prefers-reduced-motion: no-preference) {
  /* The group keeps its observer but gives up its own travel: a parent sliding
     up while its children also slide reads as two competing motions. */
  .mg-js .mg-reveal[data-stagger] {
    opacity: 1;
    transform: none;
    transition: none;
  }

  /* Scoped to `.mg-reveal[data-stagger]`, never to `[data-stagger]` alone. A
     stagger group that is not also a reveal target is never observed, so it
     would never receive `.is-in` -- hiding its children would strand them at
     opacity 0 permanently. */
  .mg-js .mg-reveal[data-stagger] > * {
    opacity: 0;
  }

  /* `backwards` holds the from-state through the delay, so a child waiting its
     turn is not briefly visible first.

     Deliberately NOT `forwards`. A forwards fill keeps the animation's final
     `transform: none` in play for the life of the element, where it outranks
     any transform in the cascade -- the card's hover lift and the tile's
     image-breathe would both stop working. Without the fill the element simply
     reverts to its own rules once the animation ends. */
  .mg-js .mg-reveal[data-stagger].is-in > * {
    opacity: 1;
    animation: mg-stagger-in var(--mg-t-reveal) var(--mg-ease)
      var(--mg-d, 0ms) backwards;
  }
}

/* ==========================================================================
   37. REVEALS ON THE WOOCOMMERCE-OWNED PAGES

   The homepage template can carry `.mg-reveal` in its own markup; the single
   product page cannot, because WooCommerce prints those containers and offers
   no filter for their classes. Naming them here keeps one motion language
   across the site without forking `single-product.php` and inheriting its
   upgrade burden.

   The gallery is excluded on purpose. It is the LCP element on this page, and
   an element at opacity 0 is not painted -- revealing it would defer Largest
   Contentful Paint by the length of the animation. The same reasoning already
   protects the hero image.

   `.summary` is excluded too: it is above the fold and holds the price and the
   buy button, which should never wait on a scroll observer.
   ========================================================================== */

@media (prefers-reduced-motion: no-preference) {
  .mg-js .woocommerce-tabs,
  .mg-js .related.products,
  .mg-js .up-sells.products {
    opacity: 0;
    transform: translateY(20px);
    transition:
      opacity var(--mg-t-reveal) var(--mg-ease),
      transform var(--mg-t-reveal) var(--mg-ease);
  }

  .mg-js .woocommerce-tabs.is-in,
  .mg-js .related.products.is-in,
  .mg-js .up-sells.products.is-in {
    opacity: 1;
    transform: none;
  }
}

/* ==========================================================================
   38. THREE MOBILE DEFECTS
   ========================================================================== */

/* -- 38a. Hero art running out of its frame -------------------------------

   The hero images are cut-out product photography standing on a tint, not
   photographic scenes. `object-fit: cover` fills the frame and crops whatever
   will not fit, so a wide object like the sofa was pushed past the edge of the
   card -- worst on mobile, where the frame is 16/10 and the copy is stacked
   above it.

   `contain` fits the whole object inside the frame at any viewport and lets
   the tint behind it show, which is what the tint is for. It also generalises:
   any future hero image is fitted rather than cropped, whatever its shape. */

.mg-hero__media img,
.mg-hero__media .mg-ph {
  object-fit: contain;
}

@media (max-width: 820px) {
  /* Once the art is fitted rather than cropped it sits flush against the
     frame; a little inset keeps it off the card edge. */
  .mg-hero__media {
    padding: 0.4rem 0.9rem 0;
  }
}

/* -- 38b. Buttons centring their own wrapped text -------------------------

   `justify-content: center` centres the label as a flex *item*. It says
   nothing about the lines inside that item, which keep the inherited
   start-alignment -- so as soon as a long German label like "In den
   Warenkorb" broke over two lines, the second line sat visibly left. */

.mg .single_add_to_cart_button,
.mg .add_to_cart_button,
.mg .button.alt,
.mg .checkout-button,
.mg .woocommerce-Button,
.mg button.button,
.mg a.button,
.mg input.button,
.mg .mg-btn {
  text-align: center;
}

/* -- 38c. Add-to-cart squeezed by the quantity stepper --------------------

   `form.cart` already sets `flex-wrap: wrap`, but wrapping was never reached:
   a flex item shrinks before the line breaks, so the button was squeezed next
   to the stepper until its label broke over two lines and the button grew
   taller instead of moving to a row of its own.

   A 100% flex-basis forces the break, so the label stays on one line and the
   button keeps its 48px height -- and the full-width target is the better
   mobile affordance regardless. */

@media (max-width: 560px) {
  .mg form.cart .single_add_to_cart_button {
    flex: 1 0 100%;
  }
}

/* ==========================================================================
   39. CARD ADD-TO-CART AT TWO COLUMNS

   Section 38c fixed the button on the single product page. This is the other
   one: the button inside a product tile, which is a different element
   (`.mg-btn`, not `.single_add_to_cart_button`) and was untouched by it.

   At two columns on a 375px phone the tile leaves the button roughly 136px.
   The base `.mg-btn` spends 48px of that on horizontal padding alone, before
   the cart glyph and its gap, which left about 64px for the label -- so it
   wrapped onto a second line and doubled the button's height.

   The label is now the shorter "In den Korb" (see mangorivo_card()). Padding
   and gap tighten here to match, because the shorter label alone still did not
   fit inside the original padding.
   ========================================================================== */

@media (max-width: 560px) {
  .mg .mg-card__quick .mg-btn {
    padding-left: 0.6rem;
    padding-right: 0.6rem;
    gap: 0.35rem;
    font-size: 0.8rem;
  }

  /* The glyph is sized in em, so it already tracks the smaller label; this
     only stops it being the thing that forces the wrap on the narrowest
     phones, where the tile drops below 160px. */
  .mg .mg-card__quick .mg-add::before {
    width: 1em;
    height: 1em;
  }
}

/* ==========================================================================
   40. CATEGORY MEGA MENU

   One markup tree, two presentations. On the desktop the nested `<ul>` becomes
   an absolutely positioned multi-column panel; inside Kadence's mobile drawer
   it stays an ordinary nested list, which the drawer already knows how to
   collapse. Nothing here is duplicated per breakpoint.

   Sized for growth rather than for today's six: the columns are `auto-fill`, so
   twenty or forty categories reflow into more columns instead of overflowing,
   and the panel scrolls once it would be taller than the viewport.
   ========================================================================== */

.mg .header-navigation li.mg-catsnav {
  position: relative;
}

.mg .header-navigation li.mg-catsnav > a {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
}

.mg-catsnav__cv {
  width: 10px;
  height: 7px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform var(--mg-t-micro) var(--mg-ease);
}

.mg .header-navigation li.mg-catsnav:hover .mg-catsnav__cv,
.mg .header-navigation li.mg-catsnav:focus-within .mg-catsnav__cv {
  transform: rotate(180deg);
}

/* -- Desktop panel --------------------------------------------------------- */

@media (min-width: 1025px) {
  .mg .header-navigation li.mg-catsnav > ul.sub-menu.mg-mega {
    position: absolute;
    top: 100%;
    /* Anchored to the item's right edge, not centred on it. The nav sits on the
       right of the header, so a centred 900px panel hung ~80px past the
       viewport and clipped. Right-anchoring keeps it on screen at any width
       without needing to measure anything. */
    left: auto;
    right: 0;
    transform: translateY(6px);
    z-index: 300;

    /* Wide enough for three columns, but capped to the viewport so a long list
       never pushes a horizontal scrollbar onto the page. */
    width: max-content;
    min-width: 460px;
    max-width: min(92vw, 900px);
    max-height: min(70vh, 620px);
    overflow-y: auto;
    overscroll-behavior: contain;

    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
    gap: 0.15rem 1.4rem;
    margin: 0;
    padding: 1.1rem 1.3rem;
    list-style: none;

    background: var(--mg-surface);
    border: 1px solid var(--mg-border);
    border-radius: var(--mg-r-md);
    box-shadow: var(--mg-shadow-3);

    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition:
      opacity var(--mg-t-ui) var(--mg-ease),
      transform var(--mg-t-ui) var(--mg-ease),
      visibility 0s linear var(--mg-t-ui);
  }

  .mg .header-navigation li.mg-catsnav:hover > ul.sub-menu.mg-mega,
  .mg .header-navigation li.mg-catsnav:focus-within > ul.sub-menu.mg-mega {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transform: translateY(0);
    transition-delay: 0s;
  }

  /* The gap between the trigger and the panel is dead space; without a bridge
     the panel closes while the pointer crosses it. */
  .mg .header-navigation li.mg-catsnav::after {
    content: "";
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    height: 10px;
  }

  .mg-mega__col {
    break-inside: avoid;
    margin-bottom: 0.5rem;
  }
}

/* -- Shared item styling --------------------------------------------------- */

.mg .header-navigation .mg-mega a {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.6rem;
  padding: 0.4rem 0.5rem;
  border-radius: var(--mg-r-sm);
  color: var(--mg-text);
  text-decoration: none;
  line-height: 1.3;
}

.mg .header-navigation .mg-mega .mg-mega__parent {
  font-family: "Gabarito", "Poppins", system-ui, sans-serif;
  font-weight: 700;
  font-size: 0.98rem;
  color: var(--mg-head);
}

.mg .header-navigation .mg-mega a:hover,
.mg .header-navigation .mg-mega a:focus-visible {
  background: var(--mg-surface-2);
  color: var(--mg-head);
}

.mg .header-navigation .mg-mega .is-current > a,
.mg .header-navigation .mg-mega li.is-current > a {
  background: var(--mg-surface-2);
  color: var(--mg-head);
  font-weight: 700;
}

/* The count is reference information, not a label; it should never compete
   with the category name for attention. */
.mg-mega__n {
  flex: none;
  font-family: "Oswald", "Gabarito", system-ui, sans-serif;
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  color: var(--mg-text-2);
  font-variant-numeric: tabular-nums;
}

.mg .header-navigation .mg-mega ul.mg-mega__kids {
  margin: 0.1rem 0 0;
  padding: 0 0 0 0.5rem;
  list-style: none;
  border-left: 1px solid var(--mg-border);
}

.mg .header-navigation .mg-mega ul.mg-mega__kids a {
  padding: 0.3rem 0.5rem;
  font-size: 0.9rem;
  color: var(--mg-text-2);
}

.mg .header-navigation .mg-mega .mg-mega__all {
  grid-column: 1 / -1;
  margin-top: 0.3rem;
  padding-top: 0.6rem;
  border-top: 1px solid var(--mg-border);
}

.mg .header-navigation .mg-mega .mg-mega__all a {
  justify-content: flex-start;
  font-weight: 600;
  color: var(--mg-orange-dk);
}

/* -- Inside the mobile drawer ---------------------------------------------- */

@media (max-width: 1024px) {
  /* Kadence collapses `.sub-menu` itself, so the panel positioning above is
     scoped away entirely and this stays an ordinary indented list. */
  .mg .mg-mega {
    display: block;
    margin: 0;
    padding: 0 0 0 0.4rem;
    list-style: none;
    background: none;
    border: 0;
    box-shadow: none;
  }

  .mg .mg-mega a {
    min-height: 44px;
    align-items: center;
  }

  .mg .header-navigation .mg-mega ul.mg-mega__kids {
    padding-left: 0.75rem;
  }
}

/* ==========================================================================
   41. CATEGORY INDEX PAGE

   The addressable version of the mega menu, at /kategorien/. Auto-fill columns
   again, so the page absorbs forty categories by adding rows rather than by
   needing a new layout.
   ========================================================================== */

.mg-catindex {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 1rem;
}

.mg-catindex__group {
  display: flex;
  flex-direction: column;
  padding: 0.9rem;
  border: 1px solid var(--mg-border);
  border-radius: var(--mg-r-md);
  background: var(--mg-surface);
  box-shadow: var(--mg-shadow-1);
  transition:
    transform var(--mg-t-ui) var(--mg-ease),
    box-shadow var(--mg-t-ui) var(--mg-ease);
}

@media (hover: hover) and (pointer: fine) {
  .mg-catindex__group:hover {
    transform: translateY(-3px);
    box-shadow: var(--mg-shadow-2);
  }
}

.mg-catindex__head {
  display: grid;
  grid-template-columns: 56px 1fr;
  grid-template-rows: auto auto;
  align-items: center;
  column-gap: 0.75rem;
  text-decoration: none;
  color: inherit;
}

.mg-catindex__art {
  grid-row: 1 / 3;
  display: grid;
  place-items: center;
  width: 56px;
  height: 56px;
  overflow: hidden;
  border-radius: var(--mg-r-sm);
  background: var(--mg-surface-2);
}

.mg-catindex__art img,
.mg-catindex__art .mg-ph {
  width: 100%;
  height: 100%;
  /* Category art is cut-out product photography, same as the hero: contain
     fits it, cover would crop it. */
  object-fit: contain;
}

.mg-catindex__name {
  align-self: end;
  font-family: "Gabarito", "Poppins", system-ui, sans-serif;
  font-weight: 700;
  font-size: 1.05rem;
  color: var(--mg-head);
}

.mg-catindex__n {
  align-self: start;
  font-family: "Oswald", "Gabarito", system-ui, sans-serif;
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--mg-text-2);
}

.mg-catindex__kids {
  margin: 0.7rem 0 0;
  padding: 0.7rem 0 0;
  list-style: none;
  border-top: 1px solid var(--mg-border);
}

.mg-catindex__kids a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  /* 44px so a child category is a comfortable target on a phone, where this
     page does most of its work. */
  min-height: 44px;
  padding: 0 0.4rem;
  border-radius: var(--mg-r-sm);
  color: var(--mg-text-2);
  text-decoration: none;
  font-size: 0.92rem;
}

.mg-catindex__kids a:hover,
.mg-catindex__kids a:focus-visible {
  background: var(--mg-surface-2);
  color: var(--mg-head);
}

/* ==========================================================================
   42. SINGLE PRODUCT - EDITORIAL PURCHASE STAGE

   Kadence's default WooCommerce product layout leaves the gallery and the
   purchase information as two unrelated floating blocks. The product detail
   page is the shop's moment of persuasion, so give those blocks one composed
   stage: a calm image surface, a focused purchase panel, and an editorial
   description flow below. The rule stays token-driven so light and dark mode
   keep the same hierarchy.
   ========================================================================== */

body.mg.single-product .product-title.product-above {
  margin-bottom: 1.1rem;
}

body.mg.single-product div.product {
  display: grid;
  grid-template-columns: minmax(0, 1.08fr) minmax(19rem, 0.92fr);
  gap: clamp(1.5rem, 4vw, 4.5rem);
  align-items: start;
}

body.mg.single-product div.product > .onsale {
  z-index: 2;
  top: 1rem;
  left: 1rem;
  margin: 0;
}

body.mg.single-product div.product > .woocommerce-product-gallery,
body.mg.single-product div.product > .summary.entry-summary {
  float: none;
  width: auto;
  margin: 0;
}

body.mg.single-product div.product > .woocommerce-product-gallery {
  display: grid;
  min-height: clamp(270px, 34vw, 430px);
  padding: clamp(1rem, 3vw, 2.5rem);
  border: 1px solid var(--mg-border);
  border-radius: var(--mg-r-lg);
  background: var(--mg-surface-2);
  box-shadow: var(--mg-shadow-1);
  align-items: center;
}

body.mg.single-product .woocommerce-product-gallery__wrapper,
body.mg.single-product .woocommerce-product-gallery__wrapper > div,
body.mg.single-product .woocommerce-product-gallery__image,
body.mg.single-product .woocommerce-product-gallery__image a {
  width: 100%;
  height: 100%;
}

body.mg.single-product .woocommerce-product-gallery__wrapper {
  display: grid;
  place-items: center;
  margin: 0;
}

body.mg.single-product .woocommerce-product-gallery__image,
body.mg.single-product .woocommerce-product-gallery__image a {
  display: grid;
  place-items: center;
}

body.mg.single-product .woocommerce-product-gallery__image img {
  display: block;
  width: min(100%, 30rem);
  max-height: 26rem;
  object-fit: contain;
  border-radius: var(--mg-r-md);
  mix-blend-mode: multiply;
}

body.mg.single-product div.product > .summary.entry-summary {
  padding: clamp(1.35rem, 3vw, 2.5rem);
  border-radius: var(--mg-r-lg);
  background: var(--mg-surface-2);
}

body.mg.single-product .summary .product_title {
  max-width: 13ch;
  margin: 0 0 1rem;
  font-size: clamp(2rem, 4.6vw, 3.45rem);
  line-height: 1.02;
}

body.mg.single-product .summary p.price {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.25rem 0.65rem;
  margin: 0;
  color: var(--mg-text);
}

body.mg.single-product .summary p.price del {
  color: var(--mg-text-2);
  font-size: 1rem;
}

body.mg.single-product .summary p.price ins {
  color: var(--mg-head);
  font-size: clamp(1.45rem, 3vw, 1.9rem);
  font-weight: 800;
  text-decoration: none;
}

body.mg.single-product .summary p.price .woocommerce-price-suffix {
  flex-basis: 100%;
  margin-top: 0.1rem;
  color: var(--mg-text-2);
  font-size: 0.8rem;
}

body.mg.single-product .summary .legal-price-info {
  margin: 0.45rem 0 0;
}

body.mg.single-product .summary .woocommerce-product-details__short-description {
  max-width: 34ch;
  margin: 1.25rem 0 0;
  color: var(--mg-text);
  font-size: 1.05rem;
  line-height: 1.55;
}

body.mg.single-product .summary form.cart {
  margin: 1.35rem 0 0;
}

body.mg.single-product div.product.product-type-external .summary .single_add_to_cart_button {
  width: 100%;
  min-height: 54px;
}

/* An outbound retailer link is not a cart action; the directional glyph makes
   that destination clear without introducing another visual language. */
body.mg.single-product div.product.product-type-external .summary .single_add_to_cart_button::before {
  content: "↗";
  width: auto;
  height: auto;
  background: none;
  -webkit-mask: none;
  mask: none;
  font-size: 1.25em;
  line-height: 1;
}

body.mg.single-product .summary .product_meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 0.9rem;
  margin: 1.25rem 0 0;
  padding-top: 1rem;
  border-top: 1px solid var(--mg-border);
  color: var(--mg-text-2);
  font-size: 0.82rem;
}

body.mg.single-product .summary .product_meta > span {
  margin: 0;
}

body.mg.single-product div.product > .woocommerce-tabs,
body.mg.single-product div.product > .related.products,
body.mg.single-product div.product > .upsells.products {
  grid-column: 1 / -1;
}

body.mg.single-product div.product > .woocommerce-tabs {
  margin-top: clamp(1.5rem, 3vw, 3rem);
}

body.mg.single-product .woocommerce-tabs .woocommerce-Tabs-panel {
  max-width: 760px;
  margin: 0;
  color: var(--mg-text);
}

body.mg.single-product .woocommerce-tabs .woocommerce-Tabs-panel > h2 {
  margin-top: 0;
  font-size: clamp(1.5rem, 2.5vw, 2rem);
}

body.mg.single-product .woocommerce-tabs .woocommerce-Tabs-panel > p {
  max-width: 68ch;
  font-size: 1rem;
  line-height: 1.75;
}

@media (max-width: 899px) {
  body.mg.single-product div.product {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 1rem;
  }

  body.mg.single-product div.product > .woocommerce-product-gallery,
  body.mg.single-product div.product > .summary.entry-summary {
    grid-column: 1;
  }

  body.mg.single-product div.product > .woocommerce-product-gallery {
    min-height: clamp(240px, 50vw, 340px);
    padding: 0.85rem;
  }

  body.mg.single-product .woocommerce-product-gallery__image img {
    max-height: 18rem;
  }

  body.mg.single-product div.product > .summary.entry-summary {
    padding: 1.35rem;
  }

  body.mg.single-product .summary .product_title {
    max-width: none;
    font-size: clamp(1.9rem, 7vw, 2.65rem);
  }

  body.mg.single-product div.product > .woocommerce-tabs,
  body.mg.single-product div.product > .related.products,
  body.mg.single-product div.product > .upsells.products {
    grid-column: 1;
  }
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) body.mg.single-product .woocommerce-product-gallery__image img {
    mix-blend-mode: normal;
  }
}

:root[data-theme="dark"] body.mg.single-product .woocommerce-product-gallery__image img {
  mix-blend-mode: normal;
}

/* ==========================================================================
   43. HOMEPAGE - CURATED FIRST IMPRESSION

   The homepage already has the right ingredients: real product photography,
   the category rail, and a warm editorial palette. This pass removes the two
   elements that made the page feel most like a template: repeated kickers and
   a blank product tile that still behaved like a purchasable item.
   ========================================================================== */

.mg-main .mg-hero__eyebrow,
.mg-main .mg-promo__eyebrow {
  display: none;
}

.mg-main .mg-card--placeholder {
  border-color: transparent;
  background: var(--mg-tint-6);
}

.mg-main .mg-card--placeholder .mg-card__media {
  display: grid;
  place-items: end start;
  padding: 1rem;
  background: var(--mg-tint-6);
}

.mg-main .mg-card--placeholder .mg-card__media .mg-ph {
  display: flex;
  align-items: flex-end;
  justify-content: flex-start;
  padding: 0;
  background: transparent;
}

.mg-main .mg-card--placeholder .mg-ph span {
  padding: 0.35rem 0.6rem;
  border: 1px solid var(--mg-border);
  border-radius: var(--mg-r-sm);
  background: var(--mg-surface);
  color: var(--mg-head);
  font-family: "Gabarito", "Poppins", system-ui, sans-serif;
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: none;
}

.mg-main .mg-card--placeholder .mg-card__body {
  background: var(--mg-tint-6);
}

.mg-main .mg-card--placeholder .mg-card__price:empty {
  display: none;
}

@media (max-width: 820px) {
  .mg-main .mg-hero__title {
    max-width: 18ch;
  }
}

/* ==========================================================================
   44. GENERATED HERO SCENE AND CATEGORY OBJECTS

   The new art is cut-out, not photography: it has no background of its own and
   must never be cropped. Everything here is `contain` on a CSS stage, which is
   also what lets one set of category objects serve both themes -- the tint
   behind them changes, the objects do not.
   ========================================================================== */

.mg-hero__scene {
  display: block;
  width: 100%;
  height: 100%;
}

.mg-hero__scene img,
.mg .mg-hero__media .mg-hero__scene img {
  width: 100%;
  height: 100%;
  /* Overrides the photographic `cover` from section 38a. A cut-out that is
     cropped loses the objects at its edges, which is the whole composition. */
  object-fit: contain;
  object-position: center;
}

/* One composition, so the track no longer scrolls and the dots are gone. */
.mg-hero__track--single {
  display: block;
  width: 100%;
  overflow: visible;
}

.mg-hero__track--single .mg-hero__slide {
  width: 100%;
}

.mg-hero__track--single ~ .mg-hero__dots {
  display: none;
}

/* Category objects sit on the theme tint, so they need breathing room rather
   than filling the tile. */
.mg .mg-cat__art img {
  width: 76px;
  height: 76px;
  object-fit: contain;
  mix-blend-mode: normal;
}

@media (max-width: 700px) {
  .mg .mg-cat__art img {
    width: 60px;
    height: 60px;
  }
}

/* ==========================================================================
   45. PRODUCT CARD - REFERENCE ANATOMY

   The card in the reference is: image on a pale stage, badge pill top-left,
   outline heart top-right, title, stars + count, price, then a full-width
   orange button that is ALWAYS VISIBLE.

   The build had that button as a hover overlay sitting on the image. That was
   a reasonable pattern and it is not this design: on the reference every card
   shows its action at rest, which is also better on touch, where a hover
   overlay can never be revealed at all.

   This section supersedes the overlay behaviour in sections 12 and 38c.
   ========================================================================== */

.mg .mg-card {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid var(--mg-border);
  border-radius: 16px;
  background: var(--mg-surface);
  box-shadow: var(--mg-shadow-1);
}

/* -- Image stage ---------------------------------------------------------- */

/* Real product photography arrives with every kind of background and crop.
   A fixed square stage with `contain` is the only version that still looks
   composed once the demo images are replaced. */
.mg .mg-card__media {
  position: relative;
  aspect-ratio: 1;
  padding: 0.9rem;
  background: var(--mg-cream);
  border-bottom: 1px solid var(--mg-border);
}

.mg .mg-card__media img,
.mg .mg-card__media .mg-ph {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* -- Always-visible action ------------------------------------------------ */

.mg .mg-card__quick,
.mg .mg-card:hover .mg-card__quick,
.mg .mg-card:focus-within .mg-card__quick {
  position: static;
  display: block;
  aspect-ratio: auto;
  padding: 0 0.85rem 0.85rem;
  opacity: 1;
  transform: none;
  pointer-events: auto;
  z-index: auto;
}

.mg .mg-card__quick .mg-btn {
  width: 100%;
  min-height: 42px;
}

/* The body grows so every button in a row sits on the same line, regardless of
   how many lines the German product title takes. */
.mg .mg-card__body {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  padding: 0.85rem 0.85rem 0.6rem;
}

.mg .mg-card__price {
  margin-top: auto;
}

/* -- Hover ---------------------------------------------------------------- */

@media (hover: hover) and (pointer: fine) {
  .mg .mg-card {
    transition:
      transform var(--mg-t-ui) var(--mg-ease),
      box-shadow var(--mg-t-ui) var(--mg-ease);
  }

  .mg .mg-card:hover {
    transform: translateY(-3px);
    box-shadow: var(--mg-shadow-2);
  }
}

/* Compact cards keep no action at all; that rule still stands. */
.mg .mg-card--compact .mg-card__quick {
  display: none;
}

/* ==========================================================================
   46. HEADER SEARCH FIELD

   The reference carries a visible search field in the header rather than an
   icon that opens one. Both exist in the markup: the field at wide widths, the
   icon-triggered overlay below 1100px where there is no room for it. CSS
   chooses, so neither depends on JavaScript to be present.
   ========================================================================== */

.mg-hsearch {
  display: none;
}

@media (min-width: 1100px) {
  .mg .header-navigation li.menu-item.mg-actions .mg-hsearch {
    position: relative;
    display: flex;
    align-items: center;
    width: clamp(190px, 18vw, 280px);
    margin-right: 0.35rem;
  }

  /* The icon field and the icon button are two routes to one feature; showing
     both reads as a duplicate control. */
  .mg .header-navigation li.menu-item.mg-actions .mg-iconbtn--search {
    display: none;
  }

  .mg-hsearch__i {
    position: absolute;
    left: 0.7rem;
    width: 16px;
    height: 16px;
    fill: none;
    stroke: var(--mg-text-2);
    stroke-width: 1.9;
    stroke-linecap: round;
    pointer-events: none;
  }

  .mg .header-navigation li.menu-item.mg-actions .mg-hsearch input[type="search"] {
    width: 100%;
    /* 40px matches the icon buttons beside it, so the header keeps one
       horizontal rhythm instead of two. */
    height: 40px;
    margin: 0;
    padding: 0 0.85rem 0 2.1rem;
    border: 1px solid var(--mg-border);
    border-radius: var(--mg-r-pill);
    background: var(--mg-surface);
    color: var(--mg-text);
    font: inherit;
    font-size: 0.88rem;
    line-height: 1;
    transition:
      border-color var(--mg-t-micro) var(--mg-ease-soft),
      box-shadow var(--mg-t-micro) var(--mg-ease-soft);
  }

  .mg .header-navigation li.menu-item.mg-actions .mg-hsearch input[type="search"]::placeholder {
    color: var(--mg-text-2);
  }

  .mg .header-navigation li.menu-item.mg-actions .mg-hsearch input[type="search"]:focus {
    outline: none;
    border-color: var(--mg-orange);
    box-shadow: 0 0 0 3px rgba(255, 130, 21, 0.22);
  }

  /* The nav underline from section 14 would otherwise draw under the field. */
  .mg .header-navigation li.menu-item.mg-actions .mg-hsearch::after {
    content: none;
  }
}

/* ==========================================================================
   47. COLLECTION TILES
   Six wide tiles under the trust row. Auto-fit, so the row absorbs however
   many collections are populated without a layout change -- two of the six are
   empty until someone curates them.
   ========================================================================== */

.mg-colls {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 0.8rem;
}

.mg-coll {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  padding: 0.7rem;
  border: 1px solid var(--mg-border);
  border-radius: 14px;
  background: var(--mg-surface);
  text-decoration: none;
  color: inherit;
  transition:
    transform var(--mg-t-ui) var(--mg-ease),
    box-shadow var(--mg-t-ui) var(--mg-ease);
}

@media (hover: hover) and (pointer: fine) {
  .mg-coll:hover {
    transform: translateY(-3px);
    box-shadow: var(--mg-shadow-2);
  }
}

.mg-coll__art {
  display: block;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border-radius: 10px;
  background: var(--mg-cream);
}

.mg-coll__art img,
.mg-coll__art .mg-ph {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.mg-coll__label {
  font-family: "Gabarito", "Poppins", system-ui, sans-serif;
  font-weight: 700;
  font-size: 0.92rem;
  line-height: 1.25;
  color: var(--mg-head);
}

@media (max-width: 700px) {
  /* Snap rail on narrow screens, matching the category row's behaviour. */
  .mg-colls {
    display: flex;
    gap: 0.6rem;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }

  .mg-colls::-webkit-scrollbar {
    display: none;
  }

  .mg-coll {
    flex: 0 0 46%;
    scroll-snap-align: start;
  }
}
