/** Shopify CDN: Minification failed

Line 1825:0 Unexpected "}"

**/
/* Accordion */
/* 2026-05-12 (Quieter): accordion outer border softened. */
.config-accordion {
  border: 1px solid #e8e8e8;
  border-radius: 10px;
  overflow: hidden;
  margin-top: 18px;
}

/* 2026-05-12 (Quieter): YOUR BUILD accordion header — warm cream
   background instead of gray. Ties to the active-state palette
   ("this is about your selection"). Same content, just a softer
   tone. Letter-spacing nudged out so it reads as a section label
   rather than a button. */
.config-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 14px;
  cursor: pointer;
  background: #faf7f2;
  font-weight: 600;
  font-family: 'Space Grotesk', sans-serif;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  transition: background 0.15s;
}
.config-header:hover {
  background: #f5f1ea;
}

/* Header puts the title and hint on the same row (hint sits to the right
   of the title) so the accordion button stays compact. The hint hides
   when the accordion is open since the body itself becomes self-explanatory.
   On narrow viewports we also hide the hint to keep the row from wrapping
   into two lines (which would defeat the compact-button intent). */
.config-header-text {
  display: flex;
  flex-direction: row;
  align-items: baseline;
  gap: 8px;
  flex: 1;
  min-width: 0;
}
.config-header-title {
  display: inline-block;
  flex-shrink: 0;
}
.config-header-hint {
  display: inline-block;
  font-size: 11px;
  font-weight: 400;
  color: #666;
  text-transform: none;
  letter-spacing: 0;
  font-family: 'Barlow', sans-serif;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
/* 2026-05-12 (Quieter): contextual hint internals — bold portion is the
   model identity (color/lens), separator slashes are quieter, add-on
   count chip is green (same money-back-to-you semantics). */
.config-header-hint b { color: #111; font-weight: 600; }
.config-header-hint .hint-sep { color: #b0b0b0; margin: 0 3px; font-weight: 400; }
.config-header-hint .hint-addons { color: #16a34a; font-weight: 600; margin-left: 6px; flex-shrink: 0; }
.config-accordion.open .config-header-hint {
  display: none;
}
/* 2026-05-12 (Quieter mobile): two-row header layout.
     Row 1: TITLE + PRICE + chevron (price is shrunk so it doesn't
            dominate the small-caps title)
     Row 2: hint (model line) using the full row width
   Implementation note: `.config-header-text` is a wrapper around
   title+hint by default. We collapse it with `display: contents` so
   its children become direct flex items of `.config-header`, then use
   `flex-wrap: wrap` + `order:` + `flex-basis: 100%` to land the hint
   on its own full-width row. */
@media (max-width: 480px) {
  .config-header {
    flex-wrap: wrap;
    align-items: center;
    row-gap: 4px;
  }
  .config-header-text {
    display: contents;
  }
  .config-header-title {
    flex: 1 1 auto;
    order: 1;
  }
  .config-right {
    flex: 0 0 auto;
    order: 2;
    /* Shrink so the price doesn't visually dominate the small-caps
       title. Mixed-case Barlow at 12px reads bigger than uppercase
       Space Grotesk at 12px — drop to 11px to balance. */
    font-size: 11px !important;
    gap: 8px;
  }
  .config-header-hint {
    flex: 1 1 100%;
    width: 100%;
    order: 3;
    display: block;
    white-space: normal;
    font-size: 11px;
    line-height: 1.35;
    text-overflow: clip;
    margin-top: 0;
  }
  .config-header-hint .hint-addons {
    margin-left: 4px;
  }
}

.config-right {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: 'Barlow', sans-serif;
  text-transform: none;
  letter-spacing: normal;
}

.config-arrow {
  transition: 0.3s;
}

.config-body {
  max-height: 0;
  overflow: hidden;
  transition: 0.3s;
  background: #fff;
}

.config-accordion.open .config-body {
  max-height: 1000px;
  padding: 14px;
}

/* Friendly intro paragraph at the top of the open accordion body —
   tells the user exactly what they're looking at and how to change
   the build. Sits above the auto-rendered config rows. */
/* 2026-05-12 (Quieter): explainer accent stripe shifts from purple
   #5b5bf7 to black, and background from cool gray to neutral. */
.config-explainer {
  margin: 0 0 12px;
  padding: 10px 12px;
  background: #f8f8f8;
  border-left: 3px solid #111;
  border-radius: 4px;
  font-size: 12px;
  line-height: 1.45;
  color: #444;
  font-family: 'Barlow', sans-serif;
  text-transform: none;
  letter-spacing: 0;
  font-weight: 400;
}

.config-accordion.open .config-arrow {
  transform: rotate(180deg);
}

.config-items {
  font-size: 14px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.config-section-label {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: #999;
  margin-bottom: 2px;
  font-family: 'Space Grotesk', sans-serif;
}

/* 2026-05-12 (Quieter): "×N" quantity indicator next to addon title in
   the YOUR BUILD section when an accessory's stepper has qty > 1. */
.config-addon-qty {
  display: inline-block;
  margin-left: 4px;
  font-size: 11px;
  font-weight: 600;
  color: #666;
}

.config-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  font-size: 13px;
  line-height: 1.5;
}

/* 2026-05-12 (Quieter): composite row — replaces the 4 separate
   Lens/Frame/Size/Mirror rows. Title in bold + meta line below + price
   on the right. Used for the Glasses item in YOUR BUILD. */
.config-row--composite {
  align-items: flex-start;
  padding: 4px 0;
}
.config-row--composite .config-key {
  line-height: 1.4;
}
.config-row--composite .config-key b {
  color: #111;
  font-weight: 600;
}
.config-row--composite .config-val {
  font-weight: 600;
}

.config-key {
  color: #666;
  /* L25: long lens labels ("Spare lens: Clear · Left mirror · fits your
     Medium frame") wrapped weirdly when the row was a tight flex pair —
     the price would orphan to its own line with just "kr" visible. Letting
     the key shrink + wrap keeps the price column tight on the right edge. */
  flex: 1 1 auto;
  min-width: 0;
}

.config-val {
  color: #222;
  font-weight: 500;
  text-align: right;
  white-space: nowrap;
}

/* L25: price cell wrapper holds the optional struck original price + the
   current price. Inline-flex keeps them on the same row, right-aligned,
   with a small gap. */
.config-val-wrap {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  white-space: nowrap;
}
.config-val-orig {
  color: #999;
  font-weight: 500;
  font-size: 12px;
  text-decoration: line-through;
}

.config-row--subtotal {
  margin-top: 4px;
  padding-top: 6px;
  border-top: 1px solid #eee;
}

.config-row--subtotal .config-key { font-weight: 600; color: #222; }
.config-row--subtotal .config-val { font-weight: 600; }

/* L25 / L27: "You save X" summary row below Subtotal. Matches the
   sticky build drawer's savings line — same green (#16a34a) palette.
   The L25 warm-orange was misread as red / negative; positive-savings
   green reads as money-back-to-you. No minus prefix on the value
   either ("You save 218 kr", not "You save −218 kr"). */
.config-row--savings {
  margin-top: 2px;
  padding: 6px 0 2px;
  color: #16a34a;
}
.config-row--savings .config-key {
  color: #16a34a;
  font-weight: 500;
}
.config-val--savings {
  color: #16a34a;
  font-weight: 700;
}

.config-divider {
  height: 1px;
  background: #e0e0e0;
  margin: 8px 0;
}

/* Layout */
.px-block .block-parent {
  display: flex;
  justify-content: space-between;
  gap: 20px;
}

.px-wrap {
  margin-top: 20px;
}

/* Size Guide */
.sizeguidebtn {
  font-family: "Inter Tight", sans-serif;
  font-weight: 400;
  line-height: 1;
  text-decoration: underline;
  text-underline-offset: 3px;
  font-size: 14px;
  margin-top: 10px;
}

/* Addons */
.addons {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.addon-card {
  display: flex;
  justify-content: space-between;
  padding: 12px;
  border-radius: 8px;
  border: 1px solid #ddd;
  cursor: pointer;
  transition: 0.2s;
  background: #fff;
}

.addon-card.active:not([data-addon-category]) {
  background: #111;
  color: #fff;
  border-color: #111;
}

.addon-card.active:not([data-addon-category]) .compare {
  color: #bbb;
}

.addon-left strong {
  font-size: 16px;
  font-family: 'Inter Tight';
  font-weight: 600;
}

.addon-right {
    max-width: 80px;
    display: flex;
    justify-content: flex-end;
    align-items: center;
    width: 100%;
}


.compare {
  text-decoration: line-through;
  font-size: 12px;
  margin-right: 5px;
}

.badge {
  background: red;
  color: #fff;
  font-size: 10px;
  padding: 2px 6px;
  margin-left: 6px;
  border-radius: 4px;
}

span.price {
  font-weight: 700;
}

/* 60/40 grid split */
@media only screen and (min-width: 1100px) {
  .large-up--sixty { width: 60%; }
  .large-up--forty { width: 40%; }
}

/* 2026-05-12 (Quieter): lens-type group container.
   - Desktop (≥768px): 5 cols (Standard / HC / Reflective / Polarized / Photochromic)
   - Mobile + tablet (≤767px): 3 cols. 5-up was too cramped at narrower
     widths — labels like "High Contrast" or "Photochromic" wrap to
     multiple lines, tiles get visually noisy. 3 cols = 2 rows (3+2)
     gives each tile breathing room. */
.px-groups {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 6px;
}

@media (max-width: 767px) {
  /* Default mobile: 3-col grid. Works for The View (5 lens types →
     3+2 wrap) and any product with 3 or 6 types. */
  .px-groups {
    grid-template-columns: repeat(3, 1fr);
  }
  /* 2026-05-12 (Quieter mobile): adapt grid to actual tile count via
     `:has()`. Avoids lonely tiles on a wrapped second row and empty
     cells from over-specified columns.
       - 2 tiles (Clip-On: Polarized + Clear)        → 2 cols
       - 4 tiles (The Classic: HC/Refl/Polar/Photo)  → 4 cols
       - everything else (View's 5)                  → 3 cols default
  */
  .px-groups:has(> .px-group:nth-child(2)):not(:has(> .px-group:nth-child(3))) {
    grid-template-columns: repeat(2, 1fr);
  }
  .px-groups:has(> .px-group:nth-child(4)):not(:has(> .px-group:nth-child(5))) {
    grid-template-columns: repeat(4, 1fr);
  }
}

.px-groups button.px-group {
  max-width: none;
  width: 100%;
  min-width: 0;
}

/* 2026-05-12 (Quieter): lens-type tile — softened.
   Was: gray fill #f5f5f5 + 1px #e0e0e0 border, solid-black active state.
   Now: transparent + 1px #e8e8e8 border (default), warm-cream fill + 1px
   #111 border when active. Text stays #111 in active state (no white-on-
   black palette flip). Hover: slightly darker neutral border. */
.px-group {
  padding: 14px 16px;
  background: transparent;
  border: 1px solid #e8e8e8;
  border-radius: 10px;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}

.px-group:hover {
  border-color: #b0b0b0;
}

.px-group.active {
  background: #faf7f2;
  color: #111;
  border-color: #111;
}

/* 2026-05-12 (Quieter): "Bestseller" badge floats above the top edge
   of the Photochromic lens-type tile. Black on warm-cream so it reads
   as a curated callout, not a sale pill (sale-red would be off-brand
   for a non-discount badge). The lens-type tiles are position:relative
   already so absolute positioning anchors correctly; we add the rule
   defensively below in case any other variant relies on default. */
.px-group { position: relative; }
.px-group__badge {
  position: absolute;
  top: -9px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 3;
  background: #111;
  color: #fff;
  font: 700 9px/1 'Space Grotesk', sans-serif;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 3px 9px;
  border-radius: 3px;
  white-space: nowrap;
  pointer-events: none;
}
.px-group.active .px-group__badge {
  background: #faf7f2;
  color: #111;
  border: 1px solid #111;
  padding: 2px 8px;
}

/* 2026-05-12 (Quieter): mobile Bestseller badge — slightly smaller +
   tighter so it fits over the narrower mobile lens-type tiles (which
   drop to 3-col grid below 480px). */
@media (max-width: 480px) {
  .px-group__badge {
    font-size: 8.5px;
    padding: 2px 7px;
    top: -8px;
    letter-spacing: 0.06em;
  }
  .px-group.active .px-group__badge {
    padding: 1px 6px;
  }
}
.px-group.active .lens-card__name { color: #111; }
.px-group.active .lens-card__price { color: #111; font-weight: 700; }
.px-group.active .lens-card__icon img { filter: none; }

.px-group h5 {
    margin: 0;
    text-align: left;
}

/* Lens card — compact 2x2 grid */
.lens-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 4px;
    padding: 4px 0;
}

.lens-card__icon {
    width: 22px;
    height: 22px;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 2px;
}

.lens-card__icon img {
    width: 20px;
    height: 20px;
}

/* 2026-05-12 (Quieter): inline-SVG lens-type icons (Standard / High
   Contrast / Reflective / Polarized / Photochromic). Use currentColor
   so the icon takes on the surrounding text color — default #888-ish
   muted, active #111. */
.lens-card__icon svg.px-lens-icon {
    width: 22px;
    height: 22px;
    color: #555;
    transition: color 0.15s ease;
}
.px-group.active .lens-card__icon svg.px-lens-icon {
    color: #111;
}

.lens-card__name {
    font-size: 12px;
    font-weight: 700;
    margin: 0;
    line-height: 1.2;
}

.lens-card__price {
    font-size: 13px;
    font-weight: 700;
    font-family: 'Inter Tight', sans-serif;
    opacity: 0.8;
}

/* Active state */
.px-group.active .lens-card__icon img {
    filter: invert(1);
}

.px-group.active .lens-card__sub {
    opacity: 0.8;
}

/* Lens detail panel — Roka style */
/* ── Lens detail expanding panel (Direction B) ── */
.lens-detail {
    position: relative;
    margin-top: 12px;
    min-height: 0;
}
.lens-detail__pointer {
    position: absolute;
    top: -6px;
    width: 12px;
    height: 12px;
    background: #faf7f2;
    border: none;
    transform: rotate(45deg);
    transition: left 0.25s ease;
    left: 60px; /* default, repositioned by JS */
}
/* 2026-05-12 (Quieter): lens detail card — warm cream fill, no border.
   Pointer above matches. The Category badge inside switches from
   gray-on-white to white-on-cream-border to fit the warmer palette. */
.lens-detail__card {
    background: #faf7f2;
    border: none;
    border-radius: 10px;
    padding: 14px 18px 16px;
}
.lens-detail__header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 6px;
}
.lens-detail__best-for {
    font-size: 13px;
    font-weight: 600;
    color: #222;
}
.lens-detail__category {
    font-size: 10px;
    font-weight: 600;
    color: #444;
    background: #fff;
    border: 1px solid #e0d8cd;
    border-radius: 3px;
    padding: 2px 7px;
    letter-spacing: 0.04em;
}
.lens-detail__desc {
    font-size: 12.5px;
    line-height: 1.5;
    color: #666;
    margin: 0 0 12px;
}
.lens-detail__bar-wrap {
    margin: 0;
}
.lens-detail__bar-label {
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: #999;
    display: block;
    margin-bottom: 5px;
}
/* 2026-05-12 (Quieter): light-transmission bar — backfill is now a
   gradient from dark (left = low VLT, dark lens) to light (right =
   high VLT, clear lens). The gradient is the visual hint for "what
   you'd see at each end of the bar" — without it the bar reads as
   an abstract number scale. Markers sit on top, indicating the
   active variant's position(s). */
.lens-detail__bar {
    position: relative;
    height: 8px;
    background: linear-gradient(90deg, #2a2a2a 0%, #6b6b6b 40%, #cfcfcf 75%, #f4f4f4 100%);
    border-radius: 4px;
    overflow: hidden;
}
.lens-detail__bar-fill {
    position: absolute;
    top: -2px;
    bottom: -2px;
    height: 12px;
    background: #111;
    border: 2px solid #fff;
    border-radius: 3px;
    transition: width 0.3s ease, left 0.3s ease;
    box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.2);
    min-width: 8px;
}
.lens-detail__bar-fill--range {
    background: #111;
    border: none;
    height: 8px;
    top: 0;
    box-shadow: none;
}
.lens-detail__bar-fill--marker {
    /* Discrete marker for individual variants (Standard's Clear / Smoke
       split). Narrower than --range, sits on top of the gradient. */
    width: 10px !important;
    height: 14px;
    top: -3px;
    background: #111;
    border: 2px solid #fff;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
    transform: translateX(-50%);
}
.lens-detail__bar-values {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-top: 5px;
    font-size: 11px;
    color: #666;
}
.lens-detail__bar-uv {
    font-weight: 600;
    color: #222;
    font-size: 10px;
    background: #e8f5e9;
    color: #2e7d32;
    padding: 1px 6px;
    border-radius: 3px;
}

/* Legacy classes kept for compatibility */
.lens-detail__specs { display: none; }
.lens-detail__icon { display: none; }
.lens-detail__conditions { display: none; }
.lens-detail__dot { display: none; }

/* 2026-05-12 (Quieter): the gradient transmission bar + its
   "LIGHT TRANSMISSION" label are hidden on ALL viewports — the
   numeric VLT range ("8–18% VLT") plus the Cat. badge in the header
   communicate the same info more directly. Bar visualization added
   complexity without proportional clarity gain (especially for the
   two-marker Standard variant, which was only ever one product's
   special case). */
.lens-detail__bar-label,
.lens-detail__bar {
  display: none;
}

/* 2026-05-12 (Quieter mobile): on mobile we also drop the prose
   description and tighten padding. Desktop keeps the description.
   Net mobile height: ~50px (was 157px). */
@media (max-width: 640px) {
  .lens-detail__card {
    padding: 10px 12px 10px;
  }
  .lens-detail__desc {
    display: none;
  }
  .lens-detail__header {
    margin-bottom: 6px;
  }
  .lens-detail__best-for {
    font-size: 12.5px;
    line-height: 1.3;
  }
  .lens-detail__bar-values {
    margin-top: 0;
  }
}
.lens-detail__transmission { display: none; }
.lens-detail__sub { display: none; }

.config-variant-info {
    color: #999;
    font-weight: 400;
    font-style: italic;
    font-size: 0.9em;
}

button.px-group.active img {
  filter: invert(1);
}

button.px-group.active h5 {
  color: #fff;
}

/* Sub buttons */
.px-sub {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 10px;
}

.px-sub-btn {
  padding: 8px 12px;
  border: 1px solid #ccc;
  border-radius: 6px;
  cursor: pointer;
}

.px-sub-btn.active {
  background: #000;
  color: #fff;
}

/* Rows */
.px-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 5px 0 12px;
}

/* Mirror Cards */
/* Clip size selector — Medium and Small shown side-by-side as toggle cards.
   Mirrors the .px-mirror-row card pattern (gray fill, black active state)
   for visual consistency across the configurator. */
.px-row.px-size-row--clip {
  display: flex;
  flex-wrap: nowrap;
  gap: 8px;
  width: 100%;
}
.px-row.px-size-row--clip button.px-btn {
  flex: 1 1 0%;
  min-width: 0;
  max-width: none;
  padding: 14px 16px;
  min-height: 64px;
  box-sizing: border-box;
  border: 1px solid #e0e0e0;
  background: #f5f5f5;
  border-radius: 10px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  font-family: 'Space Grotesk', sans-serif;
  transition: background 0.15s;
}
.px-row.px-size-row--clip button.px-btn strong {
  font-size: 14px;
  font-weight: 600;
}
.px-row.px-size-row--clip button.px-btn .px-btn__sub {
  font-size: 11px;
  color: #888;
  text-align: center;
  line-height: 1.3;
  word-wrap: break-word;
}
.px-row.px-size-row--clip button.px-btn.active {
  background: #222;
  color: #fff;
  border-color: #222;
}
.px-row.px-size-row--clip button.px-btn.active .px-btn__sub {
  color: rgba(255, 255, 255, 0.75);
}

/* 2026-05-12 (Quieter): Mirror Position row.
   Desktop: side-by-side (or 3-up when Right-Mirror is also shown),
            tight V0 compression.
   Mobile (≤640px): stacked vertically with more padding + bigger
            text, full-width touch targets.
   Equal-height stretch so wrapped qualifiers don't make buttons
   uneven. */
.px-row.px-mirror-row {
  display: flex;
  flex-wrap: nowrap;
  gap: 8px;
  width: 100%;
  align-items: stretch;
}
@media (max-width: 640px) {
  .px-row.px-mirror-row {
    flex-direction: column;
  }
}

/* 2026-05-12 (Quieter): mirror button base — transparent default,
   tight V0 padding, equal-height flex column.
   Border is 2px from the start (light gray for inactive) so the active
   state can flip border-color to #111 without changing layout. This
   keeps padding identical between states — content doesn't shift 1px
   when the user clicks. The `!important` on padding is needed because
   a legacy `@media (max-width:512px) .px-btn { padding: 4px !important }`
   rule in custom.css (originally for tiny frame thumbnails) would
   otherwise override us. */
.px-row.px-mirror-row button.px-btn {
  flex: 1 1 0%;
  min-width: 0;
  max-width: none !important;
  border: 2px solid #e8e8e8 !important;
  background: #fff;
  padding: 10px 12px !important;
  min-height: auto;
  overflow: hidden;
  border-radius: 10px;
  transition: background 0.15s, border-color 0.15s;
}

/* 2026-05-12 (Quieter): active mirror button — same 2px border (color
   only) on warm cream fill. Padding unchanged from inactive so the
   text doesn't shift position on toggle.
   Selector includes both classes (.px-btn.active) so its specificity
   (0,4,1) beats the base rule's (0,3,1). Without that, the base rule's
   border-color #e8e8e8 wins and the active button never turns black. */
.px-row.px-mirror-row button.px-btn.active {
  background: #faf7f2 !important;
  color: #111;
  border-color: #111 !important;
  padding: 10px 12px !important;
}

.px-row.px-mirror-row button.px-btn.active .mirror-card h5,
.px-row.px-mirror-row button.px-btn.active .mirror-card p {
  color: inherit;
}
.px-row.px-mirror-row button.px-btn.active .mirror-card p {
  color: #555;
}

.px-row.px-mirror-row button.px-btn.active .mirror-card h6 {
  border-color: rgb(17 17 17 / 12%);
}

/* 2026-05-12 (Quieter mobile): mirror buttons compressed for mobile
   vertical-space budget. Stacked layout with tight padding + smaller
   text. Title-to-body margin tightens so each card is ~52px tall
   instead of ~72px (saves ~40px for 2 stacked cards). The qualifier
   text truncates to one line — the title (Left / Right / Dual)
   carries the primary meaning. */
@media (max-width: 640px) {
  /* Both active + inactive get identical padding so toggling state
     doesn't shift the text 1px. Border thickness is constant (2px)
     across states — only the color flips. */
  .px-row.px-mirror-row button.px-btn,
  .px-row.px-mirror-row button.px-btn.active {
    padding: 11px 14px !important;
  }
  .mirror-card h5 {
    font-size: 14px !important;
    margin-bottom: 2px !important;
  }
  .mirror-card p {
    font-size: 11.5px !important;
    line-height: 1.3 !important;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
}

/* 2026-05-12 (Quieter, revised): all 3 mirror buttons are now visible
   at all times (Left + Right + Dual). Previously the counter-traffic
   side (the data-mirror-locked one) was hidden via display:none and
   the customer had to click a swap link to reveal it — but on combos
   where the geo-recommended mirror is OOS or unavailable, this
   actively hid valid alternatives. User asked 2026-05-12: "doesn't
   show dual or right mirror — check that all [show]."

   We keep the data-mirror-locked attribute so the swap link still
   knows which side is "the other one" (for re-orienting the
   recommendation footnote text after a swap), but the attribute no
   longer hides the button visually. The recommendation hint is now
   carried by the button's qualifier copy ("Right-hand traffic — US,
   Europe, most of the world" vs "Left-hand traffic — UK, Australia"),
   which customers can read directly on each card. */
.px-row.px-mirror-row button[data-mirror-locked] {
  /* Was: display: none. Now visible. The attribute persists for JS
     book-keeping of which side is counter-traffic but doesn't hide. */
}
/* .show-locked is the legacy "reveal" toggle from the swap-link UX.
   With buttons always visible it's a no-op now; left in place so a
   legacy click handler that adds the class doesn't error. */
.px-row.px-mirror-row.show-locked button[data-mirror-locked] {
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
}

/* 2026-05-12 (Quieter): switch link below the mirror buttons —
   recommendation copy + action. Replaces the previous .px-size-expand-
   link styling reused on the mirror-footnote (was blue underlined).
   Now: two-line p with the action as an inline link inside. */
/* 2026-05-12 (Quieter, revised): with all 3 mirrors now visible, the
   swap-link footnote is redundant — customers click the Right Mirror
   card directly instead of "Switch to Right Mirror →". The footnote
   is hidden by default. If a future product reintroduces the geo-lock
   2-button UX, drop this rule. */
.mirror-footnote {
  display: none;
  font-size: 11px;
  color: #666;
  line-height: 1.5;
  margin: 12px 0 0;
}
.mirror-footnote__switch {
  color: #111;
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
  font-weight: 500;
}
.mirror-footnote__switch:hover {
  text-decoration-thickness: 2px;
}
/* 2026-05-12 (Quieter mobile): hide the recommendation sentence on
   mobile to save another line of vertical space. The swap link
   ("Switch to Right Mirror for UK / Australia →") still shows — it's
   the actionable part. Customers who want context have the mirror
   card description directly above. The recommendation sentence is
   wrapped in <span class="mirror-footnote__recommend"> by the Liquid
   and by swapSingleSideMirror() so this targets both initial render
   and post-swap re-renders. */
@media (max-width: 640px) {
  .mirror-footnote {
    margin-top: 8px;
  }
  .mirror-footnote__recommend {
    display: none;
  }
}

/* 2026-05-12 (Quieter): model line ("MODEL  Matte Black/Polarized
   Smoke · Left/M145") — written by JS into [data-model-line]. Was a
   plain 11px gray line; now styled as a "tracked label + readable
   content" pattern. JS in Pass 3 writes the formatted HTML. Until
   then this style applies to whatever the JS writes today. */
.px-model-line {
  display: block;
  font-size: 13px;
  font-family: 'Inter Tight', sans-serif;
  color: #222;
  line-height: 1.4;
  margin: 14px 0 4px;
  /* 2026-05-12 (Quieter): override the parent's text-transform:
     uppercase that bled in from the .px-block header rules. Model
     line shows variant titles ("Matte Black", "Standard Smoke")
     which read correctly in mixed case. The LABEL ("Model") stays
     uppercase via its own rule. */
  text-transform: none;
  letter-spacing: 0;
}
.px-model-line__name, .px-model-line__spec {
  text-transform: none;
  letter-spacing: 0;
}
.px-model-line__label {
  font: 600 11px/1 'Space Grotesk', sans-serif;
  color: #888;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  margin-right: 10px;
}
.px-model-line__name {
  font-weight: 600;
  color: #111;
}
.px-model-line__sep {
  color: #b0b0b0;
  margin: 0 4px;
  font-weight: 400;
}
.px-model-line__spec {
  color: #666;
  font-weight: 500;
  margin-left: 10px;
  padding-left: 12px;
  border-left: 1px solid #ddd;
}

/* 2026-05-12 (Quieter mobile): the model line is long ("MODEL Matte
   Black / Photochromic Smoke 0–3 / Left / M145") and wraps badly on
   mobile — sometimes mid-word ("0–\n3"). Force a clean break using
   CSS Grid:
     Row 1, col 1: LABEL  ("MODEL")
     Row 1, col 2: NAME   ("Matte Black / Photochromic Smoke 0–3")
     Row 2, col 2: SPEC   ("Right / M145")  ← aligns under NAME
   Spec lands on its own row, indented to where the name starts (not
   flush left under the label). Each variant produces the same 2-line
   layout regardless of name length, so card heights match. The
   vertical divider is dropped — redundant with the line break. */
@media (max-width: 480px) {
  .px-model-line {
    display: grid;
    grid-template-columns: auto 1fr;
    align-items: baseline;
    row-gap: 2px;
  }
  .px-model-line__label {
    grid-column: 1;
    grid-row: 1;
  }
  .px-model-line__name {
    grid-column: 2;
    grid-row: 1;
    white-space: nowrap;
  }
  .px-model-line__spec {
    grid-column: 2;
    grid-row: 2;
    margin-left: 0;
    padding-left: 0;
    border-left: 0;
  }
}

/* 2026-05-12 (Quieter): mirror card content — left-align, tight V0
   vertical rhythm (title above qualifier with 1px margin), gray
   qualifier for hierarchy. */
.mirror-card {
  overflow: hidden;
  text-align: left;
  word-break: break-word;
}

.mirror-card h5 {
  font-size: 14px;
  font-family: 'Inter Tight', sans-serif;
  font-weight: 600;
  margin-bottom: 1px;
  line-height: 1.15;
  color: #222;
  /* 2026-05-12: override the theme's global `h5 { text-transform: var(--FONT-HEADING-TRANSFORM) }`
     rule. Without this, "Left Mirror" / "Dual Mirror" render as
     "LEFT MIRROR" / "DUAL MIRROR" — too shouty for the quieter palette. */
  text-transform: none;
  letter-spacing: 0;
}

.mirror-card p {
  font-size: 11px;
  text-align: left;
  color: #888;
  margin: 0;
  line-height: 1.3;
  word-wrap: break-word;
}

.mirror-card h6 {
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px solid hsl(0deg 0% 13% / 15%);
  font-size: 11px;
}

/* Variant */
.varient-title-sub {
    display: flex;
    justify-content: space-between;
    gap: 8px;
    flex: 1;
}

span.px-price {
  font-size: 14px;
  font-family: 'Inter Tight';
  font-weight: 700;
}

/* Buttons — base */
.px-btn {
    padding: 10px;
    border: 1px solid #ccc;
    border-radius: 6px;
    cursor: pointer;
    max-width: 90px;
    width: 100%;
    min-height: auto;
    /* L28 (D-CAT-TILE): allow absolute-positioned cat badge inside. */
    position: relative;
}

/* Model thumbnail buttons — square with image */
.px-size-group .px-btn {
    padding: 4px;
    aspect-ratio: 1 / 1;
}

.px-size-group .px-btn .px-img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: 4px;
    aspect-ratio: 1 / 1;
}

/* L28 (D-CAT-TILE) + 2026-05-12 (Quieter): Cat. badge on photochromic
   variant tiles. Customers need to distinguish 0–2 vs 0–3 vs 0–3 Full
   Spectrum at thumbnail size — both lens images look near-identical.
   2026-05-12 update: badge now CENTERED horizontally at the top of the
   tile (was top-left). Drops the "Cat." prefix — content is short
   enough that "0–3" / "0–2" reads clean. Pill is white-on-dark with
   thin backdrop blur for legibility over any photo. */
.px-btn__cat {
    position: absolute;
    top: 6px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 2;
    padding: 2px 7px;
    background: rgba(255, 255, 255, 0.95);
    color: #111;
    border-radius: 3px;
    font-family: 'Space Grotesk', sans-serif;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.02em;
    line-height: 1.15;
    pointer-events: none;
    white-space: nowrap;
    -webkit-backdrop-filter: blur(2px);
    backdrop-filter: blur(2px);
}
/* L36: badge stays black-on-white regardless of tile state. The L28
   active-state invert was distracting — every photochromic click made
   the badge flip palette. The black pill on the active dark tile is
   still readable (white text on dark badge sits inside the otherwise-
   dark active tile fine), and the customer's eye stays on the photo. */
.px-size-group .px-btn--sold-out .px-btn__cat {
    opacity: 0.55;
}

/* 2026-05-12 (Quieter): size-info row holds the Medium label + Size
   Guide button on the same line. Was a standalone .px-size-info; now
   wrapped in .px-size-info-row for the flex pairing. The standalone
   .px-size-info below (used for Small) keeps the old standalone style. */
.px-size-info-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin: 16px 0 8px;
}
.px-size-info-row .px-size-info { margin: 0; }

/* Size section: expand/collapse for Small */
.px-size-info {
    font-size: 14px;
    color: #222;
    font-family: 'Space Grotesk', sans-serif;
    font-weight: 600;
    margin: 16px 0 8px;
    line-height: 1.3;
}
.px-size-info span {
    font-weight: 400;
    color: #888;
    font-size: 12px;
}
/* 2026-05-12 (Quieter): Small-expand link — was blue (#3b82f6),
   now black underlined to match the quieter palette. The link text is
   driven by JS and changes with active lens group ("Polarized also
   comes in Small..." vs "Hide Small options"). */
.px-size-expand-link {
    font-size: 12px;
    color: #111;
    cursor: pointer;
    margin-top: 8px;
    display: inline-block;
    text-decoration: underline;
    text-underline-offset: 3px;
    font-weight: 500;
}
.px-size-expand-link:hover {
    text-decoration-thickness: 2px;
}
.px-size-section-small {
    display: none;
    margin-top: 4px;
}
.px-size-section-small.is-open {
    display: block;
}
.px-size-section-small .px-size-group {
    margin-top: 0;
}

.px-btn__label {
    font-size: 11px;
    word-break: break-word;
    line-height: 1.2;
}

.px-size-group .px-row {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

/* 2026-05-12 (Quieter): active frame tile — 2px black border on warm-
   cream fill. Padding shrinks by 1px so total tile size is unchanged
   between states (no layout shift on click). */
.px-btn.active {
  background: #faf7f2;
  color: #111;
  border: 2px solid #111;
  padding: 9px;
}
.px-size-group .px-btn.active {
  padding: 3px;
}

.px-btn.hide {
  display: none !important;
}

/* 2026-05-12 (Quieter): sold-out frame tile — light white-fade overlay
   instead of the previous 60% grayscale + diagonal slash + 60% opacity.
   The image stays visible (slight saturation drop only); a 28% white
   overlay tells the customer the tile is paused without hiding the
   product. Caption sits at the bottom in dark text with a soft text-
   shadow so it reads on any color. Stays clickable so the L27
   alternatives chip mechanism still surfaces a replacement. */
.px-btn--sold-out {
  position: relative;
  opacity: 1;
  cursor: pointer;
  overflow: hidden;
}
.px-btn--sold-out .px-img {
  filter: saturate(0.7);
}
.px-btn--sold-out::after {
  content: '';
  position: absolute;
  inset: 0;
  background: rgba(255, 255, 255, 0.28);
  border-radius: 6px;
  pointer-events: none;
  z-index: 2;
}
.px-sold-out-label {
  position: absolute;
  bottom: 5px;
  left: 0;
  right: 0;
  font-size: 9.5px;
  font-weight: 700;
  color: #111;
  text-align: center;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  text-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);
  z-index: 3;
  padding: 1px 0;
  background: transparent;
}
.px-btn--sold-out.active {
  opacity: 1;
  border-color: #111;
  border-width: 2px;
  padding: 3px;
}

/* Notify Me button — HIDDEN. Klaviyo's Back-in-Stock app auto-injects its
   own button below the .px-oos-info text, so showing our custom button
   plus Klaviyo's resulted in two duplicate notify buttons. The OOS info
   text ("<variant> is currently out of stock — get notified below") plus
   Klaviyo's injected button is sufficient. The class is still added by
   the configurator JS (which we don't touch); we just hide it visually. */
.px-notify-btn {
  display: none !important;
}

/* 2026-05-12: hide Pipeline-native "Only N left" countdown widget.
   The configurator owns its own .px-low-stock banner (amber pill below
   YOUR BUILD), which shows the same info with the consistent palette.
   Showing both = duplicate stock message between YOUR BUILD and the
   cart row. */
.variant__countdown { display: none !important; }

/* Low stock indicator */
.px-low-stock {
  font-size: 13px;
  color: #e97316;
  font-weight: 600;
  padding: 8px 12px;
  text-align: left;
  background: #fff7ed;
  border-radius: 6px;
  border: 1px solid #fed7aa;
  margin-bottom: 8px;
}
.px-low-stock.px-low-stock--out {
  color: #dc2626;
  font-weight: 600;
  background: #fef2f2;
  border-color: #fecaca;
}
.px-low-stock__dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  background: #e97316;
  border-radius: 50%;
  margin-right: 6px;
  vertical-align: middle;
  animation: px-pulse 1.5s ease-in-out infinite;
}
@keyframes px-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.4; }
}

/* OOS info above Notify Me button */
.px-oos-info {
  font-size: 13px;
  color: #666;
  text-align: center;
  padding: 8px 0 4px;
  line-height: 1.4;
}
.px-oos-info strong {
  color: #222;
  font-weight: 600;
}
.px-oos-restock {
  font-size: 12px;
  color: #888;
  font-weight: 400;
  font-style: italic;
}

/* Prominent inline OOS banner — shown above YOUR CONFIGURATION
   when the selected variant is unavailable. Replaces the previous
   small "Item is out of stock" text as the primary OOS signal. */
.px-oos-banner {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  margin: 12px 0;
  padding: 14px 16px;
  background: #fef2f2;
  border: 1px solid #fecaca;
  border-radius: 10px;
  color: #991b1b;
}
.px-oos-banner[hidden] { display: none; }
.px-oos-banner__icon {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: #fee2e2;
  color: #dc2626;
}
.px-oos-banner__text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  line-height: 1.35;
}
.px-oos-banner__title {
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.01em;
  color: #991b1b;
}
.px-oos-banner__sub {
  font-size: 13px;
  color: #7f1d1d;
}

