:root,
[data-theme="light"] {
  --brand-blue: #be185d;
  --brand-blue-rgb: 190, 24, 93;
  --brand-blue-dark: #831843;
  --brand-blue-dark-rgb: 131, 24, 67;
  --brand-black: #0f0f0f;
  --brand-gradient: var(--brand-blue);
  --brand-gradient-soft: linear-gradient(
    135deg,
    rgba(var(--brand-blue-rgb), 0.12),
    rgba(var(--brand-blue-rgb), 0.12)
  );

  /* Neutrals carry a faint rose/mauve tint so surfaces sit with the brand
     colour. They were sage-green-leaning when the brand was emerald -
     against magenta that read as a colour clash. */
  --vd-bg: #faf7f8;
  --vd-surface: #ffffff;
  --vd-surface-2: #f3eef0;
  --vd-surface-3: #e9e1e4;
  --vd-border: #e3dadf;
  --vd-text: #201619;
  --vd-text-muted: #74656c;
  --vd-shadow: 0 0.5rem 1.5rem rgba(35, 15, 24, 0.08);
  --vd-shadow-sm: 0 0.25rem 0.5rem rgba(35, 15, 24, 0.06);
  --vd-shadow-lg: 0 1.5rem 3rem rgba(35, 15, 24, 0.12);
  --vd-navbar-bg: rgba(255, 255, 255, 0.85);
  --vd-code-bg: #f3eef0;

  /* Corner radii. These used to be Bootstrap's --bs-border-radius-* so its
     components picked up our rounding; Bootstrap is gone, so they are plain
     project tokens now. The rest of the old --bs-* bridge (link colours,
     body bg, focus ring, button API...) existed only to re-skin Bootstrap
     and was deleted with it - nothing reads those any more. */
  --vd-radius: 0.65rem;
  --vd-radius-sm: 0.45rem;
  --vd-radius-lg: 0.9rem;
  --vd-radius-xl: 1.25rem;

  --vd-success: #22c55e;
}

[data-theme="dark"] {
  /* Rose-neutral dark counterparts to the light tokens above. */
  --vd-bg: #0f0b0d;
  --vd-surface: #1a1316;
  --vd-surface-2: #241a1f;
  --vd-surface-3: #2f2228;
  --vd-border: #3a2a31;
  --vd-text: #f5eef1;
  --vd-text-muted: #ab97a1;
  --vd-shadow: 0 0.5rem 1.5rem rgba(0, 0, 0, 0.5);
  --vd-shadow-sm: 0 0.25rem 0.5rem rgba(0, 0, 0, 0.4);
  --vd-shadow-lg: 0 1.5rem 3rem rgba(0, 0, 0, 0.55);
  --vd-navbar-bg: rgba(15, 11, 13, 0.8);
  --vd-code-bg: #241a1f;
}
.text-white {
  color: rgba(255, 255, 255, 255) !important;
}
/* ---------- Base ---------- */
html {
  scroll-behavior: smooth;
}

body {
  font-family:
    "Inter",
    -apple-system,
    BlinkMacSystemFont,
    "Segoe UI",
    Roboto,
    Helvetica,
    Arial,
    sans-serif;
  /* Background/colour/base metrics used to come from Bootstrap's reboot
     (via --bs-body-bg / --bs-body-color). Bootstrap is gone, so set them
     here - the admin <body> carries no Tailwind classes and would otherwise
     render on transparent white in dark mode. */
  background-color: var(--vd-bg);
  color: var(--vd-text);
  font-size: 1rem;
  line-height: 1.5;
  letter-spacing: -0.01px;
  transition:
    background-color 0.2s ease,
    color 0.2s ease;
}

/* Heading scale. Bootstrap used to size headings and also shipped .h1-.h6
   helper classes (admin markup uses e.g. <h1 class="h3">). Tailwind's
   preflight resets headings to inherit, so with Bootstrap gone these have
   to be declared here or every admin heading renders at body size.
   Tailwind text-* utilities still override these, being !important. */
h1,
h2,
h3,
h4,
h5,
h6,
.h1,
.h2,
.h3,
.h4,
.h5,
.h6,
.fw-display {
  font-weight: 700;
  letter-spacing: -0.02em;
  margin-top: 0;
}

/* `html` prefix required: Tailwind's preflight sets `h1..h6 { font-size:
   inherit }` and its <style> is injected after this file, so a bare element
   selector would tie on specificity and lose on source order - leaving every
   <h5>/<h6> at body size. The .hN class forms already outrank preflight. */
html h1,
.h1 {
  font-size: 2.25rem;
  line-height: 1.2;
}
html h2,
.h2 {
  font-size: 1.8rem;
  line-height: 1.25;
}
html h3,
.h3 {
  font-size: 1.5rem;
  line-height: 1.3;
}
html h4,
.h4 {
  font-size: 1.25rem;
  line-height: 1.35;
}
html h5,
.h5 {
  font-size: 1.1rem;
  line-height: 1.4;
}
html h6,
.h6 {
  font-size: 0.95rem;
  line-height: 1.4;
}

code,
pre,
kbd {
  background-color: var(--vd-code-bg);
}

::selection {
  background: rgba(var(--brand-blue-rgb), 0.25);
}

a {
  text-decoration: none;
}
.text-muted-2 {
  color: var(--vd-text-muted) !important;
}

.container-xl-page {
  max-width: 1320px;
}

