/* ================================================================
   Me2You - production site styles
   Brand tokens mirror /shared/tokens.css (same orange/cream palette
   used across wireframes), but this file is the live CSS for PHP
   pages. Bootstrap 5 underneath; this layers brand, components.
   ================================================================ */

/* ----------------------------------------------------------------
   1. DESIGN TOKENS (custom properties)
   Complete brand vocabulary: colours, spacing, radii, shadows,
   transitions, typography scale, z-index layers.
   ---------------------------------------------------------------- */
:root {
  /* -- Brand palette -- */
  --brand-orange:     #F89A1F;
  --brand-orange-600: #E8851A;
  --brand-orange-700: #C76B0F;
  /* -800 is the WCAG-AA-safe shade for body-copy links + inline accents on
     white/cream: #9A5309 is ~5.0:1, clears the 4.5:1 normal-text threshold
     that #F89A1F (2.1:1) and #C76B0F (3.8:1) both fail. */
  --brand-orange-800: #9A5309;
  --brand-orange-100: #FFE7C8;
  --brand-orange-50:  #FFF6E9;
  --brand-plum:       #8E7CA0;
  --brand-plum-700:   #5C4A6E;
  --brand-plum-100:   #ECE6F2;

  /* -- Ink (neutral) scale -- */
  --ink-900:          #1F1A17;
  --ink-700:          #3D342E;
  --ink-500:          #6B5E55;
  --ink-400:          #948578;
  --ink-300:          #C9BEB3;
  --ink-200:          #E7DFD5;
  --ink-100:          #F4EEE5;
  --ink-50:           #FAF6EF;
  --paper:            #FFF;

  /* -- Semantic colours -- */
  --success:          #2F9E5A;
  --success-100:      #DDF1E4;
  --warning:          #E8A400;
  --warning-100:      #FFF1CD;
  --danger:           #D44A3A;
  --danger-100:       #FCE2DD;
  --info:             #2D7AC7;
  --info-100:         #DCEAF8;

  /* -- Order status palette -- */
  --status-placed-bg:        var(--warning-100);
  --status-placed-fg:        #8A5E00;
  --status-paid-bg:          var(--success-100);
  --status-paid-fg:          #1E6E3E;
  --status-dispatched-bg:    var(--info-100);
  --status-dispatched-fg:    #1B4F86;
  --status-received-bg:      var(--brand-orange-100);
  --status-received-fg:      var(--brand-orange-700);
  --status-completed-bg:     #E2EFE7;
  --status-completed-fg:     #1E6E3E;
  --status-cancelled-bg:     #EDE7E3;
  --status-cancelled-fg:     #5B4A40;
  --status-disputed-bg:      var(--danger-100);
  --status-disputed-fg:      #8C2A1F;

  /* -- Roles -- */
  --role-buyer:          #2F9E5A;
  --role-seller:         #F89A1F;
  --role-admin:          #8E7CA0;

  /* -- Category palette (WCAG-AA on white + cream, dot / accent use only) -- */
  --cat-electronics:     #1F6FB2;
  --cat-fashion:         #B53371;
  --cat-home:            #2A7D4F;
  --cat-vehicles:        #C0392B;
  --cat-baby:            #2A7197;
  --cat-books:           #3F51B5;
  --cat-services:        #5A6B7B;
  --cat-other:           #7A6A5C;
  --cat-plants:          #0C7C55;
  --cat-food:            #9C6109;
  --cat-art:             #7B3FB8;
  --cat-crafts:          #0C7878;
  --cat-property:        #7A3FA0;

  /* -- Border radii -- */
  --radius-xs:        6px;
  --radius-sm:        10px;
  --radius-md:        14px;
  --radius-lg:        20px;
  --radius-xl:        28px;
  --radius-pill:      999px;

  /* -- Borders -- */
  --border-thin:      1px solid var(--ink-200);
  --border-strong:    1.5px solid var(--ink-300);
  --border-brand:     1.5px solid var(--brand-orange);

  /* -- Shadows (warm, not cold grey) -- */
  --shadow-xs:        0 1px 2px rgb(46,33,22,0.06);
  --shadow-sm:        0 2px 6px rgb(46,33,22,0.08);
  --shadow-md:        0 6px 18px rgb(46,33,22,0.10);
  --shadow-lg:        0 16px 36px rgb(46,33,22,0.14);
  --shadow-xl:        0 12px 40px rgb(46,33,22,0.16);
  --shadow-pop:       0 12px 28px rgb(248,154,31,0.28);
  --shadow-orange:    0 4px 14px rgb(248,154,31,0.28);

  /* -- Spacing scale (4pt grid) -- */
  --space-1:          4px;
  --space-2:          8px;
  --space-3:          12px;
  --space-4:          16px;
  --space-5:          24px;
  --space-6:          32px;
  --space-7:          48px;
  --space-8:          64px;
  --space-9:          96px;

  /* -- Transitions -- */
  --ease-out:         cubic-bezier(0.22, 0.61, 0.36, 1);
  --ease-spring:      cubic-bezier(0.34, 1.56, 0.64, 1);
  --duration-fast:    0.12s;
  --duration-normal:  0.2s;
  --duration-slow:    0.3s;

  /* -- Typography -- */
  --font-display:     'Quicksand', 'Nunito', sans-serif;
  --font-body:        'Nunito', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-mono:        'JetBrains Mono', ui-monospace, monospace;

  /* -- Type scale -- */
  --fs-display:       clamp(40px, 6vw, 64px);
  --fs-h1:            clamp(32px, 4.5vw, 44px);
  --fs-h2:            28px;
  --fs-h3:            22px;
  --fs-h4:            18px;
  --fs-body:          16px;
  --fs-sm:            14px;
  --fs-xs:            12px;
  --fs-price:         22px;
  --fs-price-lg:      32px;

  /* -- Layout -- */
  --content-max:      1200px;
  --content-narrow:   720px;
  --header-h:         72px;
  --bottom-nav-h:     64px;

  /* -- Z-index layers -- */
  --z-dropdown:       1050;
  --z-sticky:         1000;
  --z-bnav:           999;
  --z-modal:          1100;
  --z-toast:          1200;
  --z-tooltip:        1300;
}


/* ----------------------------------------------------------------
   1b. DARK MODE (custom property overrides)
   Applied via data-theme="dark" on <html>. All existing styles
   automatically adapt because they reference the custom properties.
   Brand orange stays the same in both modes.
   ---------------------------------------------------------------- */
[data-theme="dark"] {
  /* -- Ink scale (inverted) -- */
  --ink-900:          #f0ebe4;
  --ink-700:          #d6cfbf;
  --ink-500:          #a69d90;
  --ink-400:          #8a8279;
  --ink-300:          #4a4540;
  --ink-200:          #3a3a3a;
  --ink-100:          #2e2e2e;
  --ink-50:           #1a1a1a;
  --paper:            #2a2a2a;

  /* -- Brand plum (slightly lighter for contrast) -- */
  --brand-plum:       #a896b8;
  --brand-plum-700:   #8672a0;
  --brand-plum-100:   #3a3248;

  /* -- Semantic colours (darkened backgrounds) -- */
  --success-100:      #1a3328;
  --warning-100:      #3a2e10;
  --danger-100:       #3a1a18;
  --info-100:         #1a2a40;

  /* -- Order status palette (dark-friendly) -- */
  --status-placed-bg:        var(--warning-100);
  --status-placed-fg:        #e8b84d;
  --status-paid-bg:          var(--success-100);
  --status-paid-fg:          #5ec87e;
  --status-dispatched-bg:    var(--info-100);
  --status-dispatched-fg:    #6aabe0;
  --status-received-bg:      #3a2810;
  --status-received-fg:      #f0a840;
  --status-completed-bg:     #1a3328;
  --status-completed-fg:     #5ec87e;
  --status-cancelled-bg:     #2e2a28;
  --status-cancelled-fg:     #a69d90;
  --status-disputed-bg:      var(--danger-100);
  --status-disputed-fg:      #e07060;

  /* -- Shadows (darker, more subtle) -- */
  --shadow-xs:        0 1px 2px rgb(0,0,0,0.2);
  --shadow-sm:        0 2px 6px rgb(0,0,0,0.25);
  --shadow-md:        0 6px 18px rgb(0,0,0,0.3);
  --shadow-lg:        0 16px 36px rgb(0,0,0,0.35);
  --shadow-xl:        0 12px 40px rgb(0,0,0,0.4);
  --shadow-pop:       0 12px 28px rgb(248,154,31,0.2);
  --shadow-orange:    0 4px 14px rgb(248,154,31,0.22);

  color-scheme: dark;
}


/* Listing cards */
[data-theme="dark"] .listing-card {
  background: var(--paper);
  border-color: var(--ink-200);
}

/* Buttons keep brand orange, but text contrast adjusts */
/* White text on the orange primary button in dark mode (the brand orange stays
   bright in dark mode, so white is the high-contrast choice). The !important
   beats the orange hero link colour, which a button rendered as an <a> would
   otherwise inherit and become orange-on-orange (invisible). */
/* On a dark page the bright orange fill glows (halation), so white label text
   reads as nearly invisible until hover darkens the fill. Dark ink on the
   bright orange clears WCAG AA comfortably (about 8:1) and stays crisp. */
[data-theme="dark"] .btn-brand,
[data-theme="dark"] a.btn-brand,
[data-theme="dark"] .btn-brand:hover,
[data-theme="dark"] a.btn-brand:hover,
[data-theme="dark"] .btn-brand:active {
  color: #1a1a1a !important;
}
[data-theme="dark"] .btn-brand svg {
  stroke: #1a1a1a;
}

/* Form controls */
[data-theme="dark"] .form-control,
[data-theme="dark"] .form-select {
  background: var(--ink-100);
  border-color: var(--ink-300);
  color: var(--ink-900);
}
[data-theme="dark"] .form-control:focus,
[data-theme="dark"] .form-select:focus {
  background: var(--paper);
}
[data-theme="dark"] .form-control::placeholder {
  color: var(--ink-400);
}