/* 2026-05-12 (Quieter): OOS mirror buttons are now SELECTABLE so the
   customer can click an out-of-stock side to register for Notify Me.
   Previously `pointer-events: none` made the buttons fully inert —
   customers couldn't even hover or click. With the click enabled, the
   click handler sets state.mirror, filterAndAutoSelect detects the
   variant is OOS (existsOos branch), and sets `_mirrorOosGeolock` so
   the cart button renders as "Notify Me". Visual differentiation
   stays: lower opacity + lighter border + the "Out of stock" stock
   indicator chip inside the card. */
.px-mirror--oos {
  opacity: 0.7;
  position: relative;
  border-color: #d1d5db !important;
  cursor: pointer;
}
.px-mirror--oos.active {
  border-color: #111 !important;
  opacity: 1;
}
/* 2026-05-12 (Quieter): mirror buttons reserve space for the stock
   indicator so buttons stay the SAME height whether they're in OOS
   state or available. Without this reservation, adding the indicator
   on click / state change made the button grow taller, causing the
   row to "jump" visually.

   .mirror-card uses an empty pseudo-element to reserve the indicator
   row's height. The real .mirror-stock-indicator slots into the same
   space when present. Net height: identical in both states. */
.mirror-card::after {
  content: '';
  display: block;
  height: 14px;
  margin-top: 4px;
}
.mirror-card:has(.mirror-stock-indicator)::after {
  display: none;
}