/* ---------- Utilities ---------- */
.bg-brand-gradient {
  background: var(--brand-gradient) !important;
  color: #fff !important;
}
.bg-vd-surface {
  background-color: var(--vd-surface) !important;
}
.bg-vd-surface-2 {
  background-color: var(--vd-surface-2) !important;
}
.text-gradient {
  background: var(--brand-gradient);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.shadow-vd {
  box-shadow: var(--vd-shadow) !important;
}
.shadow-vd-sm {
  box-shadow: var(--vd-shadow-sm) !important;
}
.shadow-vd-lg {
  box-shadow: var(--vd-shadow-lg) !important;
}
.rounded-vd {
  border-radius: var(--vd-radius-lg) !important;
}
.rounded-vd-xl {
  border-radius: var(--vd-radius-xl) !important;
}
.section-py {
  padding-block: clamp(3rem, 6vw, 6rem);
}
.section-py-sm {
  padding-block: clamp(2rem, 4vw, 3.5rem);
}
.hover-lift {
  transition:
    transform 0.2s ease,
    box-shadow 0.2s ease;
}
.hover-lift:hover {
  transform: translateY(-4px);
  box-shadow: var(--vd-shadow-lg);
}
.chip-scroll {
  display: flex;
  gap: 0.5rem;
  overflow-x: auto;
  scrollbar-width: thin;
  padding-bottom: 0.25rem;
}
.chip-scroll::-webkit-scrollbar {
  height: 6px;
}
.chip-scroll::-webkit-scrollbar-thumb {
  background: var(--vd-border);
  border-radius: 3px;
}
.divider-label {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  color: var(--vd-text-muted);
  font-size: 0.85rem;
}
.divider-label::before,
.divider-label::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--vd-border);
}
.skeleton {
  background: linear-gradient(
    90deg,
    var(--vd-surface-2) 25%,
    var(--vd-surface-3) 37%,
    var(--vd-surface-2) 63%
  );
  background-size: 400% 100%;
  animation: vd-skel 1.4s ease infinite;
  border-radius: var(--vd-radius);
}
@keyframes vd-skel {
  0% {
    background-position: 100% 50%;
  }
  100% {
    background-position: 0 50%;
  }
}
[data-reveal] {
  opacity: 0;
  transform: translateY(16px);
  transition:
    opacity 0.5s ease,
    transform 0.5s ease;
}
[data-reveal].is-visible {
  opacity: 1;
  transform: none;
}

/* ---------- Buttons ---------- */
.btn {
  font-weight: 600;
  border-radius: var(--vd-radius);
  box-shadow: none;
}
.btn:focus,
.btn:focus-visible,
.btn.focus,
.btn-check:focus + .btn {
  box-shadow: none;
  outline: none;
}
.btn-lg {
  border-radius: var(--vd-radius-lg);
}
.btn-primary {
}
.btn-gradient {
  background: var(--brand-gradient);
  border: none;
  color: #fff;
}
.btn-gradient:hover {
  color: #fff;
  filter: brightness(1.08);
}
.btn-outline-primary {
}
.btn-dark {
}
.btn-icon {
  width: 2.5rem;
  height: 2.5rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border-radius: 50%;
}
.btn-check:checked + .btn-outline-primary,
.btn-outline-primary.active {
  color: #fff;
}

/* ---------- Forms ---------- */
.form-control,
.form-select {
  background-color: var(--vd-surface);
  border-color: var(--vd-border);
  color: var(--vd-text);
  border-radius: var(--vd-radius);
  padding-block: 0.6rem;
}
.form-control:focus,
.form-select:focus {
  background-color: var(--vd-surface);
  color: var(--vd-text);
  border-color: var(--brand-blue);
  box-shadow: 0 0 0 0.25rem rgba(var(--brand-blue-rgb), 0.18);
}
.form-control::placeholder {
  color: var(--vd-text-muted);
  opacity: 0.8;
}
.input-group-text {
  background-color: var(--vd-surface-2);
  border-color: var(--vd-border);
  color: var(--vd-text-muted);
}
.form-check-input:checked {
  background-color: var(--brand-blue);
  border-color: var(--brand-blue);
}
.form-check-input:focus {
  box-shadow: 0 0 0 0.2rem rgba(var(--brand-blue-rgb), 0.18);
}
.form-switch .form-check-input:checked {
  background-color: var(--brand-blue);
}
.form-range::-webkit-slider-thumb {
  background: var(--brand-blue);
}
.form-floating > label {
  color: var(--vd-text-muted);
}

/* upload dropzone */
.upload-dropzone {
  border: 2px dashed var(--vd-border);
  border-radius: var(--vd-radius-lg);
  background: var(--vd-surface-2);
  text-align: center;
  padding: 2rem 1rem;
  cursor: pointer;
  transition:
    border-color 0.15s ease,
    background-color 0.15s ease;
}
.upload-dropzone:hover,
.upload-dropzone.is-dragover {
  border-color: var(--brand-blue);
  background: rgba(var(--brand-blue-rgb), 0.06);
}
.upload-dropzone .bi {
  font-size: 2rem;
  color: var(--brand-blue);
}
.upload-thumb {
  position: relative;
  width: 100%;
  aspect-ratio: 1;
  border-radius: var(--vd-radius);
  overflow: hidden;
  border: 1px solid var(--vd-border);
  background: var(--vd-surface-2);
}
.upload-thumb .remove-btn {
  position: absolute;
  top: 0.25rem;
  right: 0.25rem;
}
.upload-thumb .drag-handle {
  position: absolute;
  top: 0.25rem;
  left: 0.25rem;
  width: 1.75rem;
  height: 1.75rem;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.55);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: grab;
}
.upload-thumb.sortable-ghost {
  opacity: 0.4;
}