/* Hero section */
[data-theme="dark"] .m2y-hero {
  background: linear-gradient(160deg, #1a1a1a 0%, #2a2018 40%, #3a2810 100%);
  /* Match the gradient foot so the stats bar fades into the same dark tone. */
  --hero-base: #3a2810;
}

/* Trust strip cards */
[data-theme="dark"] .m2y-trust-strip {
  background: var(--ink-50);
}
[data-theme="dark"] .m2y-trust__card {
  background: var(--paper);
  border-color: var(--ink-200);
}
[data-theme="dark"] .m2y-trust__icon {
  background: #3a2810;
}

/* Category chips */
[data-theme="dark"] .cat-chip {
  background: var(--paper);
  border-color: var(--ink-300);
  color: var(--ink-900);
}

/* Search suggest dropdown */
[data-theme="dark"] .search-suggest {
  background: var(--paper);
  border-color: var(--ink-300);
}
[data-theme="dark"] .search-suggest__item:hover,
[data-theme="dark"] .search-suggest__item.active {
  background: var(--ink-100);
}

/* Toast notifications */
[data-theme="dark"] .m2y-toast {
  background: var(--paper);
  border-color: var(--ink-300);
  color: var(--ink-900);
}

/* Table zebra striping */
[data-theme="dark"] .m2y-table thead th {
  background: var(--ink-100);
}
[data-theme="dark"] .m2y-table tbody tr:nth-child(even) {
  background: var(--ink-100);
}
[data-theme="dark"] .m2y-table tbody tr:hover {
  background: #3a2810;
}

/* Bootstrap table overrides.
   Bootstrap's .table defaults its surface to white and its text to a dark
   ink via --bs-table-bg / --bs-table-color, so untouched data tables (buyer
   orders, seller fees, POPIA / cookies / agreement tables) rendered WHITE on
   a dark page. Re-point the table CSS vars at our dark tokens: an elevated
   --paper surface, --ink-900 body text and an --ink-200 hairline. Bootstrap
   composes its zebra / hover accents on top of --bs-table-bg, so the striped
   and hover variants below stay dark-on-dark legible. */
[data-theme="dark"] .table {
  --bs-table-bg: var(--paper);
  --bs-table-color: var(--ink-900);
  --bs-table-border-color: var(--ink-200);
  --bs-table-striped-color: var(--ink-900);
  --bs-table-hover-color: var(--ink-900);
  --bs-table-active-color: var(--ink-900);
  color: var(--ink-900);
  border-color: var(--ink-200);
}
/* The .table-light header variant hard-sets its own near-white --bs-table-bg
   and dark text inline, so a thead.table-light still glowed white. Re-skin it
   to a slightly raised panel with muted heading ink (matches .m2y-table). */
[data-theme="dark"] .table-light,
[data-theme="dark"] .table-light > th,
[data-theme="dark"] .table-light > td,
[data-theme="dark"] .table > thead.table-light th {
  --bs-table-bg: var(--ink-100);
  --bs-table-color: var(--ink-700);
  --bs-table-border-color: var(--ink-300);
  background-color: var(--ink-100);
  color: var(--ink-700);
}
/* Zebra and hover accents: keep them a touch lighter than --paper so rows
   stay distinct without becoming a glaring panel. */
[data-theme="dark"] .table-striped > tbody > tr:nth-of-type(even) > * {
  --bs-table-accent-bg: var(--ink-100);
}
[data-theme="dark"] .table-hover > tbody > tr:hover > * {
  --bs-table-accent-bg: #3a2810;
}

/* Alert brand */
[data-theme="dark"] .alert-brand {
  background: #3a2810;
  border-color: var(--brand-orange);
}

/* Escrow banner */
[data-theme="dark"] .escrow-banner {
  background: var(--success-100);
}
[data-theme="dark"] .escrow-banner.is-frozen {
  background: var(--danger-100);
}

/* Skeleton loading */
[data-theme="dark"] .skeleton {
  background: linear-gradient(90deg, #2e2e2e 25%, #3a3a3a 50%, #2e2e2e 75%);
  background-size: 200% 100%;
}

/* Mobile bottom nav */
[data-theme="dark"] .m2y-bnav {
  background: #1a1a1a;
  border-top-color: var(--ink-300);
}


/* Loading overlay */
[data-theme="dark"] .m2y-loading-overlay {
  background: rgb(26,26,26,0.7);
}

/* Selection colour */
[data-theme="dark"] ::selection {
  background: #5a3810;
  color: #f0ebe4;
}

/* Scrollbar */
[data-theme="dark"] ::-webkit-scrollbar-thumb {
  background: var(--ink-300);
}
[data-theme="dark"] ::-webkit-scrollbar-thumb:hover {
  background: var(--ink-400);
}

/* Tour tooltip */
[data-theme="dark"] .m2y-tour-tip {
  background: #2a2a2a;
  box-shadow: 0 8px 32px rgb(0,0,0,0.5);
}
[data-theme="dark"] .m2y-tour-tip__arrow {
  background: #2a2a2a;
}

/* Hero stats bar */
[data-theme="dark"] .m2y-hero__stats {
  /* Same dissolve as light: the base rule's gradient already fades into
     --hero-base (#3a2810, the dark hero gradient foot), so the bar melts
     into the frame. Drop the hairline that would mark a hard divide. */
  box-shadow: none;
  border-top: 0;
}

/* Pill defaults */
[data-theme="dark"] .pill,
[data-theme="dark"] .tag {
  background: var(--ink-100);
  color: var(--ink-900);
}

/* Empty state icon */
[data-theme="dark"] .m2y-empty__icon {
  background: var(--ink-100);
  color: var(--ink-400);
}

/* Cookie consent banner */
[data-theme="dark"] #m2yCookieConsent > div {
  background: var(--paper) !important;
  color: var(--ink-900) !important;
}

/* -- Theme toggle button -------------------------------- */
.m2y-theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  padding: 0;
  border: 1px solid var(--ink-300);
  border-radius: 50%;
  background: transparent;
  color: var(--ink-700);
  cursor: pointer;
  transition: color 0.15s ease,
              border-color 0.15s ease,
              background 0.15s ease;
  flex-shrink: 0;
}
.m2y-theme-toggle:hover {
  color: var(--brand-orange);
  border-color: var(--brand-orange);
  background: var(--brand-orange-50);
}
.m2y-theme-toggle:focus-visible {
  outline: 2px solid var(--brand-orange);
  outline-offset: 2px;
}
.m2y-theme-toggle svg {
  width: 18px;
  height: 18px;
  pointer-events: none;
}
/* Light mode: show moon icon */
.m2y-theme-toggle__moon { display: block; }
.m2y-theme-toggle__sun  { display: none; }
/* Dark mode: show sun icon */
[data-theme="dark"] .m2y-theme-toggle__moon { display: none; }
[data-theme="dark"] .m2y-theme-toggle__sun  { display: block; }

[data-theme="dark"] .m2y-theme-toggle {
  border-color: var(--ink-300);
  color: var(--ink-900);
}
[data-theme="dark"] .m2y-theme-toggle:hover {
  color: var(--brand-orange);
  border-color: var(--brand-orange);
  background: #3a2810;
}


/* ----------------------------------------------------------------
   2. ACCESSIBILITY
   ---------------------------------------------------------------- */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.skip-to-content {
  position: absolute;
  top: -100%;
  left: var(--space-4);
  z-index: 9999;
  padding: var(--space-3) var(--space-6);
  background: var(--brand-orange);
  color: #fff;
  font-weight: 700;
  font-family: var(--font-body);
  border-radius: var(--radius-sm);
  text-decoration: none;
  transition: top var(--duration-normal) var(--ease-out);
}
.skip-to-content:focus {
  top: var(--space-4);
  outline: 2px solid var(--brand-orange-700);
  outline-offset: 2px;
}

:focus-visible {
  outline: 2px solid var(--brand-orange);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  /* No positional lift on hover when motion is reduced: keep the colour and
     shadow feedback, drop the translate so nothing jumps. */
  .btn-brand:hover,
  .listing-card:hover { transform: none; }
}


/* ----------------------------------------------------------------
   3. BASE / RESET
   ---------------------------------------------------------------- */
html {
  scroll-behavior: smooth;
}

body {
  font-family: var(--font-body);
  background: var(--ink-50);
  color: var(--ink-900);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* Phone safety net: a stray wide child (an unconstrained image, a long
     unbroken string) must never make the whole page scroll sideways. The
     intentional horizontal rails (cat-chip rail, feed) set their own
     overflow on their own element, so this does not clip them. */
  overflow-x: hidden;
}

/* No image may exceed its column and force a horizontal scroll on the
   phone. Block-level images that already declare width/height keep their
   intrinsic ratio via height:auto only where the height is not pinned by
   a class (the card photo pins object-fit, so it is excluded). */
img { max-width: 100%; }

/* Muted body copy. Bootstrap's default .text-muted uses a translucent
   secondary colour whose alpha compounds on the cream and dark-card
   backgrounds and drops below the 4.5:1 normal-text ratio. We pin it to
   the solid --ink-500 token, which clears 4.5:1 on cream (#FAF6EF, about
   5.9:1) and white in light mode, and on the dark canvas (#1a1a1a) and
   dark cards (#2a2a2a, about 4.9:1) in dark mode. No alpha, so no
   background-dependent failures. */
.text-muted {
  color: var(--ink-500) !important;
}

/* Page-load fade. Applied ONLY by site.js (it adds .m2y-loading then swaps to
   .m2y-ready in the same tick), so the page is always visible by default for
   no-JS users, slow connections, and first paint. We deliberately do NOT put a
   blanket opacity-0 animation on body, because that hides content before paint
   (hurts FCP/LCP and breaks the page when JS is slow or disabled). */
body.m2y-loading { opacity: 0; }
body.m2y-ready   { opacity: 1; transition: opacity 0.3s ease; }

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: -0.01em;
}
/* Body links use the AA-safe -800 shade (5:1 contrast on white/cream). */
a { color: var(--brand-orange-800); text-decoration: none; }
a:hover { text-decoration: underline; }

/* Inline prose links must be distinguishable without relying on colour
   alone (WCAG link-in-text-block). We underline links that sit inside
   running text on the content pages, scoped to paragraphs, list items,
   plain breadcrumb navs and the product text blocks so buttons, nav,
   cards and other component links keep their own styling. The :not()
   guards skip anything styled as a button or a component link that opts
   out of underlines. */
.safety p a:not(.btn):not([class*="-link"]),
.safety li a:not(.btn):not([class*="-link"]),
.legal p a:not(.btn):not([class*="-link"]),
.legal li a:not(.btn):not([class*="-link"]),
.pdp-desc-section p a:not(.btn):not([class*="-link"]),
.pdp-escrow .sub a:not(.btn):not([class*="-link"]),
.pdp-seller-rating a:not(.btn):not([class*="-link"]),
.pdp-social-signin a:not(.btn):not([class*="-link"]),
nav[aria-label="breadcrumb"] a:not(.btn) {
  text-decoration: underline;
}

::selection {
  background: var(--brand-orange-100);
  color: var(--ink-900);
}




/* ----------------------------------------------------------------
   5. BUTTONS (brand)
   ---------------------------------------------------------------- */
.btn-brand {
  background: var(--brand-orange);
  color: #fff;
  font-weight: 700;
  border: none;
  border-radius: var(--radius-md);
  padding: 10px 24px;
  cursor: pointer;
  /* Resting orange glow, mirrored from the hi-fi prototype primary button
     (btnPrimary uses --shadow-pop at rest). This soft halo is what makes
     the single primary action read as the clear, lifted next step. */
  box-shadow: var(--shadow-pop);
  transition: background var(--duration-fast) ease,
              box-shadow var(--duration-fast) ease,
              transform var(--duration-fast) ease;
}
.btn-brand:hover {
  background: var(--brand-orange-600);
  color: #fff;
  box-shadow: var(--shadow-pop);
  transform: translateY(-1px);
}
.btn-brand:focus-visible {
  outline: 2px solid var(--brand-orange);
  outline-offset: 2px;
  box-shadow: 0 0 0 3px rgb(248,154,31,0.3);
}
.btn-brand:active {
  background: var(--brand-orange-700);
  color: #fff;
  transform: translateY(1px);
  box-shadow: none;
}
.btn-brand:disabled, .btn-brand.disabled {
  background: var(--ink-300);
  border: none;
  color: var(--ink-500);
  cursor: not-allowed;
  box-shadow: none;
  transform: none;
  opacity: 0.5;
}

.btn-outline-brand {
  background: transparent;
  color: var(--brand-orange-700);
  border: 1px solid var(--brand-orange);
  border-radius: var(--radius-sm);
  font-weight: 700;
  padding: 10px 24px;
  cursor: pointer;
  transition: background var(--duration-fast) ease,
              color var(--duration-fast) ease,
              box-shadow var(--duration-fast) ease,
              transform var(--duration-fast) ease;
}
.btn-outline-brand:hover {
  background: var(--brand-orange-100);
  color: var(--brand-orange-700);
  box-shadow: var(--shadow-sm);
}
.btn-outline-brand:focus-visible {
  outline: 2px solid var(--brand-orange);
  outline-offset: 2px;
  box-shadow: 0 0 0 3px rgb(248,154,31,0.3);
}
.btn-outline-brand:active { transform: translateY(1px); }
.btn-outline-brand:disabled, .btn-outline-brand.disabled {
  opacity: 0.5;
  cursor: not-allowed;
  transform: none;
}

.btn:focus-visible {
  outline: 2px solid var(--brand-orange);
  outline-offset: 2px;
}
.btn:disabled, .btn.disabled {
  opacity: 0.5;
  cursor: not-allowed;
}


/* ----------------------------------------------------------------
   6. CARDS / LISTINGS
   ---------------------------------------------------------------- */
.listing-card {
  background: var(--paper);
  border-radius: var(--radius-lg);
  border: 1px solid var(--ink-200);
  /* Calm resting shadow so a card reads as a quiet object on the cream
     canvas, not a flat outline. Lifts gently on hover. */
  box-shadow: var(--shadow-sm);
  /* Inset frame, mirrored from the hi-fi prototype ProductCard (padding:10
     around a rounded image). The white border around the photo is the main
     reason the prototype cards read as finished objects, not bare tiles. */
  padding: var(--space-2);
  transition: transform var(--duration-normal) var(--ease-out),
              box-shadow var(--duration-normal) var(--ease-out),
              border-color var(--duration-normal) var(--ease-out);
  height: 100%;
  display: flex;
  flex-direction: column;
}
.listing-card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-md);
  border-color: var(--ink-300);
}
.listing-card a { text-decoration: none; color: inherit; }
.listing-card a:hover { text-decoration: none; }
.listing-card .img,
.listing-card__img {
  aspect-ratio: 1/1;
  background-color: var(--ink-100);
  background-size: cover;
  background-position: center;
  position: relative;
  overflow: hidden;
  /* Rounded photo inside the white frame (prototype image radius is 14px). */
  border-radius: var(--radius-md);
  /* --img is the per-listing thumbnail url passed via data-style-vars. */
  background-image: var(--img, none);
}
/* Dimmed thumbnail variant (used for sold-out wishlist entries). */
.listing-card .img--dim,
.listing-card__img--dim { opacity: 0.5; }
.listing-card .img img,
.listing-card__img img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform var(--duration-normal) var(--ease-out);
}
.listing-card:hover .img img,
.listing-card:hover .listing-card__img img {
  transform: scale(1.03);
}
/* The real-photo path. Behaves exactly like the old bare <img>; the class
   only lets the placeholder below sit alongside it without a selector clash. */