.mirror-stock-indicator {
  display: block;
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  margin-top: 4px;
  height: 14px;
  line-height: 14px;
}
.mirror-stock-indicator--oos {
  color: #dc2626;
}
.mirror-stock-indicator--available {
  color: #16a34a;
}

/* OOS Alternatives Panel */
.px-alternatives {
  margin-top: 12px;
  padding: 14px 16px;
  background: #f8f8f8;
  border: 1px solid #e5e5e5;
  border-radius: 10px;
}
.px-alternatives__header {
  margin-bottom: 8px;
}
.px-alternatives__oos-label {
  font-size: 13px;
  color: #666;
  line-height: 1.4;
}
.px-alternatives__title {
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: #222;
  margin-bottom: 10px;
  font-family: 'Space Grotesk', sans-serif;
}
.px-alternatives__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.px-alt-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  background: #fff;
  border: 1px solid #ddd;
  border-radius: 20px;
  cursor: pointer;
  font-size: 13px;
  font-family: 'Inter Tight', sans-serif;
  font-weight: 500;
  color: #222;
  transition: all 0.15s;
}
.px-alt-chip:hover {
  border-color: #222;
  background: #222;
  color: #fff;
}
.px-alt-chip__change {
  font-size: 10px;
  opacity: 0.6;
}
.px-alt-chip:hover .px-alt-chip__change {
  opacity: 0.8;
}