/* ---------- Navbar ---------- */
.vd-navbar {
  background: var(--vd-navbar-bg);
  backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--vd-border);
}
.vd-navbar .navbar-brand {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  font-weight: 800;
  font-size: 1.25rem;
  color: var(--vd-text) !important;
}
.vd-navbar .navbar-brand img {
  height: 34px;
  width: 34px;
  object-fit: contain;
}
.vd-navbar .nav-link {
  font-weight: 600;
  color: var(--vd-text) !important;
  padding: 0.5rem 0.9rem !important;
  border-radius: var(--vd-radius-sm);
}
.vd-navbar .nav-link.active {
  color: var(--brand-blue) !important;
}
.vd-navbar .nav-link:hover {
  background: var(--vd-surface-2);
}
.theme-toggle-btn {
  border: 1px solid var(--vd-border);
  background: var(--vd-surface);
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--vd-text);
}
.theme-toggle-btn .fa-moon {
  display: none;
}
[data-theme="dark"] .theme-toggle-btn .fa-sun {
  display: none;
}
[data-theme="dark"] .theme-toggle-btn .fa-moon {
  display: inline-block;
}
.cart-badge-btn {
  position: relative;
}
.cart-badge-btn .badge {
  position: absolute;
  top: -4px;
  right: -6px;
  font-size: 0.6rem;
  padding: 0.25em 0.45em;
}
.search-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  z-index: 1080;
  display: none;
}
.search-overlay.show {
  display: block;
}
.search-overlay .search-panel {
  max-width: 720px;
  margin: 8vh auto 0;
}

/* ---------- Cards / Product ---------- */
.vd-card {
  background: var(--vd-surface);
  border: 1px solid var(--vd-border);
  border-radius: var(--vd-radius-lg);
}
/* Payment methods: selector tiles side by side from sm up, stacked below
   that. Flex rather than a 3-column grid so a tile hidden for ineligibility
   (Card / Apple Pay) lets the remaining ones expand instead of leaving a hole
   in the row. */
.payment-method-row {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin-bottom: 1.25rem;
}
@media (min-width: 640px) {
  .payment-method-row {
    flex-direction: row;
  }
  .payment-method-row > .payment-option-card {
    flex: 1 1 0;
    min-width: 0;
  }
}
.payment-option-card {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin: 0;
  padding: 0.9rem 1rem;
  cursor: pointer;
  border: 1px solid var(--vd-border) !important;
  border-radius: var(--vd-radius, 0.75rem);
  background: var(--vd-surface);
  transition:
    border-color 0.15s ease,
    background-color 0.15s ease;
}
.payment-option-card:hover {
  border-color: color-mix(
    in srgb,
    var(--brand-blue) 45%,
    var(--vd-border)
  ) !important;
}
.payment-option-card:has(.payment-option-radio:checked) {
  border-color: var(--brand-blue) !important;
  background-color: color-mix(in srgb, var(--brand-blue) 6%, var(--vd-surface));
}
/* Keyboard focus lands on the radio inside, so lift the ring to the whole
   tile - otherwise tabbing through leaves no visible target. */
.payment-option-card:focus-within {
  outline: 2px solid color-mix(in srgb, var(--brand-blue) 55%, transparent);
  outline-offset: 2px;
}
.payment-option-body {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-width: 0;
  flex: 1 1 auto;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--vd-text);
}
.payment-option-icon {
  font-size: 1.15rem;
  color: var(--brand-blue);
}
.payment-option-name {
  white-space: nowrap;
}
.payment-option-radio {
  width: 1.05rem;
  height: 1.05rem;
  flex: 0 0 auto;
  cursor: pointer;
}
.card-brand-icons-img {
  height: 18px;
  width: auto;
  margin-left: auto;
  /* Decoration, not content - never let the brand strip push the tile wider
     than its share of the row. */
  min-width: 0;
  max-width: 100%;
  object-fit: contain;
}
.checkout-step-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.6rem;
  height: 1.6rem;
  border-radius: 50%;
  background: var(--brand-gradient);
  color: #fff;
  font-size: 0.8rem;
  margin-right: 0.5rem;
}
.checkout-progress {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.checkout-progress-step {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--vd-text-muted);
  white-space: nowrap;
}
.checkout-progress-step.is-active,
.checkout-progress-step.is-done {
  color: var(--vd-text);
}
.checkout-progress-dot {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.6rem;
  height: 1.6rem;
  border-radius: 50%;
  border: 1px solid var(--vd-border);
  font-size: 0.75rem;
  color: var(--vd-text-muted);
}
.checkout-progress-step.is-active .checkout-progress-dot {
  background: var(--brand-gradient);
  border-color: transparent;
  color: #fff;
}
.checkout-progress-step.is-done .checkout-progress-dot {
  background: var(--vd-success);
  border-color: transparent;
  color: #fff;
}
.checkout-progress-line {
  flex: 1 1 auto;
  height: 2px;
  background: var(--vd-border);
  min-width: 1.5rem;
}
.checkout-progress-line.is-done {
  background: var(--vd-success);
}
/* ---------- Order Summary card (cart / checkout / confirmation) ----------
   One component in three places, so a change to the total row or the trust
   strip lands on all of them instead of drifting apart. */