.listing-card__photo {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform var(--duration-normal) var(--ease-out);
}
.listing-card:hover .listing-card__photo { transform: scale(1.03); }

/* Designed placeholder for listings with no seller photo. A soft
   category-tinted panel carrying the category glyph and the item title,
   so each empty card reads as distinct and intentional rather than the
   same flat grey image. --cat-colour arrives via data-style-vars (one
   colour per top-level category); we tint the fill from it with
   colour-mix and keep a solid fallback for older WebView. No gradient on
   an interactive surface, no extra image request: light for 3G. */
.listing-ph {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 16px;
  text-align: center;
  /* Fallback solid tint for WebView without colour-mix. */
  background: var(--ink-100);
  background: color-mix(in srgb, var(--cat-colour, var(--ink-300)) 12%, var(--paper));
  color: var(--cat-colour, var(--ink-500));
}
.listing-ph__glyph {
  width: 44px;
  height: 44px;
  opacity: 0.9;
  flex-shrink: 0;
}
.listing-ph__title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 13px;
  line-height: 1.3;
  color: var(--ink-700);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  max-width: 90%;
}
.card-condition-badge {
  position: absolute;
  top: var(--space-2);
  left: var(--space-2);
  font-size: 11px;
  font-weight: 700;
  padding: 2px var(--space-2);
  border-radius: var(--radius-xs);
  white-space: nowrap;
  /* Default fallback when no condition modifier is present. Each modifier
     pins a fixed colour pair so contrast stays >= 4.5:1 in dark mode. */
  background: var(--ink-100);
  color: var(--ink-700);
}
.card-condition-badge--new      { background: #DDF1E4; color: #1E6E3E; }
.card-condition-badge--like-new { background: #DCEAF8; color: #1B4F86; }
.card-condition-badge--good     { background: #FFF1CD; color: #8A5E00; }
.card-condition-badge--fair     { background: #EDE7E3; color: #5B4A40; }

/* Same colour pairs reused on the product detail page condition pill
   (.pdp-condition) so the badge stays consistent across listing and PDP. */
.pdp-condition--new      { background: #DDF1E4; color: #1E6E3E; }
.pdp-condition--like-new { background: #DCEAF8; color: #1B4F86; }
.pdp-condition--good     { background: #FFF1CD; color: #8A5E00; }
.pdp-condition--fair     { background: #EDE7E3; color: #5B4A40; }
.listing-card .body,
.listing-card__body {
  /* The white frame already supplies the side gutter, so the body hugs the
     frame edge (prototype body padding is 12px 4px 4px). */
  padding: var(--space-3) var(--space-1) var(--space-1);
  flex: 1;
  display: flex;
  flex-direction: column;
}
.listing-card .title,
.listing-card__title {
  /* Display face for the card title, matching the prototype ProductCard
     (Quicksand 700, 15px). The body font left titles reading flatter than
     the hi-fi reference. */
  font-family: var(--font-display);
  font-weight: 700;
  color: var(--ink-900);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  line-height: 1.25;
  margin-bottom: var(--space-1);
  min-height: 2.5em;
  font-size: 15px;
  letter-spacing: -0.005em;
}
.listing-card__seller {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  color: var(--ink-500);
  margin-bottom: 2px;
}
.listing-card__seller svg { flex-shrink: 0; color: var(--ink-300); }
.listing-card__rating {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  font-size: 12px;
  font-weight: 700;
  color: var(--ink-700);
  flex-shrink: 0;
}
.listing-card__location {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  color: var(--ink-500);
  margin-bottom: 2px;
}
.listing-card__location svg { flex-shrink: 0; color: var(--ink-300); }
.card-trust-row { margin-bottom: 4px; }
.card-escrow-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 11px;
  font-weight: 700;
  /* Fixed light chip in both themes. The success token flips dark in
     dark mode, which dropped this badge below 4.5:1 contrast. Pinning
     the colours keeps the escrow badge readable everywhere. */
  color: #1E6E3E;
  background: #DDF1E4;
  padding: 3px 10px;
  border-radius: var(--radius-pill);
}
.card-bottom-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  margin-top: auto;
  padding-top: 4px;
}
.card-time-ago {
  font-size: 11px;
  color: var(--ink-500);
  white-space: nowrap;
  flex-shrink: 0;
}
.listing-card .meta,
.listing-card__meta {
  font-size: 12px;
  color: var(--ink-500);
  margin-bottom: 4px;
}
.listing-card .price,
.listing-card__price {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--fs-price);
  color: var(--ink-900);
  letter-spacing: -0.01em;
  line-height: 1.2;
  /* Keep large rand values (e.g. R 2 850 000) on one line so the card
     layout never breaks into a stack of digits. */
  white-space: nowrap;
}
.listing-card__price-currency,
.price__currency {
  font-weight: 600;
  opacity: 0.7;
  margin-right: 2px;
}
.listing-card--compact .listing-card__body { padding: var(--space-2) var(--space-1) var(--space-1); }
.listing-card--compact .listing-card__title {
  font-size: 13px;
  min-height: auto;
  -webkit-line-clamp: 1;
}
.listing-card--compact .listing-card__price { font-size: 16px; }
.card-social-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 4px;
}
.card-views { font-size: 11px; color: var(--ink-500); }


/* ----------------------------------------------------------------
   7. STATUS PILLS
   ---------------------------------------------------------------- */
.pill, .tag {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 4px 12px;
  border-radius: var(--radius-pill);
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  line-height: 1.4;
  white-space: nowrap;
  background: var(--ink-100);
  color: var(--ink-700);
}
.pill-placed     { background: var(--status-placed-bg);     color: var(--status-placed-fg); }
.pill-paid       { background: var(--status-paid-bg);       color: var(--status-paid-fg); }
.pill-dispatched { background: var(--status-dispatched-bg); color: var(--status-dispatched-fg); }
.pill-received   { background: var(--status-received-bg);   color: var(--status-received-fg); }
.pill-completed  { background: var(--status-completed-bg);  color: var(--status-completed-fg); }
.pill-cancelled  { background: var(--status-cancelled-bg);  color: var(--status-cancelled-fg); }
.pill-disputed   { background: var(--status-disputed-bg);   color: var(--status-disputed-fg); }
.pill-pending    { background: var(--status-placed-bg);     color: var(--status-placed-fg); }
.pill-accepted   { background: var(--status-paid-bg);       color: var(--status-paid-fg); }
.pill-rejected   { background: var(--status-disputed-bg);   color: var(--status-disputed-fg); }
.pill-expired    { background: var(--status-cancelled-bg);  color: var(--status-cancelled-fg); }


/* ----------------------------------------------------------------
   8. FORMS
   ---------------------------------------------------------------- */
.form-control, .form-select {
  background: var(--ink-50);
  border: 1.5px solid var(--ink-300);
  border-radius: 12px;
  color: var(--ink-900);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  padding: 10px 14px;
  transition: border-color var(--duration-fast) ease,
              box-shadow var(--duration-fast) ease;
}
.form-control:focus, .form-select:focus {
  background: var(--paper);
  border-color: var(--brand-orange);
  box-shadow: 0 0 0 3px rgb(248,154,31,0.18);
  outline: none;
}
.form-label { font-weight: 600; color: var(--ink-700); margin-bottom: var(--space-1); }
.form-control::placeholder { color: var(--ink-400); opacity: 1; }


/* ----------------------------------------------------------------
   9. HERO (homepage - premium)
   ---------------------------------------------------------------- */
.m2y-hero {
  /* Contained, calm cream panel (the hi-fi target) instead of a full-bleed
     three-stop orange gradient. A single restrained tint lets the orange
     read as an accent, not the whole canvas. */
  /* --hero-base is the hero's own bottom-edge colour. The stats bar fades
     into this exact value so it dissolves into the frame with no hard cut.
     Dark mode overrides --hero-base to match its gradient foot. */
  --hero-base: var(--brand-orange-50);
  background: var(--brand-orange-50);
  border: 1px solid var(--brand-orange-100);
  border-radius: var(--radius-xl);
  padding: 48px 0 0;
  margin: var(--space-5) 0 var(--space-6);
  position: relative;
  overflow: hidden;
}
.m2y-hero__logo {
  display: block;
  animation: heroFloat 4s ease-in-out infinite;
  filter: drop-shadow(0 4px 12px rgb(248,154,31,0.18));
}

@keyframes heroFloat {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-6px); }
}
.m2y-hero__heading {
  font-size: clamp(30px, 5vw, 48px);
  line-height: 1.12;
  margin: 0 0 14px;
  letter-spacing: -0.02em;
}
/* Hero accent is large display text - the -700 shade clears the 3:1
   large-text AA threshold that raw --brand-orange (2.1:1) fails. */
.m2y-hero__accent { color: var(--brand-orange-700); position: relative; }
.m2y-hero__accent::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: 2px;
  width: 100%;
  height: 6px;
  background: var(--brand-orange-100);
  border-radius: 3px;
  z-index: -1;
}
.m2y-hero__sub {
  color: var(--ink-500);
  font-size: 18px;
  line-height: 1.55;
  margin-bottom: 24px;
  max-width: 480px;
}
.m2y-hero__cta {
  padding: 12px 28px !important;
  font-size: 16px !important;
  border-radius: 14px !important;
}
.m2y-hero__illustration {
  position: relative;
  width: 280px;
  height: 280px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.m2y-hero__illustration::before {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(circle, rgb(248,154,31,0.12) 0%, transparent 70%);
  border-radius: 50%;
}
.m2y-hero__illustration-img {
  animation: heroFloat 4s ease-in-out infinite;
  filter: drop-shadow(0 8px 24px rgb(248,154,31,0.2));
  opacity: 0.15;
}
.m2y-hero__stats {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-5);
  /* Dissolve into the hero frame: transparent at the top so the hero tint
     flows through, fading into the hero's own base colour at the bottom.
     No hard border line, no solid panel, so there is no cut-off edge. */
  background: linear-gradient(to bottom, transparent 0%, var(--hero-base) 72%);
  border-top: 0;
  border-radius: 0;
  padding: var(--space-4) var(--space-6);
  margin-top: var(--space-6);
}
.m2y-hero__stat { display: flex; align-items: center; gap: 6px; white-space: nowrap; }
.m2y-hero__stat-num {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 18px;
  color: var(--ink-900);
}
.m2y-hero__stat-label { font-size: 14px; font-weight: 600; color: var(--ink-500); }
.m2y-hero__stat-icon { color: var(--success); flex-shrink: 0; }
.m2y-hero__stat-divider { width: 1px; height: 24px; background: var(--ink-300); flex-shrink: 0; }

/* Hero entrance: one orchestrated reveal on load. Children rise and fade in
   sequence (transform + opacity only). Opt-in via no-preference, so reduced
   motion users see the final state immediately with no animation. */
@media (prefers-reduced-motion: no-preference) {
  @keyframes heroRise {
    from { opacity: 0; transform: translateY(14px); }
    to   { opacity: 1; transform: translateY(0); }
  }
  .m2y-hero__heading,
  .m2y-hero__sub,
  .m2y-hero__actions,
  .m2y-hero__illustration,
  .m2y-hero__stats {
    animation: heroRise 0.5s var(--ease-out, ease-out) both;
  }
  .m2y-hero__heading              { animation-delay: 0.05s; }
  .m2y-hero__sub                  { animation-delay: 0.12s; }
  .m2y-hero__sub + .m2y-hero__sub { animation-delay: 0.18s; }
  .m2y-hero__illustration         { animation-delay: 0.20s; }
  .m2y-hero__actions              { animation-delay: 0.26s; }
  .m2y-hero__stats                { animation-delay: 0.34s; }
  /* Logo rises in first, then resumes its gentle float. */
  .m2y-hero__logo {
    animation: heroRise 0.5s var(--ease-out, ease-out) both,
               heroFloat 3s ease-in-out 0.55s infinite;
  }
}

/* Contain the hero panel to the content width with breathing room either
   side, so it reads as one calm card rather than a full-bleed band. */
.m2y-hero {
  max-width: calc(var(--content-max) - var(--space-6));
  margin-left: auto;
  margin-right: auto;
}

@media (max-width: 575.98px) {
  .m2y-hero {
    padding: 28px 0 0;
    margin: var(--space-4) var(--space-3) var(--space-5);
    border-radius: var(--radius-lg);
  }
  .m2y-hero__heading { font-size: 28px; }
  .m2y-hero__sub { font-size: 15px; }
  .m2y-hero__logo { width: 64px; height: 64px; }
  .m2y-hero__stats { gap: var(--space-3); padding: var(--space-3) var(--space-4); flex-wrap: wrap; justify-content: center; }
  .m2y-hero__stat-num { font-size: 15px; }
  .m2y-hero__stat-label { font-size: 12px; }
  .m2y-hero__cta { padding: 10px 20px !important; font-size: 14px !important; }
}


/* ----------------------------------------------------------------
   10. TRUST STRIP (homepage - premium)
   ---------------------------------------------------------------- */
.m2y-trust-strip { background: var(--ink-50); padding: 48px 0 56px; margin-top: 0; }
.m2y-trust__card {
  background: var(--paper);
  border: 1px solid var(--ink-200);
  border-radius: var(--radius-lg);
  padding: 28px 24px;
  height: 100%;
  text-align: center;
  transition: box-shadow var(--duration-normal) var(--ease-out),
              transform var(--duration-normal) var(--ease-out);
}
.m2y-trust__card:hover { transform: translateY(-4px); box-shadow: 0 12px 32px rgb(46,33,22,0.1); }
.m2y-trust__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: var(--brand-orange-50);
  color: var(--brand-orange-700);
  margin: 0 auto 16px;
}
.m2y-trust__title {
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 700;
  margin-bottom: 8px;
  color: var(--ink-900);
}
.m2y-trust__text { font-size: 14px; color: var(--ink-500); margin-bottom: 0; line-height: 1.55; }