/* Headings */
/* 2026-05-12 (Quieter): section titles ("CHOOSE YOUR TYPE",
   "REAR-VIEW MIRROR POSITION", etc.) — was 14px 600 near-black.
   Now 11px 600 tracked-out gray. Reads as a quiet label rather than
   a heavy heading — matches the rest of the page's rhythm. */
.px-block h4,
.px-lens h4,
.px-wrap h4 {
  font-size: 11px;
  color: #888;
  font-family: 'Space Grotesk', sans-serif;
  margin: 22px 0 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  line-height: 1;
}

.px-model-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
}

#px-color-title {
  font-size: 13px;
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0;
  margin: 16px 0 8px;
  color: #444;
}

.px-model-header h4 {
  margin: 20px 0 10px;
  flex: 1;
  min-width: 0;
}

.px-model-label {
  font-size: 14px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.sizeguidebtn {
  font-size: 12px;
  color: #222;
  text-decoration: underline;
  background: none;
  border: none;
  cursor: pointer;
  white-space: nowrap;
  flex-shrink: 0;
  padding: 0;
}

/* Size Group */
.px-size-group h5 {
  font-size: 12px;
  font-weight: 500;
  color: rgb(34 34 34 / 80%);
  font-family: 'Space Grotesk';
}

/* Legacy icon row — kept for backwards compat */
.px-groups .icon-title-row {
  display: flex;
  gap: 8px;
  margin-bottom: 8px;
  padding-bottom: 8px;
  border-bottom: 1px solid rgb(34 34 34 / 15%);
}

button.px-group.active .icon-title-row {
  border-color: rgb(255 255 255 / 15%);
}

/* Narrow configurator — when using 2/3 or 3/4 gallery width */
/* Uses container query if supported, falls back to media query */

@media (max-width:1380px){
.varient-title-sub {
    align-items: flex-start;
    gap: 8px;
    width: 100%;
    flex-direction: column;
}

.product__icon-item {
    flex: 1;
    flex-direction: column;
    text-align: center;
}

/* Compact lens card in narrow layout */
.px-group {
    padding: 12px 14px;
}

.lens-card .leans-row {
    gap: 6px;
}

.px-groups .icon-title-row {
    margin-bottom: 8px;
    padding-bottom: 8px;
}

.px-group h5 {
    font-size: 13px;
    margin-bottom: 2px;
}

span.px-price {
    font-size: 14px;
}

.lens-card p {
    font-size: 12px;
    line-height: 1.4;
    margin-top: 4px;
}

/* Mirror cards: compact */
.px-row.px-mirror-row button.px-btn {
    padding: 10px;
    max-width: none;
    min-height: auto;
}

.mirror-card h5 {
    font-size: 13px;
}

.mirror-card p {
    font-size: 11px;
}

.mirror-card h6 {
    font-size: 12px;
    margin-top: 6px;
    padding-top: 6px;
}

/* Model buttons */
.px-size-group .px-btn {
    max-width: 80px;
    padding: 3px;
}

/* Headings: tighter */
.px-block h4, .px-lens h4, .px-wrap h4 {
    font-size: 14px;
    margin: 16px 0 8px;
    text-align: left;
}
}

@media (max-width:1024px){
.media__thumb {
    width: 60px;
    height: 60px;
    margin-right: 10px !important;
    margin-block-end: 10px;
}

.varient-title-sub {
    align-items: self-end;
    flex-direction: row;
}
.px-wrap {
    text-align: left;
}

.accordion__wrapper {
    text-align: left;
}
}




@media (max-width:767px){

/* 2026-05-12 (Quieter): mobile lens-type tiles + mirror buttons.
   This block used to override the desktop styles with pre-Quieter
   rules (black-solid mirror-active, 2x2 lens-type grid that conflicted
   with the 5-up grid). Now aligned with the Quieter palette:
   - Lens tiles stay as a grid (5 cols at this breakpoint, drops to
     3 cols below 480px via the earlier media rule at line ~340)
   - Mirror buttons inherit the global stacked-mobile layout from the
     ≤640px rule (cream + black border active, NOT solid black)
   - Locked mirror stays hidden via the global selector
   We keep only the truly mobile-specific tweaks (font sizes, lens-
   card detail). */

.lens-card__name { font-size: 13px; }
.lens-card__price { font-size: 13px; }
.lens-card__sub { font-size: 12px; }
.lens-card__desc { font-size: 12px; }
}

/* Footnote link to reveal locked mirror — uses px-size-expand-link class directly */

/* Mirror out-of-stock notice */
.mirror-oos-notice {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    margin-top: 10px;
    padding: 10px 14px;
    background: #f8f4eb;
    border: 1px solid #e8dfc8;
    border-radius: 8px;
    font-size: 12.5px;
    line-height: 1.5;
    color: #5a4e3a;
}
.mirror-oos-notice__icon {
    flex-shrink: 0;
    font-size: 15px;
    line-height: 1.3;
    color: #b8922e;
}
.mirror-oos-notice__text {
    flex: 1;
}
.mirror-oos-notice__text strong {
    font-weight: 600;
    color: #3d3422;
}
.mirror-oos-reveal {
    color: #3b82f6;
    cursor: pointer;
    font-weight: 500;
    margin-top: 4px;
    display: inline-block;
}
.mirror-oos-reveal:hover {
    text-decoration: underline;
}

/* Addon category hint — WCAG AA contrast fix */
.addon-category-hint {
    color: #666 !important;
}

/* Mirror card font — use Space Grotesk for consistency */
.mirror-card h5 {
    font-family: 'Space Grotesk', sans-serif !important;
}
.mirror-card p {
    font-family: 'Space Grotesk', sans-serif !important;
}

/* Model buttons — bigger on mobile: 4 per row */
.px-size-group .px-btn {
    max-width: calc(25% - 6px) !important;
    flex: 0 0 calc(25% - 6px);
    padding: 3px;
}

.px-size-group .px-row {
    gap: 8px;
}

/* Mirror cards — (handled above in stacked layout) */

img.quantity-review-images {
    max-width: 200px;
}

/* Section headings */
.px-block h4, .px-lens h4, .px-wrap h4 {
    font-size: 14px;
    margin: 16px 0 8px;
}
}

.addon-card.disabled {
  opacity: 0.6;
  cursor: not-allowed;
  pointer-events: none;
  position: relative;
}

.addon-card.disabled a,
.addon-card.disabled button {
  pointer-events: none;
}

.addon-card.disabled::after {
  content: attr(data-tooltip);
  position: absolute;
  bottom: 110%;
  left: 50%;
  transform: translateX(-50%);
  background: #000;
  color: #fff;
  font-size: 12px;
  padding: 6px 10px;
  border-radius: 4px;
  white-space: nowrap;
  opacity: 0;
  transition: opacity 0.2s ease;
}

.addon-card.disabled:hover::after {
  opacity: 1;
}