.summary-card {
  border: 1px solid var(--vd-border);
  border-radius: var(--vd-radius-lg, 1rem);
  background: var(--vd-surface);
  overflow: hidden;
  box-shadow: 0 1px 2px rgb(0 0 0 / 0.04);
}
.summary-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.9rem 1.25rem;
  border-bottom: 1px solid var(--vd-border);
  /* Tinted rather than plain: gives the card a head that reads as a header
     without a heavy filled bar shouting over the totals underneath. */
  background: color-mix(in srgb, var(--brand-blue) 5%, var(--vd-surface));
}
.summary-count {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--vd-text-muted);
  white-space: nowrap;
}
.summary-card-body {
  padding: 1.25rem;
}
.summary-lines {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}
.summary-lines > div {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
}
.summary-lines dt {
  margin: 0;
  font-weight: 400;
  color: var(--vd-text-muted);
}
.summary-lines dd {
  margin: 0;
  font-weight: 600;
  color: var(--vd-text);
  /* Tabular figures keep the decimal points aligned down the column as the
     amounts change - proportional digits make them visibly jitter. */
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.summary-line-save dt,
.summary-line-save dd,
.summary-free {
  color: var(--vd-success, #16a34a) !important;
}
.summary-total {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 1rem;
  padding: 0.9rem 1rem;
  border-radius: var(--vd-radius, 0.75rem);
  border: 1px solid color-mix(in srgb, var(--brand-blue) 25%, transparent);
  background: color-mix(in srgb, var(--brand-blue) 7%, var(--vd-surface));
}
.summary-total-label {
  font-size: 0.95rem;
  font-weight: 700;
  color: var(--vd-text);
}
.summary-total-note {
  font-size: 0.72rem;
  color: var(--vd-text-muted);
}
.summary-total-value {
  font-size: 1.6rem;
  font-weight: 800;
  line-height: 1.1;
  color: var(--brand-blue);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.summary-coupon {
  margin-top: 1.25rem;
  padding-top: 1.25rem;
  border-top: 1px dashed var(--vd-border);
}
.summary-coupon-row {
  display: flex;
  gap: 0.5rem;
}
.checkout-total-divider {
  border-top: 1px dashed var(--vd-border);
  opacity: 1;
}
.checkout-trust-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 1rem;
  padding-top: 1rem;
  border-top: 1px solid var(--vd-border);
}
.checkout-trust-row span {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.72rem;
  color: var(--vd-text-muted);
}
.checkout-trust-row i {
  font-size: 0.85rem;
}
/* The real <input> inside Card Fields' iframe renders at its own intrinsic
   height (percentage heights don't cascade through PayPal's internal DOM,
   which we don't control) - forcing height:100% on style.input does nothing,
   so most of any container taller than that intrinsic ~15px text line just
   shows PayPal's own unstylable white iframe-body background. checkout.js's
   cardFieldStyles() now grows the input's own true box via vertical padding
   instead (~44px including padding) - size this container to match that,
   not to some arbitrary form-control height, or the leftover gap is white
   again. */
/* Matches the plain <input>s alongside these (border-line + bg-surface2), so
   the card form reads as one set of fields. Previously these carried no
   border and a --vd-surface background, which only stayed legible because
   they sat inside the tinted selected payment tile - once the fields moved
   into the shared panel below the selector row, field and container were the
   same colour and the boxes vanished. */
.hosted-field {
  position: relative;
  height: 46px;
  padding: 0 0.75rem;
  overflow: hidden;
  background-color: var(--vd-surface-2);
  border: 1px solid var(--vd-border);
  border-radius: var(--vd-radius);
  box-sizing: border-box;
  transition:
    border-color 0.15s ease,
    box-shadow 0.15s ease;
}
/* PayPal owns the focus state inside its iframe, so we can't :focus here -
   :focus-within still fires on the host element when focus enters the frame. */
.hosted-field:focus-within {
  border-color: var(--brand-blue);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--brand-blue) 20%, transparent);
}
/* PayPal renders a fixed ~12px decorative accent bar inset from each edge of
   the field, baked into their iframe's own internal layout - confirmed by
   direct testing it's not our border/outline/box-shadow (setting those to
   none had zero effect) and not a text caret (survived typing real text into
   the field), and unrelated to our input's own padding (increasing that
   moved the text but not the bar). Tried cropping it via widening+shifting
   the iframe (same trick as the vertical fix above, horizontal this time):
   a small shift does crop the LEFT bar with no side effects, but the RIGHT
   bar is anchored independently and staid put even at a much larger shift -
   and that larger shift started truncating real rendered text ("Name on
   card" -> "e on card", the card number's last 4 digits vanishing). That's
   not a cosmetic risk, it's a real one: a live typed card number could lose
   visible digits past the edge. Not worth it for a ~2px accent - reverted to
   plain 100%/100%, both bars present but nothing is ever at risk of being
   invisibly cropped off. */
.hosted-field > div[id^="zoid-paypal-card"] {
  width: calc(100% + 40px) !important;
  margin-left: -20px !important;
  height: 100% !important;
  background: transparent !important;
}
.hosted-field iframe {
  width: 100% !important;
  height: calc(100% + 7px) !important;
  margin-top: -7px !important;
  border: 0 !important;
  background: transparent !important;
}
.product-card {
  background: var(--vd-surface);
  border: 1px solid var(--vd-border);
  border-radius: var(--vd-radius-lg);
  overflow: hidden;
  height: 100%;
  display: flex;
  flex-direction: column;
  transition:
    transform 0.2s ease,
    box-shadow 0.2s ease,
    border-color 0.2s ease;
}
.product-card:hover {
  transform: translateY(-4px);
  box-shadow: var(--vd-shadow-lg);
  border-color: rgba(var(--brand-blue-rgb), 0.35);
}
.product-card .product-thumb {
  overflow: hidden;
  position: relative;
  background: var(--vd-surface-2);
}
.product-card .product-thumb img {
  width: 100%;
  height: auto;
  display: block;
  transition: transform 0.35s ease;
}
.product-card:hover .product-thumb img {
  transform: scale(1.05);
}
.product-card .product-body {
  padding: 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  flex: 1;
}
.product-card .product-price {
  font-weight: 800;
  font-size: 1.15rem;
  color: var(--vd-text);
}
.product-card .product-price .old-price {
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--vd-text-muted);
  text-decoration: line-through;
  margin-right: 0.35rem;
}
/* Unscoped base so .old-price also works outside product cards, e.g. the
   product detail page's price block. */