/* Trust badge (rendered by trust_badge_html). The band colour arrives
   as --m2y-trust-bg via data-style-vars; everything else is static so
   the page never needs an inline style attribute. */
.m2y-trust {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px;
  border-radius: 999px;
  background: var(--m2y-trust-bg, #6B5E55);
  color: #fff;
  font-size: 12px;
  font-weight: 700;
  white-space: nowrap;
}


/* ----------------------------------------------------------------
   11. SECTION TITLES (homepage)
   ---------------------------------------------------------------- */
.hp-section-title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--fs-h3);
  letter-spacing: -0.01em;
  color: var(--ink-900);
  margin-bottom: var(--space-4);
}
.hp-see-all {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 14px;
  font-weight: 600;
  color: var(--brand-orange-700);
  text-decoration: none;
  transition: color var(--duration-fast) ease;
}
.hp-see-all:hover { color: var(--brand-orange); text-decoration: none; }


/* ----------------------------------------------------------------
   12. CATEGORY CHIPS (horizontal scroll)
   ---------------------------------------------------------------- */
.cat-chip-scroll {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding-bottom: 4px;
}
.cat-chip-scroll::-webkit-scrollbar { display: none; }
.cat-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 10px 16px;
  background: var(--paper);
  border: 1px solid var(--ink-300);
  border-radius: var(--radius-pill);
  color: var(--ink-700);
  font-weight: 600;
  font-size: 14px;
  text-decoration: none;
  white-space: nowrap;
  flex-shrink: 0;
  transition: background var(--duration-fast) ease,
              color var(--duration-fast) ease,
              border-color var(--duration-fast) ease,
              box-shadow var(--duration-fast) ease;
}
.cat-chip__icon { display: inline-flex; align-items: center; color: var(--ink-500); flex-shrink: 0; }
.cat-chip:hover {
  /* Quiet ink tint on hover. Orange is reserved for the active chip so the
     rail stays calm and the accent stays meaningful. */
  background: var(--ink-100);
  border-color: var(--ink-400);
  color: var(--ink-900);
  text-decoration: none;
}
.cat-chip:hover .cat-chip__icon { color: var(--ink-700); }
.cat-chip.active {
  background: var(--brand-orange);
  border-color: var(--brand-orange-600);
  color: #fff;
  font-weight: 700;
}
.cat-chip.active .cat-chip__icon { color: #fff; }


/* ----------------------------------------------------------------
   13. FOOTER
   ---------------------------------------------------------------- */
.m2y-foot {
  background: #1F1A17;
  color: #d6cfbf;
  padding: 48px 0 28px;
  margin-top: 56px;
  font-size: 13px;
  font-family: var(--font-body);
  line-height: 1.6;
}
.m2y-foot a { color: #d6cfbf; border-bottom: none; text-decoration: none; transition: color var(--duration-fast) ease; }
.m2y-foot a:hover { color: var(--brand-orange); text-decoration: none; }
.m2y-foot__heading {
  color: #fff;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 15px;
  margin-bottom: var(--space-3);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.m2y-foot__links li { margin-bottom: 6px; }
.m2y-foot__links a { font-size: 13px; transition: color var(--duration-fast) ease; }
.m2y-foot__rule { border-color: #3a3530; margin: 28px 0 var(--space-4); }
.m2y-foot__brand { color: #fff; font-family: var(--font-display); font-weight: 700; font-size: 18px; }
.m2y-foot__copy { font-size: 12px; color: #a69d90; }
.m2y-foot__pay { font-size: 12px; color: #a69d90; }

@media (max-width: 575.98px) {
  .m2y-foot { padding: 28px 0 18px; }
  .m2y-foot__heading { font-size: 14px; margin-bottom: var(--space-2); }
}


/* ----------------------------------------------------------------
   14. TOASTS / ALERTS
   ---------------------------------------------------------------- */
.alert-brand {
  background: var(--brand-orange-50);
  border: 1px solid var(--brand-orange);
  color: var(--ink-900);
  border-radius: var(--radius-sm);
}


/* ----------------------------------------------------------------
   15. MOBILE BOTTOM NAV
   ---------------------------------------------------------------- */
.m2y-bnav {
  display: none;
  position: fixed;
  bottom: 0; left: 0; right: 0;
  height: 64px;
  background: #fff;
  border-top: 1px solid var(--ink-200);
  padding: 6px 0 8px;
  z-index: var(--z-bnav);
  justify-content: space-around;
  align-items: center;
}
.m2y-bnav a {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  /* WCAG 2.5.5: minimum 44x44px touch target for the primary mobile nav. */
  min-height: 44px;
  min-width: 44px;
  padding: 4px 8px;
  font-size: 11px;
  color: var(--ink-500);
  text-decoration: none;
  position: relative;
  transition: color var(--duration-fast) ease;
}
.m2y-bnav a.active { color: var(--brand-orange-700); font-weight: 700; }
/* The active-item dot is defined once, on the authoritative bottom-nav
   block lower in this file (as ::after, under the bar). The earlier
   ::before dot was removed so the active tab shows a single dot, not two. */
.m2y-bnav a svg { width: 22px; height: 22px; }

@media (max-width: 768px) {
  .m2y-bnav { display: flex; }
  /* Bottom spacing for the fixed nav is owned by the authoritative footer
     block (.m2y-foot padding-bottom). Keeping body padding here too would
     double the gap on the phone, so it is not set in this earlier block. */
}


/* ----------------------------------------------------------------
   16. ESCROW-STATUS BANNER
   ---------------------------------------------------------------- */
.escrow-banner {
  background: var(--success-100);
  border-left: 4px solid var(--success);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-sm);
  margin: var(--space-4) 0;
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
.escrow-banner.is-frozen { background: var(--danger-100); border-left-color: var(--danger); }
.escrow-banner .lbl { font-weight: 700; color: var(--ink-900); }
.escrow-banner .countdown { font-family: var(--font-mono); }


/* ----------------------------------------------------------------
   17. SKELETON LOADING
   ---------------------------------------------------------------- */
.skeleton {
  background: linear-gradient(90deg, #f0ebe4 25%, #e8e0d6 50%, #f0ebe4 75%);
  background-size: 200% 100%;
  animation: m2y-shimmer 1.5s ease-in-out infinite;
  border-radius: var(--radius-xs);
  position: relative;
  overflow: hidden;
}

@keyframes m2y-shimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

@keyframes shimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}
.skeleton-text, .skeleton--text { height: 14px; margin-bottom: var(--space-2); }
.skeleton-text:last-child, .skeleton--text:last-child { width: 60%; }
.skeleton-title, .skeleton--heading { height: 20px; width: 60%; margin-bottom: var(--space-3); }
.skeleton-img, .skeleton--img { aspect-ratio: 1; width: 100%; border-radius: var(--radius-lg) var(--radius-lg) 0 0; }
.skeleton-card, .skeleton--card { padding: var(--space-3); border: 1px solid var(--ink-200); border-radius: var(--radius-lg); height: 200px; }
.skeleton--avatar { width: 48px; height: 48px; border-radius: 50%; }
.skeleton--price { height: 26px; width: 80px; }
.skeleton--pill { height: 22px; width: 64px; border-radius: var(--radius-pill); }

.skeleton-suggest-row { display: flex; align-items: center; gap: 10px; padding: var(--space-2) 14px; }
.skeleton-suggest-thumb { width: 40px; height: 40px; border-radius: var(--radius-xs); flex-shrink: 0; }
.skeleton-suggest-info { flex: 1; display: flex; flex-direction: column; gap: 6px; }
.skeleton-suggest-line { height: 12px; border-radius: var(--radius-xs); }
.skeleton-suggest-line:first-child { width: 70%; }
.skeleton-suggest-line:last-child  { width: 45%; }
.skeleton-suggest-price { width: 48px; height: 16px; border-radius: var(--radius-xs); flex-shrink: 0; }


/* ================================================================
   ENHANCED COMPONENTS (production polish)
   ================================================================ */

/* ----------------------------------------------------------------
   18. TOAST NOTIFICATIONS (slide-in from right)
   ---------------------------------------------------------------- */
.m2y-toast {
  position: fixed;
  top: var(--space-5);
  right: var(--space-5);
  z-index: var(--z-toast);
  min-width: 300px;
  max-width: 420px;
  padding: var(--space-4) var(--space-5);
  border-radius: var(--radius-md);
  background: var(--paper);
  border: 1px solid var(--ink-300);
  box-shadow: var(--shadow-xl);
  font-size: 14px;
  color: var(--ink-900);
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  transform: translateX(calc(100% + var(--space-5)));
  opacity: 0;
  transition: transform var(--duration-slow) var(--ease-spring),
              opacity var(--duration-slow) var(--ease-out);
  pointer-events: none;
}
.m2y-toast.is-active { transform: translateX(0); opacity: 1; pointer-events: auto; }
.m2y-toast--success { border-left: 4px solid var(--success); }
.m2y-toast--warning { border-left: 4px solid var(--warning); }
.m2y-toast--danger  { border-left: 4px solid var(--danger); }
.m2y-toast--info    { border-left: 4px solid var(--info); }
.m2y-toast__title { font-weight: 700; margin-bottom: var(--space-1); }
.m2y-toast__body { color: var(--ink-500); font-size: 13px; line-height: 1.45; flex: 1; }
.m2y-toast__close {
  margin-left: auto;
  background: none;
  border: none;
  color: var(--ink-500);
  cursor: pointer;
  padding: var(--space-1);
  border-radius: var(--radius-xs);
  font-size: 18px;
  line-height: 1;
  transition: color var(--duration-fast) ease;
}
.m2y-toast__close:hover { color: var(--ink-900); }

/* On a 375px phone the fixed toast (min-width 300px + 24px offset) sat
   close to the edge. Pin it to both sides with a small inset so it never
   touches the viewport edge or triggers a horizontal scroll. */
@media (max-width: 575.98px) {
  .m2y-toast {
    left: var(--space-3);
    right: var(--space-3);
    min-width: 0;
    max-width: none;
  }
}

@keyframes m2y-toast-in {
  from { transform: translateX(calc(100% + var(--space-5))); opacity: 0; }
  to   { transform: translateX(0); opacity: 1; }
}

@keyframes m2y-toast-out {
  from { transform: translateX(0); opacity: 1; }
  to   { transform: translateX(calc(100% + var(--space-5))); opacity: 0; }
}


/* ----------------------------------------------------------------
   19. PRICE STYLING
   ---------------------------------------------------------------- */
.m2y-price {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--fs-price);
  color: var(--ink-900);
  letter-spacing: -0.01em;
  line-height: 1.2;
}
.m2y-price__currency { font-weight: 600; opacity: 0.7; font-size: 0.8em; margin-right: 2px; }
.m2y-price--lg { font-size: var(--fs-price-lg); }
.m2y-price--sm { font-size: 18px; }


/* ----------------------------------------------------------------
   20. EMPTY STATE
   ---------------------------------------------------------------- */
.m2y-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: var(--space-8) var(--space-6);
  min-height: 240px;
}
.m2y-empty__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 72px;
  height: 72px;
  border-radius: 50%;
  background: var(--ink-100);
  color: var(--ink-300);
  margin-bottom: var(--space-5);
}
.m2y-empty__icon svg { width: 32px; height: 32px; opacity: 0.6; }
.m2y-empty__title {
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 700;
  color: var(--ink-700);
  margin-bottom: var(--space-2);
}
.m2y-empty__text {
  font-size: 14px;
  color: var(--ink-500);
  max-width: 360px;
  line-height: 1.5;
  margin-bottom: var(--space-5);
}


/* ----------------------------------------------------------------
   21. TABLE ZEBRA STRIPING (admin)
   ---------------------------------------------------------------- */
.m2y-table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 14px; }
.m2y-table thead th {
  background: var(--ink-50);
  padding: var(--space-3) var(--space-4);
  font-weight: 700;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink-500);
  border-bottom: 2px solid var(--ink-300);
  text-align: left;
  white-space: nowrap;
}
.m2y-table tbody td {
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--ink-100);
  color: var(--ink-900);
  vertical-align: middle;
}
.m2y-table tbody tr:nth-child(even) { background: var(--ink-50); }
.m2y-table tbody tr:hover { background: var(--brand-orange-50); }

.table-striped > tbody > tr:nth-of-type(odd) > * { --bs-table-accent-bg: transparent; }
.table-striped > tbody > tr:nth-of-type(even) > * { --bs-table-accent-bg: var(--ink-50); }
.table-hover > tbody > tr:hover > * { --bs-table-accent-bg: var(--brand-orange-50); }


/* ----------------------------------------------------------------
   22. BREADCRUMBS (chevron separators)
   ---------------------------------------------------------------- */
.m2y-breadcrumb {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0;
  list-style: none;
  padding: 0;
  margin: 0 0 var(--space-5) 0;
  font-size: 13px;
}
.m2y-breadcrumb li { display: inline-flex; align-items: center; }
.m2y-breadcrumb li + li::before {
  content: '';
  display: inline-block;
  width: 6px;
  height: 6px;
  border-right: 1.5px solid var(--ink-500);
  border-bottom: 1.5px solid var(--ink-500);
  transform: rotate(-45deg);
  margin: 0 var(--space-2);
  flex-shrink: 0;
}
.m2y-breadcrumb a { color: var(--ink-500); text-decoration: none; transition: color var(--duration-fast) ease; }
.m2y-breadcrumb a:hover { color: var(--brand-orange-700); text-decoration: underline; }
.m2y-breadcrumb .is-current { color: var(--ink-900); font-weight: 600; }


/* ----------------------------------------------------------------
   23. BADGE PULSE (unread count)
   ---------------------------------------------------------------- */
.m2y-badge-pulse {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 20px;
  padding: 0 6px;
  border-radius: var(--radius-pill);
  background: var(--danger);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
}
.m2y-badge-pulse::after {
  content: '';
  position: absolute;
  inset: -2px;
  border-radius: inherit;
  background: var(--danger);
  opacity: 0.4;
  animation: m2y-pulse 2s ease-in-out infinite;
  z-index: -1;
}

@keyframes m2y-pulse {
  0%, 100% { transform: scale(1); opacity: 0.4; }
  50% { transform: scale(1.35); opacity: 0; }
}


/* ----------------------------------------------------------------
   24. SECTION TITLE (orange underline accent)
   ---------------------------------------------------------------- */
.m2y-section-title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 22px;
  color: var(--ink-900);
  margin-bottom: var(--space-5);
  position: relative;
  padding-bottom: var(--space-2);
}
.m2y-section-title::after {
  content: '';
  position: absolute;
  bottom: 0; left: 0;
  width: 40px;
  height: 3px;
  border-radius: 2px;
  background: var(--brand-orange);
}


/* ----------------------------------------------------------------
   25. UTILITIES
   ---------------------------------------------------------------- */
.m2y-divider { border: none; border-top: 1px solid var(--ink-100); margin: var(--space-6) 0; }
.m2y-card-grid { display: grid; gap: var(--space-5); }
.m2y-img-placeholder { background: var(--ink-100); display: flex; align-items: center; justify-content: center; color: var(--ink-300); }
.m2y-truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.m2y-loading-overlay {
  position: absolute;
  inset: 0;
  background: rgb(255,255,255,0.7);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 10;
  border-radius: inherit;
}
.m2y-tag {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 2px 10px;
  border-radius: var(--radius-pill);
  font-size: 12px;
  font-weight: 600;
  background: var(--ink-100);
  color: var(--ink-700);
}
/* Avatar sizes itself from the width/height attributes set per call by
   avatar_html() (36 in the header, 28 in the feed, 24 in community, 96 on
   profiles), so do NOT pin a fixed width/height on the base class. */
.m2y-avatar { border-radius: 50%; object-fit: cover; display: block; border: 1px solid var(--paper); box-shadow: var(--shadow-xs); }
.m2y-avatar--lg { width: 56px; height: 56px; }
.m2y-avatar--sm { width: 28px; height: 28px; }
.m2y-card-link { text-decoration: none; color: inherit; display: block; }
.m2y-card-link:hover { text-decoration: none; color: inherit; }
.m2y-stars { display: inline-flex; gap: 1px; color: var(--brand-orange); }
.m2y-stars--muted { color: var(--ink-300); }


/* ----------------------------------------------------------------
   25b. WELCOME TOUR (onboarding tooltips)
   ---------------------------------------------------------------- */
.m2y-tour-overlay {
  position: fixed;
  inset: 0;
  background: rgb(31,26,23,0.65);
  z-index: 10000;
  transition: opacity var(--duration-normal) var(--ease-out);
  opacity: 0;
  pointer-events: none;
}
.m2y-tour-overlay.is-active {
  opacity: 1;
  pointer-events: auto;
}

/* Highlighted element styles (applied via JS) */
.m2y-tour-highlight {
  position: relative !important;
  z-index: 10001 !important;
  box-shadow: 0 0 0 3px var(--brand-orange), 0 0 0 6px rgb(248,154,31,0.35) !important;
  border-radius: var(--radius-sm) !important;
  animation: m2yTourPulse 2s ease-in-out infinite;
}

@keyframes m2yTourPulse {
  0%, 100% { box-shadow: 0 0 0 3px var(--brand-orange), 0 0 0 6px rgb(248,154,31,0.35); }
  50%      { box-shadow: 0 0 0 4px var(--brand-orange), 0 0 0 12px rgb(248,154,31,0.18); }
}

/* Tooltip bubble */
.m2y-tour-tip {
  position: fixed;
  z-index: 10002;
  background: #1F1A17;
  color: #fff;
  border-radius: var(--radius-md);
  padding: 20px 22px 16px;
  max-width: 320px;
  width: calc(100vw - 32px);
  box-shadow: 0 8px 32px rgb(0,0,0,0.3);
  font-family: var(--font-body);
  font-size: 14px;
  line-height: 1.55;
  opacity: 0;
  transform: translateY(8px);
  transition: opacity var(--duration-normal) var(--ease-out),
              transform var(--duration-normal) var(--ease-out);
  pointer-events: none;
}
.m2y-tour-tip.is-visible {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}

/* Modal variant (centered, no arrow) */
.m2y-tour-tip.is-modal {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) scale(0.95);
  max-width: 400px;
}
.m2y-tour-tip.is-modal.is-visible {
  transform: translate(-50%, -50%) scale(1);
}

/* Arrow */
.m2y-tour-tip__arrow {
  position: absolute;
  width: 14px;
  height: 14px;
  background: #1F1A17;
  transform: rotate(45deg);
}
/* Arrow positions set via JS inline style */

/* Tip content */
.m2y-tour-tip__text {
  margin-bottom: 14px;
}

/* Footer row: step counter + skip + next */
.m2y-tour-tip__footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.m2y-tour-tip__step {
  font-size: 12px;
  font-weight: 600;
  color: #a69d90;
  flex-shrink: 0;
}
.m2y-tour-tip__skip {
  font-size: 13px;
  color: #a69d90;
  background: none;
  border: none;
  cursor: pointer;
  padding: 0;
  font-family: var(--font-body);
  text-decoration: underline;
  text-underline-offset: 2px;
  transition: color var(--duration-fast) ease;
}
.m2y-tour-tip__skip:hover {
  color: #fff;
}
.m2y-tour-tip__next {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  /* Darker on-brand orange so white text clears 4.5:1 contrast. */
  background: #B65F0A;
  color: #fff;
  border: none;
  border-radius: var(--radius-sm);
  padding: 8px 20px;
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
  transition: background var(--duration-fast) ease;
  flex-shrink: 0;
}
.m2y-tour-tip__next:hover {
  background: var(--brand-orange-600);
}
.m2y-tour-tip__next:active {
  background: var(--brand-orange-700);
}

/* Tour link on help page */
.m2y-tour-launch {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  /* Reset native button chrome so the <button> matches the old link look */
  background: none;
  border: 0;
  padding: 10px 8px;
  min-height: 44px;
  font: inherit;
  color: var(--brand-orange-700);
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  transition: color var(--duration-fast) ease;
}
.m2y-tour-launch:hover {
  color: var(--brand-orange);
  text-decoration: underline;
}

/* Reduced motion: disable pulse, skip transitions */
@media (prefers-reduced-motion: reduce) {
  .m2y-tour-highlight {
    animation: none !important;
  }
  .m2y-tour-tip,
  .m2y-tour-overlay {
    transition: none !important;
  }
}

@media print {
  .m2y-tour-overlay,
  .m2y-tour-tip {
    display: none !important;
  }
}


/* ----------------------------------------------------------------
   26. CUSTOM SCROLLBAR
   ---------------------------------------------------------------- */
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--ink-300); border-radius: var(--radius-pill); }
::-webkit-scrollbar-thumb:hover { background: var(--ink-500); }
* { scrollbar-width: thin; scrollbar-color: var(--ink-300) transparent; }


/* ----------------------------------------------------------------
   26b. TABLET (768px - 1024px)
   The layout previously jumped straight from mobile (<=768px) to
   desktop with no intermediate rules. These tune the hero, content
   width and listing grid density for tablet portrait/landscape.
   ---------------------------------------------------------------- */
@media (min-width: 768px) and (max-width: 1024px) {
  .m2y-hero__heading { font-size: clamp(26px, 4.2vw, 40px); }
  .m2y-content, .container { padding-left: 24px; padding-right: 24px; }
  /* Listing grid: 3 across on tablet instead of 4, for comfortable tap size */
  .listing-grid { grid-template-columns: repeat(3, 1fr); }
  .m2y-hero { padding-top: 36px; padding-bottom: 28px; }
  /* Keep the brand search field comfortably wide on tablet */
  .m2y-header__search { max-width: 360px; }
}


/* ----------------------------------------------------------------
   27. PRINT STYLES
   ---------------------------------------------------------------- */