.old-price {
  color: var(--vd-text-muted);
  text-decoration: line-through;
  margin-right: 0.35rem;
  font-weight: 500;
}
.wishlist-btn {
  position: absolute;
  top: 0.6rem;
  right: 0.6rem;
  width: 2.1rem;
  height: 2.1rem;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.9);
  border: none;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--brand-black);
  z-index: 2;
}
[data-theme="dark"] .wishlist-btn {
  background: rgba(23, 24, 29, 0.85);
  color: #fff;
}
.wishlist-btn.active,
.wishlist-btn:hover {
  color: #ff3b6b;
}
.badge-corner {
  position: absolute;
  top: 0.6rem;
  left: 0.6rem;
  z-index: 2;
}

/* Icon-based, no product photography - a placeholder/stock image looked
   worse than no image at all across a grid of very different categories. */
.category-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  text-align: center;
  background: var(--vd-surface);
  border: 1px solid var(--vd-border);
  border-radius: var(--vd-radius-lg);
  padding: 1.75rem 1rem;
  height: 100%;
  transition:
    transform 0.2s ease,
    box-shadow 0.2s ease,
    border-color 0.2s ease;
}
.category-tile:hover {
  transform: translateY(-4px);
  box-shadow: var(--vd-shadow-lg);
  border-color: var(--brand-blue);
}
.category-tile .category-tile-icon {
  width: 3.5rem;
  height: 3.5rem;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.5rem;
  flex-shrink: 0;
}
.category-tile .category-tile-label {
  color: var(--vd-text);
  font-weight: 700;
  font-size: 0.95rem;
}

.rating-stars {
  color: #ffb400;
  font-size: 0.85rem;
  letter-spacing: 1px;
}
.rating-stars .fa-star.fa-regular {
  color: var(--vd-border);
}

/* ---------- Hero ---------- */
.hero-section {
  position: relative;
  background: var(--brand-gradient);
  color: #fff;
  border-radius: 0 0 2.5rem 2.5rem;
  overflow: hidden;
}
.hero-section::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    radial-gradient(
      circle at 15% 20%,
      rgba(255, 255, 255, 0.16),
      transparent 40%
    ),
    radial-gradient(circle at 85% 80%, rgba(15, 15, 15, 0.25), transparent 45%);
}
.hero-section .hero-content {
  position: relative;
  z-index: 1;
}
.hero-stat {
  border-left: 1px solid rgba(255, 255, 255, 0.25);
  padding-left: 1rem;
}

/* ---------- Pricing / stat cards ---------- */
.stat-card {
  background: var(--vd-surface);
  border: 1px solid var(--vd-border);
  border-radius: var(--vd-radius-lg);
  padding: 1.25rem;
}
.stat-icon {
  width: 3rem;
  height: 3rem;
  border-radius: var(--vd-radius);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.35rem;
}
.stat-card .stat-value {
  font-size: 1.7rem;
  font-weight: 800;
}
.stat-trend-up {
  color: #12b76a;
}
.stat-trend-down {
  color: #f04438;
}

.pricing-card {
  border: 1px solid var(--vd-border);
  border-radius: var(--vd-radius-xl);
  background: var(--vd-surface);
  padding: 1.75rem;
}
.pricing-card.featured {
  border-color: var(--brand-blue);
  box-shadow: 0 0 0 3px rgba(var(--brand-blue-rgb), 0.15);
}

/* ---------- Tabs / badges / alerts ---------- */
.nav-tabs {
  border-bottom-color: var(--vd-border);
}
.nav-tabs .nav-link {
  color: var(--vd-text-muted);
  border: none;
  font-weight: 600;
  border-bottom: 2px solid transparent;
}
.nav-tabs .nav-link.active {
  background: transparent;
  color: var(--brand-blue);
  border-bottom-color: var(--brand-blue);
}
.badge-license {
  border: 1px solid rgba(var(--brand-blue-rgb), 0.4);
  color: var(--brand-blue);
  background: rgba(var(--brand-blue-rgb), 0.08);
  font-weight: 600;
}
.alert-brand {
  background: rgba(var(--brand-blue-rgb), 0.08);
  border: 1px solid rgba(var(--brand-blue-rgb), 0.25);
  color: var(--vd-text);
}