@media print {
  .m2y-header, .m2y-foot, .m2y-bnav, .m2y-toast, .skip-to-content,
  .sidebar, .btn-brand, .btn-outline-brand,
  nav, footer, .no-print {
    display: none !important;
  }
  body { background: #fff; color: #000; font-size: 12pt; padding: 0; margin: 0; animation: none; }
  a { color: #000; text-decoration: underline; }
  a[href^="http"]::after { content: ' (' attr(href) ')'; font-size: 10pt; color: #555; }
  .listing-card { break-inside: avoid; border: 1px solid #ddd; box-shadow: none; }
  .m2y-table thead th { background: #eee !important; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
  .m2y-table tbody tr:nth-child(even) { background: #f9f9f9 !important; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
  .pill { border: 1px solid currentColor; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
}


/* ================================================================
   28. v1.2 POLISH PASS
   ----------------------------------------------------------------
   Additive craft layer. Reuses existing tokens only - no new colours.
   All motion is transform/opacity only (GPU-cheap) and is gated behind
   prefers-reduced-motion: no-preference, so reduced-motion users get a
   still interface by default. This is the honest default for cheap
   phones that drop frames and for users with vestibular sensitivity.
   ================================================================ */

/* ----------------------------------------------------------------
   28.1 BRANDED FOCUS RING
   Strengthen the shared focus-visible into a clear two-part ring
   (orange outline + soft halo) so a keyboard or screen-reader user can
   always see where they are, even on a washed-out LCD in sunlight.
   ---------------------------------------------------------------- */
.btn-brand:focus-visible,
.btn-outline-brand:focus-visible,
.listing-card a:focus-visible,
.cat-chip:focus-visible,
.m2y-socialbar__btn:focus-visible,
.m2y-header__link:focus-visible,
.pill:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
  outline: 2px solid var(--brand-orange);
  outline-offset: 2px;
  box-shadow: 0 0 0 4px var(--brand-orange-100);
}

/* ----------------------------------------------------------------
   28.2 LISTING CARD - PRICE + TRUST EMPHASIS
   Price and the escrow trust badge are the focal points on a card.
   Lift the price weight/size and give the bottom row a hairline divider
   so the eye lands on price first, trust second. Conversion-critical.
   ---------------------------------------------------------------- */
.listing-card__body {
  gap: var(--space-1);
}
.listing-card .card-bottom-row,
.listing-card__body .card-bottom-row {
  border-top: 1px solid var(--ink-100);
  margin-top: var(--space-2);
  padding-top: var(--space-2);
}
.listing-card .price,
.listing-card__price {
  /* Price reads in ink, not orange, to match the hi-fi prototype Price
     component and keep the brand accent meaningful. Orange on every card
     price flooded the grid; restraint is what reads as premium here. */
  font-size: 20px;
  color: var(--ink-900);
}
.listing-card--compact .listing-card__price {
  color: var(--ink-900);
}
.card-escrow-badge {
  letter-spacing: 0.01em;
}

/* ----------------------------------------------------------------
   28.3 SPACING RHYTHM
   Pin section and grid gaps to the 4/8/12/16/24 scale so vertical
   rhythm reads as deliberate, not arbitrary.
   ---------------------------------------------------------------- */
.listing-grid {
  gap: var(--space-4);
}
.m2y-empty {
  gap: var(--space-1);
}

/* ----------------------------------------------------------------
   28.4 EMPTY STATE - NAMED ALIAS
   Provide the .empty-state vocabulary on top of the existing .m2y-empty
   component so future markup can use either name. CTA inherits .btn-brand.
   ---------------------------------------------------------------- */
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: var(--space-1);
  padding: var(--space-8) var(--space-6);
  min-height: 240px;
}
.empty-state__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 72px;
  height: 72px;
  border-radius: 50%;
  background: var(--ink-100);
  color: var(--ink-400);
  margin-bottom: var(--space-4);
}
.empty-state__icon svg {
  width: 32px;
  height: 32px;
  stroke-width: 1.75;
}
.empty-state__title {
  font-family: var(--font-display);
  font-size: var(--fs-h4);
  font-weight: 700;
  color: var(--ink-700);
}
.empty-state__text {
  font-size: var(--fs-sm);
  color: var(--ink-500);
  max-width: 360px;
  line-height: 1.5;
  margin-bottom: var(--space-4);
}

/* ----------------------------------------------------------------
   28.5 ICONOGRAPHY RHYTHM
   Inline SVG icons inside interactive surfaces share a 1.75 stroke so
   the line weight reads as one family across the system.
   ---------------------------------------------------------------- */
.btn-brand svg,
.btn-outline-brand svg,
.empty-state__icon svg,
.m2y-empty__icon svg {
  stroke-width: 1.75;
}

/* ----------------------------------------------------------------
   28.6 MOTION - REFINED, GPU-CHEAP, OPT-IN
   Only transform + opacity. Gated behind no-preference. Durations sit in
   the 120-180ms band on ease-out, matching the existing motion tokens.
   ---------------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {
  .listing-card {
    transition: transform 0.16s var(--ease-out),
                box-shadow 0.16s var(--ease-out);
  }
  .listing-card:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-md);
  }
  .btn-brand,
  .btn-outline-brand,
  .m2y-socialbar__btn {
    transition: background 0.15s var(--ease-out),
                color 0.15s var(--ease-out),
                border-color 0.15s var(--ease-out),
                box-shadow 0.15s var(--ease-out),
                transform 0.12s var(--ease-out);
  }
  .btn-brand:active,
  .btn-outline-brand:active,
  .m2y-socialbar__btn:active {
    transform: scale(0.98);
  }
  a,
  .cat-chip,
  .pill,
  .tag {
    transition: color 0.15s var(--ease-out),
                background 0.15s var(--ease-out),
                border-color 0.15s var(--ease-out);
  }
}

/* ----------------------------------------------------------------
   28.7 SKELETON SHIMMER - TRULY PAUSED UNDER REDUCED MOTION
   The global reduce block clamps duration but leaves a single shimmer
   pass. Stop it dead and show a flat tint instead. The shimmer reads as
   movement, which is exactly what a vestibular-sensitive user opts out
   of, so it must hold still rather than flash once.
   ---------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .skeleton {
    animation: none !important;
    background: var(--ink-100) !important;
  }
}


/* ----------------------------------------------------------------
   header
   Count badges (cart / messages / notifications) start hidden when
   the count is zero. JS later sets an inline display when a live count
   arrives, which overrides this class. Replaces inline style="display:none".
   ---------------------------------------------------------------- */
/* Generic: an element that starts hidden and is revealed by JS setting an
   inline display (inline style overrides this class). Used by the picker
   "other" text inputs (pickers.js) and similar JS-toggled fields. */
.m2y-js-hidden { display: none; }

.m2y-header__badge--empty {
  display: none;
}

/* ----------------------------------------------------------------
   header layout (rebuilt)
   Sticky top bar on a warm --paper background sitting above page
   content but below toasts. Mobile-first: the bar collapses to a
   logo + hamburger row with a full-width search below, and the nav
   lives in an off-canvas drawer. From 769px up the drawer, hamburger
   and mobile search are hidden and the desktop links/actions show.
   Open-state class: .open (on the drawer + overlay) plus
   body.m2y-drawer-open (scroll lock). The surviving fragments
   (__badge--empty, __avatar, focus-visible ring, tablet __search
   max-width, dark-mode link colour) are reused, not redefined.
   ---------------------------------------------------------------- */
.m2y-header {
  position: sticky;
  top: 0;
  left: 0;
  right: 0;
  z-index: 1030;
  width: 100%;
  background: var(--paper);
  border-bottom: var(--border-thin);
  box-shadow: var(--shadow-sm);
}

.m2y-header__bar {
  width: 100%;
}

.m2y-header__inner {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  max-width: 1200px;
  margin: 0 auto;
  padding: var(--space-2) var(--space-4);
  min-height: 56px;
}

/* Logo (left) */
.m2y-header__logo {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  text-decoration: none;
  flex-shrink: 0;
}
.m2y-header__logo img {
  display: block;
  width: 32px;
  height: 32px;
}
.m2y-header__wordmark {
  font-family: 'Quicksand', system-ui, sans-serif;
  font-weight: 700;
  font-size: 20px;
  color: var(--ink-900);
  line-height: 1;
}

/* Search field (shared base, used desktop + mobile) */
.m2y-header__search {
  position: relative;
  display: flex;
  align-items: center;
  flex: 1 1 auto;
  min-width: 0;
  max-width: 520px;
  height: 44px;
  padding: 0 var(--space-3);
  background: var(--ink-50);
  border: var(--border-thin);
  border-radius: var(--radius-pill);
}
.m2y-header__search:focus-within {
  border-color: var(--brand-orange);
  background: var(--paper);
}
.m2y-header__search-icon {
  flex-shrink: 0;
  color: var(--ink-500);
  margin-right: var(--space-2);
}
.m2y-header__search-input {
  flex: 1 1 auto;
  min-width: 0;
  height: 100%;
  border: 0;
  background: transparent;
  font-family: 'Nunito', system-ui, sans-serif;
  font-size: 16px;
  color: var(--ink-900);
  outline: none;
}
.m2y-header__search-input::placeholder { color: var(--ink-500); }

/* Right-side links + actions cluster */
.m2y-header__actions {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  margin-left: auto;
  flex-shrink: 0;
}
.m2y-header__links {
  display: flex;
  align-items: center;
  gap: var(--space-1);
}

/* Nav link (icon + word) */
.m2y-header__link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 44px;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  color: var(--ink-700);
  text-decoration: none;
  font-family: 'Nunito', system-ui, sans-serif;
  font-weight: 600;
  font-size: 15px;
  white-space: nowrap;
}
.m2y-header__link:hover { background: var(--ink-50); color: var(--ink-900); }
.m2y-header__link--icon {
  padding: var(--space-2);
  min-width: 44px;
  justify-content: center;
}
.m2y-header__link--auth { color: var(--brand-orange-800); }

/* Count badge anchored to an icon button */
.m2y-header__icon-wrap {
  position: relative;
  display: inline-flex;
}
.m2y-header__badge {
  position: absolute;
  top: -4px;
  right: -4px;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-pill);
  background: var(--brand-orange);
  color: #fff;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
}

/* Avatar button (circle, fills with the avatar image) */
.m2y-header__avatar {
  width: 36px;
  height: 36px;
  border-radius: var(--radius-pill);
  border: var(--border-thin);
  background: var(--ink-50);
  cursor: pointer;
  flex-shrink: 0;
}
.m2y-header__avatar--sm { width: 32px; height: 32px; }

/* Hamburger (mobile only) */
.m2y-header__hamburger {
  display: none;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  margin-left: auto;
  padding: 0;
  border: 0;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--ink-900);
  cursor: pointer;
  flex-shrink: 0;
}
.m2y-header__hamburger:hover { background: var(--ink-50); }

/* Full-width mobile search bar below the bar (mobile only) */
.m2y-header__mobile-search {
  display: none;
  padding: 0 var(--space-4) var(--space-3);
}
.m2y-header__mobile-search .m2y-header__search { max-width: none; }

/* Off-canvas drawer + dimmed overlay (mobile only) */
.m2y-header__overlay {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 1040;
  background: rgb(31,26,23,0.45);
  opacity: 0;
  /* Click-through while closed so the invisible (opacity 0) backdrop never
     swallows taps on the hamburger. Only the open overlay is interactive. */
  pointer-events: none;
}
.m2y-header__overlay.open { opacity: 1; pointer-events: auto; }

.m2y-header__drawer {
  display: none;
  position: fixed;
  top: 0;
  right: 0;
  z-index: 1041;
  width: 86%;
  max-width: 320px;
  height: 100%;
  padding: var(--space-4);
  background: var(--paper);
  box-shadow: var(--shadow-lg);
  overflow-y: auto;
  transform: translateX(100%);
}
.m2y-header__drawer.open { transform: translateX(0); }

/* Lock background scroll while the drawer is open */
body.m2y-drawer-open { overflow: hidden; }

.m2y-header__drawer-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--space-4);
}
.m2y-header__drawer-close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border: 0;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--ink-700);
  cursor: pointer;
}
.m2y-header__drawer-close:hover { background: var(--ink-50); }

.m2y-header__drawer-user {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) 0;
  border-bottom: var(--border-thin);
  margin-bottom: var(--space-3);
}
.m2y-header__drawer-name { font-family: 'Quicksand', system-ui, sans-serif; font-weight: 600; color: var(--ink-900); }
.m2y-header__drawer-email { font-size: 13px; color: var(--ink-500); word-break: break-all; }

.m2y-header__drawer-links {
  list-style: none;
  margin: 0 0 var(--space-4);
  padding: 0;
}
.m2y-header__drawer-links a {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 48px;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  color: var(--ink-900);
  text-decoration: none;
  font-family: 'Nunito', system-ui, sans-serif;
  font-weight: 600;
  font-size: 16px;
}
.m2y-header__drawer-links a:hover { background: var(--ink-50); }
.m2y-header__drawer-links a .m2y-header__badge {
  position: static;
  margin-left: auto;
}
.m2y-header__drawer-divider {
  height: 1px;
  margin: var(--space-2) 0;
  background: var(--ink-200);
  list-style: none;
}