/* ---------- Tables ---------- */
.table {
  color: var(--vd-text);
  vertical-align: middle;
}
.table > :not(caption) > * > * {
  background-color: transparent;
  border-bottom-color: var(--vd-border);
  color: inherit;
}
.table-hover > tbody > tr:hover > * {
  background-color: var(--vd-surface-2);
}
.table thead th {
  text-transform: uppercase;
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  color: var(--vd-text-muted);
  border-bottom-width: 1px;
}
.table-responsive-vd {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

/* ---------- Footer ---------- */
.vd-footer {
  background: var(--brand-black);
  color: rgba(255, 255, 255, 0.75);
}
.vd-footer a {
  color: rgba(255, 255, 255, 0.75);
}
.vd-footer a:hover {
  color: #fff;
}
.vd-footer .footer-brand {
  color: #fff;
  font-weight: 800;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.vd-footer .footer-brand img {
  height: 28px;
  width: 28px;
}
.vd-footer hr {
  border-color: rgba(255, 255, 255, 0.12);
}
.social-btn {
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.08);
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
}
.social-btn:hover {
  background: var(--brand-blue);
  color: #fff;
}

/* ---------- Auth pages ---------- */
.auth-shell {
  min-height: 100dvh;
  display: flex;
  align-items: center;
}
.auth-card {
  background: var(--vd-surface);
  border: 1px solid var(--vd-border);
  border-radius: var(--vd-radius-xl);
  box-shadow: var(--vd-shadow-lg);
}
.auth-side {
  background: var(--brand-gradient);
  color: #fff;
  border-radius: var(--vd-radius-xl) 0 0 var(--vd-radius-xl);
}

/* ---------- Timeline (orders / tickets) ---------- */
.vd-timeline {
  position: relative;
  padding-left: 2rem;
}
.vd-timeline::before {
  content: "";
  position: absolute;
  left: 0.6rem;
  top: 0.35rem;
  bottom: 0.35rem;
  width: 2px;
  background: var(--vd-border);
}
.vd-timeline .timeline-item {
  position: relative;
  padding-bottom: 1.5rem;
}
.vd-timeline .timeline-dot {
  position: absolute;
  left: -2rem;
  top: 0.15rem;
  width: 1.1rem;
  height: 1.1rem;
  border-radius: 50%;
  background: var(--brand-blue);
  border: 3px solid var(--vd-surface);
}
.vd-timeline .timeline-item.done .timeline-dot {
  background: #12b76a;
}
.vd-timeline .timeline-item.muted .timeline-dot {
  background: var(--vd-border);
}

/* ---------- Account sidebar nav ---------- */
.account-nav .nav-link {
  color: var(--vd-text);
  border-radius: var(--vd-radius-sm);
  padding: 0.55rem 0.75rem;
  font-weight: 500;
}
.account-nav .nav-link:hover {
  background: var(--vd-surface-2);
}
.account-nav .nav-link.active {
  background: rgba(var(--brand-blue-rgb), 0.1);
  color: var(--brand-blue);
  font-weight: 700;
}
.account-nav .nav-link .badge {
  margin-left: auto;
}

/* ---------- Empty state ---------- */
.empty-state {
  text-align: center;
  padding: 3rem 1rem;
  color: var(--vd-text-muted);
}
.empty-state .bi {
  font-size: 3rem;
  color: var(--vd-border);
}

/* ---------- Data table toolbar (storefront shop/search/category + admin tables) ---------- */
.table-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 1rem;
}
.table-toolbar .search-box {
  max-width: 320px;
}

/* ---------- Misc surfaces ---------- */
.dropdown-menu {
  background: var(--vd-surface);
  border-color: var(--vd-border);
  box-shadow: var(--vd-shadow);
}
.dropdown-item {
  color: var(--vd-text);
}
.dropdown-item:hover,
.dropdown-item:focus {
  background: var(--vd-surface-2);
  color: var(--vd-text);
}
.modal-content {
  background: var(--vd-surface);
  border-color: var(--vd-border);
}
.offcanvas {
  background: var(--vd-surface);
  color: var(--vd-text);
}
.list-group-item {
  background: var(--vd-surface);
  border-color: var(--vd-border);
  color: var(--vd-text);
}
.accordion-item {
  background: var(--vd-surface);
  border-color: var(--vd-border);
}
.accordion-button {
  background: var(--vd-surface);
  color: var(--vd-text);
}
.accordion-button:not(.collapsed) {
  background: rgba(var(--brand-blue-rgb), 0.08);
  color: var(--brand-blue);
  box-shadow: none;
}
.accordion-button:focus {
  box-shadow: 0 0 0 0.2rem rgba(var(--brand-blue-rgb), 0.18);
}
.pagination .page-link {
  background: var(--vd-surface);
  border-color: var(--vd-border);
  color: var(--vd-text);
}
.pagination .page-item.active .page-link {
  background: var(--brand-blue);
  border-color: var(--brand-blue);
}
hr {
  border-color: var(--vd-border);
  opacity: 1;
}

/* ---------- Scrollbar ---------- */
::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}
::-webkit-scrollbar-track {
  background: var(--vd-bg);
}
::-webkit-scrollbar-thumb {
  background: var(--vd-border);
  border-radius: 6px;
}

/* ---------- Responsive helpers ---------- */
@media (max-width: 767.98px) {
  .section-py {
    padding-block: 2.25rem;
  }
  .hero-section {
    border-radius: 0 0 1.5rem 1.5rem;
  }
  .auth-side {
    display: none;
  }
  .auth-card {
    border-radius: var(--vd-radius-xl);
  }
}

/* =========================================================================
   Long-form prose (.prose-vd)
   -------------------------------------------------------------------------
   Used by product descriptions and the product docs pages. The class was
   referenced in markup but never actually defined, so every article rendered
   with no paragraph rhythm, no list markers and an unstyled <pre>.

   Colours are set on the children rather than the container: Tailwind runs
   with important:true here, so a utility like `text-muted` on the wrapper
   would otherwise win against anything set on the wrapper itself.
   ========================================================================= */