.m2y-header__drawer-bottom { display: grid; gap: var(--space-3); }
.m2y-header__sell--full { width: 100%; justify-content: center; }
.m2y-header__drawer-signout {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  width: 100%;
  min-height: 44px;
  border: var(--border-thin);
  border-radius: var(--radius-md);
  background: var(--paper);
  color: var(--ink-700);
  font-family: 'Nunito', system-ui, sans-serif;
  font-weight: 600;
  cursor: pointer;
}
.m2y-header__drawer-auth { display: grid; gap: var(--space-2); }
.m2y-header__drawer-signin,
.m2y-header__drawer-register {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  border-radius: var(--radius-md);
  text-decoration: none;
  font-family: 'Nunito', system-ui, sans-serif;
  font-weight: 700;
}
.m2y-header__drawer-signin { border: var(--border-thin); color: var(--ink-900); }
.m2y-header__drawer-register { background: var(--brand-orange); color: #fff; }

/* DESKTOP: 769px and up. Hide all mobile-only pieces. */
@media (min-width: 769px) {
  .m2y-header__hamburger,
  .m2y-header__mobile-search,
  .m2y-header__overlay,
  .m2y-header__drawer {
    display: none !important;
  }
}

/* MOBILE: 768px and down. Hide desktop links + desktop search,
   show the hamburger, the full-width mobile search and enable the
   drawer + overlay. The icon actions (cart, messages, notifications,
   avatar) fold into the drawer to keep the bar uncluttered. */
@media (max-width: 768px) {
  .m2y-header__links,
  .m2y-header__search--desktop,
  .m2y-header__actions .m2y-header__link,
  .m2y-header__actions .m2y-header__sell,
  .m2y-header__actions .m2y-header__account,
  .m2y-header__actions .m2y-theme-toggle {
    display: none;
  }
  .m2y-header__actions { margin-left: 0; }
  .m2y-header__hamburger { display: inline-flex; }
  .m2y-header__mobile-search { display: block; }
  .m2y-header__overlay { display: block; }
  .m2y-header__drawer { display: block; }
}

/* Smooth drawer slide, gated behind no-preference for reduced-motion */
@media (prefers-reduced-motion: no-preference) {
  .m2y-header__drawer { transition: transform 220ms ease; }
  .m2y-header__overlay { transition: opacity 220ms ease; }
}


/* ----------------------------------------------------------------
   footer
   POPIA cookie consent banner. Hidden by default; JS reveals it by
   adding .is-shown when the consent cookie is absent. Replaces the
   inline styles that previously lived on the banner markup.
   ---------------------------------------------------------------- */
.m2y-cookie {
  display: none;
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 9999;
  padding: 16px;
  justify-content: center;
}
.m2y-cookie.is-shown {
  display: flex;
}
.m2y-cookie__card {
  background: var(--paper);
  max-width: 600px;
  width: 100%;
  margin: 0 auto;
  border-radius: 16px;
  box-shadow: 0 4px 24px rgba(0, 0, 0, 0.15);
  padding: 24px 28px;
  font-family: var(--font-body);
  font-size: 0.95rem;
  color: var(--ink-700);
  line-height: 1.5;
}
.m2y-cookie__text {
  margin: 0 0 16px 0;
}
.m2y-cookie__link {
  color: var(--brand-orange);
  text-decoration: underline;
}
.m2y-cookie__actions {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.m2y-cookie__accept {
  /* Darker on-brand orange so white text clears 4.5:1 contrast. */
  background: #B65F0A;
  color: #fff;
  border: none;
  border-radius: 8px;
  padding: 10px 28px;
  font-family: var(--font-body);
  font-size: 0.95rem;
  font-weight: 700;
  cursor: pointer;
  transition: background 0.15s ease;
}
.m2y-cookie__more {
  color: var(--brand-orange);
  font-size: 0.9rem;
  text-decoration: underline;
}

/* ----------------------------------------------------------------
   PWA install prompt. Hidden by default; site.js adds .is-shown when
   the browser fires beforeinstallprompt and the user has not already
   dismissed it. On-brand orange accent and Quicksand display face to
   match the rest of the chrome. CSP-safe: visibility is class-driven,
   never an inline style attribute.
   ---------------------------------------------------------------- */
.m2y-pwa-install {
  display: none;
  position: fixed;
  bottom: 16px;
  left: 0;
  right: 0;
  z-index: 9998;
  padding: 0 16px;
  justify-content: center;
}
.m2y-pwa-install.is-shown {
  display: flex;
}
.m2y-pwa-install__card {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  background: var(--paper);
  max-width: 520px;
  width: 100%;
  border-radius: 16px;
  border: var(--border-brand);
  box-shadow: 0 6px 28px rgba(0, 0, 0, 0.16);
  padding: 14px 18px;
}
.m2y-pwa-install__icon {
  flex-shrink: 0;
  width: 40px;
  height: 40px;
  border-radius: 10px;
}
.m2y-pwa-install__text {
  flex: 1 1 180px;
  margin: 0;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.95rem;
  line-height: 1.35;
  color: var(--ink-700);
}
.m2y-pwa-install__actions {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.m2y-pwa-install__accept {
  background: #B65F0A;
  color: #fff;
  border: none;
  border-radius: 8px;
  padding: 10px 18px;
  font-family: var(--font-display);
  font-size: 0.9rem;
  font-weight: 700;
  cursor: pointer;
  transition: background 0.15s ease;
}
.m2y-pwa-install__accept:hover {
  background: var(--brand-orange-800);
}
.m2y-pwa-install__dismiss {
  background: none;
  border: none;
  color: var(--ink-500);
  font-family: var(--font-display);
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
  padding: 10px 6px;
}
.m2y-pwa-install__dismiss:hover {
  color: var(--ink-700);
}

/* Lift clear of the fixed mobile bottom nav (64px tall). */
@media (max-width: 768px) {
  .m2y-pwa-install {
    bottom: 76px;
  }
}

/* ================================================================
   Shared partial styles
   Moved here from inline <style> blocks in the shared includes,
   which are pulled into many pages, so the rules belong in the
   always-loaded site stylesheet rather than a per-page file.
   ================================================================ */

/* filter bar (from app/includes/_filter_bar.php) */
.m2y-filterbar {
  background: #fff;
  border-bottom: 1px solid #ECE3DA;
  padding: 10px 16px;
  position: sticky;
  top: 0;
  z-index: 50;
}
.m2y-filterbar__inner {
  display: flex;
  align-items: center;
  gap: 12px;
  max-width: 1400px;
  margin: 0 auto;
  flex-wrap: wrap;
}
.m2y-filterbar__chips {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 1 1 auto;
  flex-wrap: wrap;
  min-width: 0;
}
.m2y-filterbar__hint {
  color: #5A4F46;
  font-size: 13px;
}
.m2y-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: #FAF6EF;
  border: 1px solid #ECE3DA;
  color: #1F1A17;
  text-decoration: none;
  font-size: 13px;
  font-weight: 600;
  padding: 4px 10px;
  border-radius: 999px;
  line-height: 1.4;
  transition: background .12s ease, border-color .12s ease;
}
.m2y-chip:hover { background: #F1E8DC; border-color: #D9CABA; color: #1F1A17; }
.m2y-chip__x { color: #9A5309; font-weight: 800; }
.m2y-filterbar__clear {
  color: #9A5309;
  font-weight: 700;
  font-size: 13px;
  text-decoration: none;
  margin-left: 4px;
}
.m2y-filterbar__clear:hover { text-decoration: underline; }
.m2y-filterbar__sort {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 0 0 auto;
}
.m2y-filterbar__sort-label {
  font-size: 12px;
  font-weight: 700;
  color: #6B5E55;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin: 0;
}
.m2y-filterbar__count {
  font-size: 13px;
  color: #6B5E55;
  margin-right: 4px;
}
.m2y-filterbar__sort-select {
  height: 36px;
  padding: 0 30px 0 12px;
  border: 1px solid #ECE3DA;
  border-radius: 8px;
  background: #fff;
  font-size: 14px;
  color: #1F1A17;
  font-family: inherit;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236B5E55' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
  background-repeat: no-repeat;
  background-position: right 10px center;
}
.m2y-filterbar__sort-select:focus {
  outline: none;
  border-color: #9A5309;
  box-shadow: 0 0 0 3px rgba(154,83,9,0.15);
}
.m2y-filterbar__go {
  height: 36px;
  padding: 0 14px;
  background: #9A5309;
  color: #fff;
  border: 0;
  border-radius: 8px;
  font-weight: 700;
  cursor: pointer;
}
/* visually hidden but keyboard-reachable - keeps the form submittable without JS */
.m2y-visually-hidden {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
.m2y-visually-hidden:focus,
.m2y-visually-hidden:focus-visible {
  position: static !important;
  width: auto;
  height: auto;
  clip: auto;
  margin: 0 0 0 6px;
}

@media (max-width: 575.98px) {
  .m2y-filterbar { padding: 8px 12px; }
  .m2y-filterbar__inner { gap: 8px; }
  .m2y-filterbar__sort { width: 100%; justify-content: flex-end; }
  .m2y-filterbar__sort-select { font-size: 13px; }
}

/* social bar (from app/includes/_social_bar.php) */
.m2y-socialbar{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.m2y-socialbar__form{margin:0}
.m2y-socialbar__btn{display:inline-flex;align-items:center;gap:6px;padding:8px 12px;min-height:40px;
  border:1px solid var(--ink-200,#E5DED5);background:var(--paper,#fff);color:var(--ink-700,#4A4034);
  border-radius:999px;font-size:13px;font-weight:600;cursor:pointer;text-decoration:none;line-height:1}
.m2y-socialbar__btn:hover{border-color:var(--brand-orange,#F89A1F)}
.m2y-socialbar__btn.is-on{background:var(--brand-orange,#F89A1F);color:#fff;border-color:var(--brand-orange,#F89A1F)}
.m2y-socialbar__count{font-variant-numeric:tabular-nums;opacity:.85}
@media (max-width:480px){.m2y-socialbar__label{display:none}}

/* admin nav (from app/admin/_nav.php) */
.admin-shell {
  display: grid;
  grid-template-columns: 250px 1fr;
  gap: 0;
  min-height: calc(100vh - 130px);
}
.admin-side {
  background: #1F1A17;
  padding: 0;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: rgba(255,255,255,0.15) transparent;
  z-index: 100;
}
.admin-side::-webkit-scrollbar { width: 4px; }
.admin-side::-webkit-scrollbar-track { background: transparent; }
.admin-side::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.15); border-radius: 2px; }
.admin-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 20px 20px 16px;
  border-bottom: 1px solid rgba(255,255,255,0.08);
  margin-bottom: 8px;
}
.admin-brand img {
  width: 32px;
  height: 32px;
  object-fit: contain;
}
.admin-brand-text {
  font-family: 'Quicksand', sans-serif;
  font-weight: 700;
  font-size: 1.15rem;
  color: #fff;
  line-height: 1;
}
.admin-brand-badge {
  display: inline-block;
  background: #F89A1F;
  color: #fff;
  font-family: 'Nunito', sans-serif;
  font-size: 0.6rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  padding: 2px 7px;
  border-radius: 4px;
  margin-left: 2px;
  vertical-align: middle;
}
.admin-group {
  font-family: 'Nunito', sans-serif;
  font-size: 0.65rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: rgba(255,255,255,0.35);
  padding: 20px 20px 6px;
  margin: 0;
}
.admin-side a.admin-link {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 20px;
  color: rgba(255,255,255,0.65);
  font-family: 'Nunito', sans-serif;
  font-size: 0.88rem;
  font-weight: 600;
  text-decoration: none;
  border-left: 3px solid transparent;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
  position: relative;
}
.admin-side a.admin-link:hover {
  background: rgba(255,255,255,0.06);
  color: rgba(255,255,255,0.9);
}
.admin-side a.admin-link.active {
  background: rgba(248,154,31,0.1);
  color: #F89A1F;
  border-left-color: #F89A1F;
}
.admin-side a.admin-link svg {
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  opacity: 0.6;
  transition: opacity 0.15s ease;
}
.admin-side a.admin-link:hover svg,
.admin-side a.admin-link.active svg {
  opacity: 1;
}
.admin-link .admin-link-label {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.admin-main {
  padding: 32px 40px;
  background: #F5F3F0;
  min-height: 100vh;
}
.admin-toggle {
  display: none;
  position: fixed;
  top: 12px;
  left: 12px;
  z-index: 1060;
  background: #1F1A17;
  color: #fff;
  border: none;
  border-radius: 8px;
  padding: 8px 10px;
  cursor: pointer;
  box-shadow: 0 2px 8px rgba(0,0,0,0.3);
  line-height: 1;
}
.admin-toggle svg {
  display: block;
}
.admin-overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.5);
  z-index: 99;
}
.admin-overlay.visible {
  display: block;
}
@media (min-width: 769px) and (max-width: 1024px) {
  .admin-shell {
    grid-template-columns: 64px 1fr;
  }
  .admin-side {
    overflow: visible;
  }
  .admin-brand-text,
  .admin-brand-badge,
  .admin-group,
  .admin-link .admin-link-label {
    display: none;
  }
  .admin-brand {
    justify-content: center;
    padding: 16px 0;
  }
  .admin-side a.admin-link {
    justify-content: center;
    padding: 12px 0;
    border-left: none;
    border-right: 3px solid transparent;
    gap: 0;
  }
  .admin-side a.admin-link.active {
    border-left-color: transparent;
    border-right-color: #F89A1F;
  }
  .admin-side a.admin-link::after {
    content: attr(data-label);
    position: absolute;
    left: 100%;
    top: 50%;
    transform: translateY(-50%);
    background: #1F1A17;
    color: #fff;
    font-size: 0.78rem;
    padding: 4px 10px;
    border-radius: 6px;
    white-space: nowrap;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.15s ease;
    margin-left: 8px;
    z-index: 200;
    box-shadow: 0 2px 8px rgba(0,0,0,0.3);
  }
  .admin-side a.admin-link:hover::after {
    opacity: 1;
  }
  .admin-main {
    padding: 24px 20px;
  }
}
@media (max-width: 768px) {
  .admin-shell {
    grid-template-columns: 1fr;
  }
  .admin-side {
    position: fixed;
    top: 0;
    left: -260px;
    width: 250px;
    height: 100vh;
    transition: left 0.25s ease;
    z-index: 1050;
  }
  .admin-side.open {
    left: 0;
  }
  .admin-toggle {
    display: block;
  }
  .admin-main {
    padding: 20px 16px;
    padding-top: 56px;
  }
}

/* The header account button is a fixed circle, so its avatar fills it. This is
   scoped to the header only - elsewhere the avatar uses its own width/height. */
.m2y-header__avatar { padding: 0; overflow: hidden; }
.m2y-header__avatar .m2y-avatar { width: 100%; height: 100%; border: 0; box-shadow: none; }

/* ================================================================
   SA address autocomplete (data-m2y-address). Reusable across the
   checkout, listing create, and driver register address fields.
   ================================================================ */
.m2y-ac-wrap { position: relative; }
.m2y-ac-list {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 1200;
  margin-top: 4px;
  background: var(--surface, #fff);
  border: 1px solid var(--border-subtle, #E7DFD4);
  border-radius: 10px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
  overflow: hidden;
  max-height: 280px;
  overflow-y: auto;
}
.m2y-ac-item {
  padding: 10px 12px;
  font-size: 14px;
  line-height: 1.35;
  color: var(--ink-900, #1F1A17);
  cursor: pointer;
  border-bottom: 1px solid var(--border-subtle, #F0EAE0);
}
.m2y-ac-item:last-child { border-bottom: none; }
.m2y-ac-item:hover,
.m2y-ac-item.is-active {
  background: var(--brand-orange-50, #FFF6E9);
  color: var(--brand-orange-800, #9A5309);
}

/* Small inline map used beside an address field (listing create). */
.m2y-ac-map {
  width: 100%;
  height: 220px;
  border-radius: 12px;
  overflow: hidden;
  border: 1px solid var(--border-subtle, #E7DFD4);
  margin-top: 8px;
}

/* ================================================================
   Country picker (pickers.js enhances [data-m2y-country] selects on
   register + profile). The script keeps the native <select> in the
   DOM so its value still submits, then renders a styled trigger and a
   searchable panel. Without these rules the native select and the
   trigger both showed - the source of the "duplicate country" control.
   ================================================================ */
.m2y-country { position: relative; }
.m2y-country__native { display: none; }
.m2y-country__trigger {
  width: 100%;
  text-align: left;
  cursor: pointer;
  background-color: #fff;
}
.m2y-country__panel {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  z-index: 1200;
  background: var(--surface, #fff);
  border: 1px solid var(--border-subtle, #E7DFD4);
  border-radius: 10px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
  padding: 8px;
  max-height: 280px;
  overflow-y: auto;
}
.m2y-country__panel[hidden] { display: none; }
.m2y-country__search { width: 100%; margin-bottom: 8px; }
.m2y-country__list { display: flex; flex-direction: column; }
.m2y-country__item {
  padding: 9px 11px;
  border-radius: 8px;
  font-size: 14px;
  line-height: 1.35;
  color: var(--ink-900, #1F1A17);
  cursor: pointer;
}
.m2y-country__item:hover,
.m2y-country__item.is-active,
.m2y-country__item[aria-selected="true"] {
  background: var(--brand-orange-50, #FFF6E9);
  color: var(--brand-orange-800, #9A5309);
}


/* ----------------------------------------------------------------
   FOOTER + MOBILE BOTTOM NAV
   Moved here verbatim from the inline <style> block that used to
   live in includes/footer.php. Kept at the end of the file so these
   authoritative values win the cascade over the earlier partial
   footer rules in section 13 and render identically.
   ---------------------------------------------------------------- */
.m2y-foot {
  background: #1F1A17;
  color: #d6cfbf;
  padding: 48px 0 28px;
  margin-top: 56px;
  font-size: 13px;
  font-family: 'Nunito', sans-serif;
  line-height: 1.6;
}

/* Column headings */
.m2y-foot__heading {
  color: #fff;
  font-family: 'Quicksand', sans-serif;
  font-weight: 700;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  margin-bottom: 14px;
}

/* Link lists */
.m2y-foot__links li {
  margin-bottom: 8px;
}
.m2y-foot__links a {
  color: #d6cfbf;
  font-size: 13px;
  text-decoration: none;
  border-bottom: none;
  transition: color 0.15s ease;
}
.m2y-foot__links a:hover,
.m2y-foot__links a:focus {
  color: #F89A1F;
  text-decoration: none;
}

/* Divider rules */
.m2y-foot__rule {
  border-color: #3a3530;
  margin: 28px 0 20px;
  opacity: 1;
}
.m2y-foot__rule--subtle {
  border-color: #2e2925;
  margin: 20px 0 16px;
}

/* Brand bar */
.m2y-foot__brand-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
  margin-bottom: 4px;
}
.m2y-foot__brand-left {
  display: flex;
  align-items: center;
  gap: 10px;
}
.m2y-foot__brand {
  color: #fff;
  font-family: 'Quicksand', sans-serif;
  font-weight: 700;
  font-size: 20px;
  letter-spacing: -0.01em;
}
.m2y-foot__tagline {
  color: #a69d90;
  font-size: 12px;
  margin: 0;
  font-style: italic;
}

/* Payments + social row */
.m2y-foot__extras {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 16px;
  margin-top: 12px;
}
.m2y-foot__payments {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.m2y-foot__pay-label {
  color: #a69d90;
  font-size: 12px;
}
.m2y-foot__badges {
  display: flex;
  align-items: center;
  gap: 6px;
}
.m2y-foot__badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 4px;
  overflow: hidden;
  line-height: 1;
}
.m2y-foot__badge svg {
  display: block;
}
.m2y-foot__badge--text {
  background: #fff;
  color: #1F1A17;
  font-size: 10px;
  font-weight: 700;
  font-family: 'Nunito', sans-serif;
  padding: 4px 8px;
  border-radius: 4px;
  height: 24px;
  min-width: 38px;
  letter-spacing: 0.04em;
}
/* EFT chip: a bank glyph plus the EFT label, sized to match the 38x24
   card chips so the payments row reads as one consistent set. */
.m2y-foot__badge--eft {
  gap: 5px;
  background: #fff;
  height: 24px;
  min-width: 38px;
  padding: 0 8px;
  border-radius: 4px;
}
.m2y-foot__eft-label {
  color: #1F1A17;
  font-family: 'Nunito', sans-serif;
  font-weight: 700;
  font-size: 10px;
  letter-spacing: 0.04em;
  line-height: 1;
}

/* Social links */
.m2y-foot__social {
  display: flex;
  align-items: center;
  gap: 12px;
}
.m2y-foot__social-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: #2e2925;
  color: #d6cfbf;
  text-decoration: none;
  border-bottom: none;
  transition: background 0.15s ease, color 0.15s ease;
}
.m2y-foot__social-link:hover,
.m2y-foot__social-link:focus {
  background: #F89A1F;
  color: #fff;
  text-decoration: none;
}

/* Copyright bar */
.m2y-foot__copyright {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px;
  font-size: 12px;
  color: #a69d90;
}
.m2y-foot__sa {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.m2y-foot__flag {
  vertical-align: middle;
}

/* Mobile bottom nav */
.m2y-bnav {
  display: none;
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 1050;
  background: #fff;
  border-top: 1px solid #e8e2da;
  padding: 6px 0 calc(6px + env(safe-area-inset-bottom, 0px));
  justify-content: space-around;
  align-items: center;
  box-shadow: 0 -2px 12px rgba(0,0,0,0.06);
}

.m2y-bnav a {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  text-decoration: none;
  color: #8a8279;
  font-size: 0.65rem;
  font-family: 'Nunito', sans-serif;
  font-weight: 600;
  padding: 4px 8px;
  border-radius: 8px;
  transition: color 0.15s ease;
  min-width: 48px;
  min-height: 44px;
  justify-content: center;
  position: relative;
}

.m2y-bnav a:hover {
  color: #F89A1F;
}

.m2y-bnav a.active {
  color: #F89A1F;
}

.m2y-bnav a.active svg {
  stroke: #F89A1F;
}

/* Active dot indicator */
.m2y-bnav a.active::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: #F89A1F;
}

@media (max-width: 768px) {
  .m2y-bnav {
    display: flex;
  }
  .m2y-foot {
    padding-bottom: 96px;
  }
}

/* Small mobile tweaks */
@media (max-width: 575.98px) {
  .m2y-foot {
    padding: 32px 0 96px;
  }
  .m2y-foot__heading {
    margin-bottom: 10px;
  }
  .m2y-foot__brand-bar {
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
  }
  .m2y-foot__extras {
    flex-direction: column;
    align-items: flex-start;
  }
  .m2y-foot__copyright {
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
  }
}

/* Inline @handle tag - shown beside a user's name in the feed, follower
   lists, community posts/comments and reviews. Quieter than .shop-handle
   (which is the larger profile-header version) and links to /@handle. */
.m2y-handle {
  font-family: var(--font-mono, monospace);
  font-size: 0.85em;
  color: var(--ink-500, #6B5E55);
  text-decoration: none;
}
.m2y-handle:hover {
  text-decoration: underline;
}

/* Footer trust marks: official Payfast payment-method logos on white chips,
   and the official SA flag. Sizing lives here (not inline) so the page CSP
   style-src can stay free of unsafe-inline. */
.m2y-foot__badges { gap: 6px; align-items: center; }
.m2y-foot__badge { padding: 3px 6px; display: inline-flex; align-items: center; }
.m2y-foot__pay-img { height: 13px; width: auto; max-width: 56px; max-height: 16px; object-fit: contain; display: block; }
.m2y-foot__badge--eft { font-size: 11px; font-weight: 700; letter-spacing: 0.02em; }
.m2y-foot__badge--wide { padding-left: 6px; padding-right: 6px; }
.m2y-foot__flag-img { height: 12px; width: auto; border-radius: 2px; vertical-align: -1px; display: inline-block; }

/* Admin page titles stay readable on the dark admin surface in dark mode
   (most admin pages lacked a dark heading override, so the titles read faint). */
[data-theme="dark"] .admin-main h1,
[data-theme="dark"] .admin-main h2,
[data-theme="dark"] .admin-header h1,
[data-theme="dark"] .dash-header h1,
[data-theme="dark"] .admin-users-title,
[data-theme="dark"] .dispute-detail-title,
[data-theme="dark"] .order-detail-title {
  color: var(--ink-900);
}