.prose-vd {
  line-height: 1.75;
  /* ~70 characters is the readable measure; docs override this where the
     layout is already column-constrained. */
  max-width: 70ch;
}
.prose-vd p,
.prose-vd li {
  color: var(--vd-text);
}
.prose-vd > * + * {
  margin-top: 1.1em;
}
.prose-vd h2,
.prose-vd h3,
.prose-vd h4,
.prose-vd h5,
.prose-vd h6 {
  color: var(--vd-text);
  font-weight: 700;
  line-height: 1.3;
  margin-top: 2em;
  margin-bottom: 0.6em;
}
.prose-vd h2 {
  font-size: 1.4rem;
}
.prose-vd h3 {
  font-size: 1.2rem;
}
.prose-vd h4,
.prose-vd h5,
.prose-vd h6 {
  font-size: 1.05rem;
}
.prose-vd ul,
.prose-vd ol {
  padding-left: 1.4rem;
}
.prose-vd ul {
  list-style: disc;
}
.prose-vd ol {
  list-style: decimal;
}
.prose-vd li + li {
  margin-top: 0.4em;
}
.prose-vd li::marker {
  color: var(--vd-text-muted);
}
.prose-vd a {
  color: var(--brand-blue);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.prose-vd a:hover {
  color: var(--brand-blue-dark, var(--brand-blue));
}
.prose-vd strong {
  color: var(--vd-text);
  font-weight: 700;
}
.prose-vd hr {
  border: 0;
  border-top: 1px solid var(--vd-border);
  margin: 2em 0;
}
.prose-vd blockquote {
  margin: 1.4em 0;
  padding: 0.2rem 0 0.2rem 1rem;
  border-left: 3px solid var(--brand-blue);
  color: var(--vd-text-muted);
}
/* Inline code, distinct from a fenced block. */
.prose-vd :not(pre) > code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.875em;
  padding: 0.15em 0.4em;
  border-radius: 0.35rem;
  border: 1px solid var(--vd-border);
  background: var(--vd-surface-2);
  color: var(--vd-text);
  white-space: nowrap;
}
.prose-vd pre {
  position: relative;
  margin: 1.4em 0;
  padding: 1rem 1.1rem;
  border-radius: var(--vd-radius, 0.75rem);
  border: 1px solid var(--vd-border);
  background: var(--vd-surface-2);
  /* A long install command must scroll inside its own box rather than
     widening the whole article. */
  overflow-x: auto;
  font-size: 0.85rem;
  line-height: 1.65;
}
.prose-vd pre code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  background: none;
  border: 0;
  padding: 0;
  white-space: pre;
  color: var(--vd-text);
}
.prose-vd img {
  max-width: 100%;
  height: auto;
  border-radius: var(--vd-radius, 0.75rem);
  border: 1px solid var(--vd-border);
}
.prose-vd table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.92rem;
}
.prose-vd th,
.prose-vd td {
  border: 1px solid var(--vd-border);
  padding: 0.5rem 0.7rem;
  text-align: left;
}
.prose-vd th {
  background: var(--vd-surface-2);
  color: var(--vd-text);
  font-weight: 600;
}

/* ---------- Product documentation chrome ---------- */
.docs-body {
  max-width: none;
}
.docs-sidebar {
  position: sticky;
  top: 6rem;
  max-height: calc(100vh - 8rem);
  overflow-y: auto;
}
.docs-step {
  display: flex;
  align-items: flex-start;
  gap: 0.65rem;
  padding: 0.5rem 0.65rem;
  border-radius: 0.6rem;
  font-size: 0.875rem;
  line-height: 1.35;
  color: var(--vd-text);
  text-decoration: none;
  transition:
    background-color 0.12s ease,
    color 0.12s ease;
}
.docs-step:hover {
  background: var(--vd-surface-2);
}
.docs-step.is-active {
  background: color-mix(in srgb, var(--brand-blue) 12%, transparent);
  color: var(--brand-blue);
  font-weight: 600;
}
.docs-step-num {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.4rem;
  height: 1.4rem;
  margin-top: 0.05rem;
  border-radius: 999px;
  border: 1px solid var(--vd-border);
  background: var(--vd-surface);
  font-size: 0.7rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--vd-text-muted);
}
.docs-step.is-active .docs-step-num {
  background: var(--brand-blue);
  border-color: var(--brand-blue);
  color: #fff;
}
.docs-step.is-locked {
  color: var(--vd-text-muted);
  cursor: default;
}
.docs-step.is-locked:hover {
  background: none;
}

/* Copy button injected into every fenced block by assets/js/docs.js. */
.docs-copy {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.25rem 0.55rem;
  border-radius: 0.45rem;
  border: 1px solid var(--vd-border);
  background: var(--vd-surface);
  color: var(--vd-text-muted);
  font-size: 0.72rem;
  font-weight: 600;
  cursor: pointer;
  opacity: 0;
  transition:
    opacity 0.12s ease,
    color 0.12s ease,
    border-color 0.12s ease;
}
.prose-vd pre:hover .docs-copy,
.docs-copy:focus-visible {
  opacity: 1;
}
.docs-copy:hover {
  color: var(--brand-blue);
  border-color: var(--brand-blue);
}
/* Touch devices get no hover, so never hide it there. */
@media (hover: none) {
  .docs-copy {
    opacity: 1;
  }
}
.docs-pager {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.75rem;
  margin-top: 1.5rem;
}
@media (min-width: 640px) {
  .docs-pager {
    grid-template-columns: 1fr 1fr;
  }
}
.docs-pager-link {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  padding: 0.9rem 1.1rem;
  border: 1px solid var(--vd-border);
  border-radius: var(--vd-radius, 0.75rem);
  background: var(--vd-surface);
  text-decoration: none;
  transition: border-color 0.12s ease;
}
.docs-pager-link:hover {
  border-color: var(--brand-blue);
}
.docs-pager-link .docs-pager-dir {
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--vd-text-muted);
}
.docs-pager-link .docs-pager-title {
  font-weight: 600;
  color: var(--vd-text);
}
.docs-pager-next {
  text-align: right;
}
.docs-step-num.is-done {
  background: var(--vd-success, #22c55e);
  border-color: var(--vd-success, #22c55e);
  color: #fff;
}
.docs-done-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.35rem 0.75rem;
  border-radius: 999px;
  border: 1px solid var(--vd-border);
  background: var(--vd-surface);
  color: var(--vd-text-muted);
  font-size: 0.8rem;
  font-weight: 600;
  cursor: pointer;
  transition:
    color 0.12s ease,
    border-color 0.12s ease,
    background-color 0.12s ease;
}
.docs-done-btn:hover {
  color: var(--vd-success, #22c55e);
  border-color: var(--vd-success, #22c55e);
}
.docs-done-btn.is-done {
  color: #fff;
  background: var(--vd-success, #22c55e);
  border-color: var(--vd-success, #22c55e);
}
.docs-toc {
  margin-bottom: 1.5rem;
  padding: 0.85rem 1rem;
  border: 1px solid var(--vd-border);
  border-radius: var(--vd-radius, 0.75rem);
  background: var(--vd-surface-2);
}
.docs-toc-label {
  display: block;
  margin-bottom: 0.4rem;
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--vd-text-muted);
}
.docs-toc ul {
  margin: 0;
  padding: 0;
  list-style: none;
}
.docs-toc li + li {
  margin-top: 0.2rem;
}
.docs-toc a {
  font-size: 0.85rem;
  color: var(--vd-text);
  text-decoration: none;
}
.docs-toc a:hover {
  color: var(--brand-blue);
  text-decoration: underline;
}
.docs-toc .is-sub {
  padding-left: 0.9rem;
}
/* Anchor link revealed on heading hover. */
.docs-body .docs-anchor {
  margin-left: 0.4rem;
  font-size: 0.8em;
  color: var(--vd-text-muted);
  opacity: 0;
  text-decoration: none;
  transition: opacity 0.12s ease;
}
.docs-body h2:hover .docs-anchor,
.docs-body h3:hover .docs-anchor,
.docs-body .docs-anchor:focus-visible {
  opacity: 1;
}
/* Offset so an anchored heading isn't hidden behind the sticky navbar. */
.docs-body h2[id],
.docs-body h3[id] {
  scroll-margin-top: 6rem;
}

/* ---------- Invoice ---------- */
.invoice-table th {
  padding: 0.5rem 0.4rem;
  border-bottom: 2px solid var(--vd-border);
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--vd-text-muted);
}
.invoice-table td {
  padding: 0.7rem 0.4rem;
  border-bottom: 1px solid var(--vd-border);
  font-size: 0.9rem;
  vertical-align: top;
}
/* Print: strip the site chrome so "Save as PDF" produces a clean document
   rather than a screenshot of the page. Forced to a light palette because a
   dark-mode invoice wastes ink and reads badly on paper. */
@media print {
  .no-print,
  header nav,
  .site-header,
  footer,
  .checkout-trust-row {
    display: none !important;
  }
  html,
  body {
    background: #fff !important;
    color: #000 !important;
  }
  .invoice-sheet {
    border: 0 !important;
    box-shadow: none !important;
    padding: 0 !important;
    max-width: none !important;
    background: #fff !important;
  }
  .invoice-sheet .text-ink,
  .invoice-sheet .text-muted,
  .invoice-sheet dt,
  .invoice-sheet dd {
    color: #000 !important;
  }
  .invoice-table th,
  .invoice-table td {
    border-color: #999 !important;
  }
  a[href]::after {
    content: "";
  }
  @page {
    margin: 18mm;
  }
}

/* =========================================================================
   Alpha-modifier colour utilities
   -------------------------------------------------------------------------
   tailwind.config.js maps the brand palette to bare CSS variables
   (surface: "var(--vd-surface)"). Tailwind cannot compute an alpha channel
   from that - it needs an rgb(... / <alpha-value>) form - so every
   `bg-surface/90`-style class silently generated NOTHING.

   The visible result was the sticky site header rendering with
   background-color: rgba(0,0,0,0) - fully transparent, saved only by its
   backdrop-blur.

   color-mix() gives the same result while keeping the variables as plain hex,
   which the rest of the theme relies on. Add a rule here when a new
   alpha-modifier class is used, or it will fail silently the same way.
   ========================================================================= */
.bg-surface\/90 {
  background-color: color-mix(
    in srgb,
    var(--vd-surface) 90%,
    transparent
  ) !important;
}
.bg-surface2\/60 {
  background-color: color-mix(
    in srgb,
    var(--vd-surface-2) 60%,
    transparent
  ) !important;
}
@media (min-width: 1024px) {
  .lg\:bg-surface2\/60 {
    background-color: color-mix(
      in srgb,
      var(--vd-surface-2) 60%,
      transparent
    ) !important;
  }
}
.text-muted\/70 {
  color: color-mix(in srgb, var(--vd-text-muted) 70%, transparent) !important;
}
/* Issue tracker: the "won't fix" and "duplicate" status chips. */
.bg-muted\/15 {
  background-color: color-mix(
    in srgb,
    var(--vd-text-muted) 15%,
    transparent
  ) !important;
}
/* Gradient stops: Tailwind composes these through --tw-gradient-* vars. */
.via-surface\/90 {
  --tw-gradient-to: transparent var(--tw-gradient-to-position);
  --tw-gradient-stops:
    var(--tw-gradient-from),
    color-mix(in srgb, var(--vd-surface) 90%, transparent)
      var(--tw-gradient-via-position),
    var(--tw-gradient-to);
}
.to-surface\/40 {
  --tw-gradient-to: color-mix(in srgb, var(--vd-surface) 40%, transparent)
    var(--tw-gradient-to-position);
}

/* Sizes outside Tailwind's default scale (there is no 13 or 18 step), used by
   account-orders.php and account-settings.php - previously no size at all. */
.h-13 {
  height: 3.25rem;
}
.w-13 {
  width: 3.25rem;
}
.h-18 {
  height: 4.5rem;
}
.w-18 {
  width: 4.5rem;
}

/* Referenced by admin/about-content.php and admin/settings.php; only
   rounded-vd and rounded-vd-xl existed. */
.rounded-vd-md {
  border-radius: var(--vd-radius) !important;
}
