/**
 * Shop Page Token System — Editor4
 *
 * Token-driven styling for shop pages (Products/Categories/Product Detail/etc).
 *
 * ─── ARCHITECTURE ─────────────────────────────────────────────────────
 * Two layers of variables, one direction of flow:
 *
 *   Theme vars   (--theme-*)   ← written by theme_css.php / e4_theme_inline_css
 *                                from theme.json (5 colours + 3 fonts)
 *        │
 *        ▼
 *   Token vars   (--so-*)      ← defined in THIS file at :root using
 *                                var(--theme-<role>, <fallback>) for every
 *                                token that the mapping JSON declares as
 *                                theme-linked. Standalone tokens (sizes,
 *                                structural borders) have plain values.
 *        │
 *        ▼
 *   Page rules   [data-so-role] ← consume var(--so-*) normally.
 *
 * SINGLE SOURCE OF TRUTH for "which token follows which theme role" is
 * assets/editor4/registry/token-registry.v1.json (the mapping JSON was
 * retired at SOAK-C exit, b44fcf5d 3 Sep 2026). If you add/change a
 * linkage, mirror the change here by rewriting the affected line to
 *   --so-<name>: var(--theme-<role>, <fallback>);
 *
 * Per-tenant CustomStyles.css MUST NOT re-declare theme-linked tokens at
 * :root — that would freeze them with hardcoded hex and defeat live
 * Theme Panel updates. save.php strips them on every page save as a
 * safety net (see e4_strip_theme_linked_tokens). CustomStyles.css is
 * only for page-scoped overrides (e.g. user edits a specific element
 * on a specific page).
 *
 * TOKEN NAMING: --so-{component}-{property}
 *   Example: --so-product-card-bg, --so-pd-title-color
 */

/* =============================================
   TOKEN DEFINITIONS — Default Values
   These can be overridden by tenant CSS
   ============================================= */

:root {
  /* --- Page-Level Tokens (SP) --- */
  /* G25 — overall shop page background, wired to the theme's "background"
     colour role (6th colour, added alongside primary/secondary/accent/text/surface).
     Each theme ships its own default background; user can customise via
     the Theme Panel. The transparent fallback preserves the pre-theme
     behaviour if --theme-background is ever undefined. */
  --so-shop-page-bg: var(--theme-background, transparent);
  --so-shop-page-text: #212529;
  --so-shop-page-font: inherit;

  /* --- Page Link Tokens (G1, G2) --- */
  --so-page-link-color: var(--theme-primary, #1B202F);
  --so-page-link-font: var(--theme-font-secondary, Josefin Sans, sans-serif);
  --so-page-link-font-size: 18px;
  --so-page-link-hover: var(--theme-accent, #609CEC);

  /* --- Meta Text Tokens (G8) --- */
  --so-meta-text-color: var(--theme-text, #777D80);
  --so-meta-text-font: var(--theme-font-secondary, Josefin Sans, sans-serif);
  --so-meta-text-font-size: 16px;

  /* --- Breadcrumb Tokens (G3) --- */
  --so-breadcrumb-color: var(--theme-text, #777D80);
  --so-breadcrumb-font: var(--theme-font-secondary, Josefin Sans, sans-serif);
  --so-breadcrumb-font-size: 16px;
  --so-breadcrumb-text: #777D80;
  --so-breadcrumb-link: #1B202F;
  --so-breadcrumb-link-hover: #609CEC;
  --so-breadcrumb-separator: #777D80;

  /* --- Search Form Tokens (SF) — Locked to Bootstrap defaults --- */
  --so-search-input-bg: #fff;
  --so-search-input-border: #ced4da;
  --so-search-input-text: #495057;
  --so-search-button-bg: #e9ecef;
  --so-search-button-icon: #6c757d;

  /* --- Categories Sidebar Tokens (CS) --- */
  --so-categories-header-bg: var(--theme-primary, #1B202F);
  --so-categories-header-text: #FFFFFF;
  --so-categories-title-color: #BCBCBC;
  --so-categories-title-font: var(--theme-font-display, Hanuman, serif);
  --so-categories-title-font-size: 20px;
  --so-categories-item-bg: transparent;
  --so-categories-item-border: rgba(0, 0, 0, 0.125);
  --so-categories-link-color: var(--theme-primary, #1B202F);
  --so-categories-link-font: var(--theme-font-secondary, Josefin Sans, sans-serif);
  --so-categories-link-font-size: 18px;
  --so-categories-link-hover: var(--theme-accent, #609CEC);
  --so-categories-list-bg: var(--theme-surface, #FFFFFF);
  --so-categories-sidebar-border: rgba(0, 0, 0, 0.125);

  /* --- Grid Header Tokens (GH) / Section Heading (G5) --- */
  --so-section-heading-color: var(--theme-secondary, #578DD5);
  --so-section-heading-font: var(--theme-font-display, Hanuman, serif);
  --so-section-heading-font-size: 28px;
  --so-grid-title-text: #578DD5;
  --so-grid-title-size: 28px;
  --so-grid-title-weight: 500;
  --so-grid-count-text: #777D80;
  --so-grid-divider-color: rgba(0, 0, 0, 0.1);
  --so-carousel-btn-bg: #609CEC;
  --so-carousel-btn-text: #fff;
  --so-carousel-btn-hover-bg: #578DD5;

  /* --- Product Card Tokens (PC) --- */
  --so-product-card-bg: var(--theme-surface, #FFFFFF);
  --so-product-card-border: #e1e1e1;
  /* COMPAT ALIAS — May 2026 var-name unification.
     Legacy code (older tenant CustomStyles.css that haven't been regenerated
     since the rename) reads --so-product-border-color. This alias keeps
     those rules resolving correctly to the canonical token. Safe to delete
     after ~3 months of stability (≈Aug 2026) once all tenants have
     re-saved via theme panel and CustomStyles.css has been regenerated. */
  --so-product-border-color: var(--so-product-card-border);
  --so-product-card-radius: 4px;
  --so-product-card-shadow: none;
  --so-product-card-padding: 10px;
  --so-product-card-hover-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  --so-product-card-info-hover-bg: #e8e8e8;

  /* --- Product Image Tokens --- */
  --so-product-image-bg: transparent;
  --so-product-image-radius: 0;
  --so-product-image-max-height: 180px;

  /* --- Product Text Tokens --- */
  --so-product-title-color: var(--theme-primary, #1B202F);
  --so-product-title-font: var(--theme-font-secondary, Josefin Sans, sans-serif);
  --so-product-title-font-size: 18px;
  --so-product-title-text: #1B202F;
  --so-product-title-size: 18px;
  --so-product-title-weight: 400;
  --so-product-title-line-height: 1.4;
  --so-product-price-color: var(--theme-accent, #609CEC);
  --so-product-price-font: var(--theme-font-primary, Nobile, sans-serif);
  --so-product-price-font-size: 14px;
  --so-product-price-text: #609CEC;
  --so-product-price-size: 14px;
  --so-product-price-weight: 700;
  --so-product-was-price-text: #999;
  --so-product-from-text: #777D80;

  /* --- Stock Badge Tokens (SB) --- */
  --so-stock-in-bg: #28a745;
  --so-stock-in-text: #fff;
  --so-stock-out-bg: #dc3545;
  --so-stock-out-text: #fff;
  --so-stock-badge-radius: 3px;
  --so-stock-badge-padding: 4px 8px;
  --so-stock-badge-size: 11px;

  /* --- Per-Page Selector Tokens (PP) — Locked to Bootstrap defaults --- */
  --so-perpage-text: #6c757d;
  --so-perpage-select-bg: #fff;
  --so-perpage-select-border: #ced4da;
  --so-perpage-select-text: #495057;

  /* --- Pagination Tokens (G23, G24) --- */
  --so-pagination-inner-color: var(--theme-primary, #1B202F);
  --so-pagination-outer-color: var(--theme-surface, #FFFFFF);

  /* --- Button/CTA Tokens --- */
  --so-button-primary-bg: var(--theme-primary, #1B202F);
  --so-button-primary-text: #FFFFFF;
  --so-button-primary-border: #1B202F;
  --so-button-radius: 4px;
  --so-button-disabled-opacity: 0.65;

  /* --- Spacing Tokens --- */
  --so-section-spacing-y: 20px;
  --so-card-gap: 15px;
  --so-row-margin-bottom: 20px;

  /* --- Visibility Tokens (Prompt 3) --- */
  /* These control element visibility via the Shop Panel toggles */
  --so-breadcrumb-display: flex;
  --so-categories-display: block;
  --so-stock-badge-display: block;
  --so-search-display: block;
  /* --- Theme-driven tokens (added from theme-token-mapping.json).
     Kept here so the mapping JSON is the single source of truth for
     which token follows which theme role. CustomStyles.css must NOT
     re-declare these at :root — page-scoped overrides only. --- */
  --so-page-title-font: var(--theme-font-primary, Nobile, sans-serif); /* G4 */
  --so-page-title-font-size: 48px; /* G4 — was missing; matches theme-token-mapping.json fallback */
  --so-page-title-color: var(--theme-primary, #1B202F); /* G4 */
  --so-paragraph-text-font: var(--theme-font-secondary, Josefin Sans, sans-serif); /* G6 */
  --so-paragraph-text-color: var(--theme-text, #777D80); /* G6 */
  --so-form-label-font: var(--theme-font-primary, Nobile, sans-serif); /* G7 */
  --so-form-label-color: var(--theme-accent, #609CEC); /* G7 */
  --so-button-process-bg: var(--theme-accent, #609CEC); /* G11 */
  --so-button-process-hover-bg: var(--theme-secondary, #578DD5); /* G12 */
  --so-button-process-color: var(--theme-surface, #FFFFFF); /* G13 */
  --so-button-process-hover-color: var(--theme-surface, #FFFFFF); /* G14 */
  --so-button-default-bg: var(--theme-surface, #FFFFFF); /* G15 */
  --so-button-default-font: var(--theme-font-primary, Nobile, sans-serif); /* G17 */
  --so-button-default-color: var(--theme-primary, #1B202F); /* G17 */
  --so-button-default-hover-color: var(--theme-primary, #1B202F); /* G18 */
  /* PA1/PA2 — Add-to-cart popup (Product-page LOCAL tokens, #222 25 Aug 2026).
     Neutral defaults: the popup previously resolved through G5/G6 (heading)
     and PD2/G5 (title+price) to exactly Display / Text / 28px and
     Display / Secondary / 28px — these chains render the same bytes until a
     merchant authors an override (written only by a real panel edit). */
  --so-cartmodal-heading-font: var(--theme-font-display, Hanuman, serif); /* PA1 */
  --so-cartmodal-heading-color: var(--theme-text, #777D80); /* PA1 */
  --so-cartmodal-title-font: var(--theme-font-display, Hanuman, serif); /* PA2 */
  --so-cartmodal-title-color: var(--theme-secondary, #578DD5); /* PA2 */
  --so-button-primary-hover-bg: var(--theme-accent, #609CEC); /* G20 */
  --so-button-primary-font: var(--theme-font-primary, Nobile, sans-serif); /* G21 */
  --so-button-primary-color: var(--theme-surface, #FFFFFF); /* G21 */
  --so-button-primary-hover-color: var(--theme-surface, #FFFFFF); /* G22 */
  --so-auth-panel-heading-font: var(--theme-font-display, Hanuman, serif); /* LP2 */
  --so-auth-panel-heading-color: var(--theme-accent, #609CEC); /* LP2 */
  --so-form-input-focus-shadow: var(--theme-accent, #609CEC); /* LP3 */
  --so-pd-title-font: var(--theme-font-secondary, Josefin Sans, sans-serif); /* PD1 */
  --so-pd-title-color: var(--theme-text, #777D80); /* PD1 */
  --so-pd-sectionheading-font: var(--theme-font-display, Hanuman, serif); /* PD2 */
  --so-pd-sectionheading-color: var(--theme-secondary, #578DD5); /* PD2 */
  --so-pd-panel-heading-font: var(--theme-font-display, Hanuman, serif); /* PD3 */
  --so-pd-details-label-font: var(--theme-font-primary, Nobile, sans-serif); /* PD4 */
  --so-pd-details-label-color: var(--theme-accent, #609CEC); /* PD4 */
  --so-pd-tab-text-font: var(--theme-font-primary, Nobile, sans-serif); /* PD5 */
  --so-pd-tab-text-color: var(--theme-accent, #609CEC); /* PD5 */
  --so-pd-tab-bg: var(--theme-surface, #FFFFFF); /* PD6 */

}


/* =============================================
   TOKEN MAPPINGS — Apply Tokens to DOM
   Selectors use data-so-role attributes
   ============================================= */

/* --- Page-Level Styling --- */
/* Apply the theme background at the html + body level so the ENTIRE
   shop page picks it up — not just the .so-shop-page inner wrapper.
   Without this, content above/below the wrapper (headers, footers,
   any gutter outside the container) would still show the browser-
   default white.
   html is included because some Bootstrap/GrapesJS setups let <html>
   show through when the canvas iframe's body doesn't fully cover the
   viewport (observed on dark themes like Midnight as a white strip
   to the left of the main content). Scoped to shop-tokens.css which
   only loads on shop pages (preview + live + editor canvas), so this
   doesn't leak into admin/backend views. */
html,
body {
  background-color: var(--theme-background, var(--so-shop-page-bg, #FFFFFF));
}
.so-shop-page {
  background-color: var(--so-shop-page-bg);
  color: var(--so-shop-page-text);
  font-family: var(--so-shop-page-font);
}


/* --- Global: no underlines on hover for any shop page links --- */
.so-shop-page a:hover,
.so-shop-page [data-so-role*="link"]:hover,
.so-shop-page [data-so-role*="page-link"]:hover {
  text-decoration: none;
}

/* --- Breadcrumb Styling --- */
[data-so-role="breadcrumb-text"] {
  color: var(--so-breadcrumb-text);
}

[data-so-role="breadcrumb-link"] {
  color: var(--so-breadcrumb-link);
  text-decoration: none;
}

[data-so-role="breadcrumb-link"]:hover {
  color: var(--so-breadcrumb-link-hover);
  text-decoration: none;
}


/* --- Search Form Styling --- */
[data-so-role="search-input"] {
  background-color: var(--so-search-input-bg);
  border-color: var(--so-search-input-border);
  color: var(--so-search-input-text);
}

[data-so-role="search-button"] {
  background-color: var(--so-search-button-bg);
}

[data-so-role="search-button"] i {
  color: var(--so-search-button-icon);
}


/* --- Categories Sidebar Styling --- */
[data-so-role="categories-sidebar"] {
  border-color: var(--so-categories-sidebar-border);
}

[data-so-role="categories-header"] {
  background-color: var(--so-categories-header-bg);
}

[data-so-role="categories-title"] {
  color: var(--so-categories-title-color, var(--so-categories-header-text));
  font-family: var(--so-categories-title-font);
  font-size: var(--so-categories-title-font-size);
  margin: 0;
  padding: 0.5rem 0;
}

[data-so-role="categories-item"] {
  background-color: var(--so-categories-item-bg);
  border-color: var(--so-categories-item-border);
  padding: 0.75rem 1rem;
}

[data-so-role="categories-link"] {
  color: var(--so-categories-link-color, var(--so-categories-link-text, #1B202F));
  font-family: var(--so-categories-link-font);
  font-size: var(--so-categories-link-font-size);
  text-decoration: none;
  display: block;
}

[data-so-role="categories-link"]:hover {
  color: var(--so-categories-link-hover);
}


/* --- Grid Header / Section Heading Styling ---
   #285 (4 Sep 2026): SYSTEM-SCOPED (contract §5 — no bare canvas rule may
   set font/size by role). Shop grid titles keep this styling; canvas
   section headings get colour from data-so-theme-role instead. */
.so-shop-page [data-so-role="grid-title"],
.so-shop-page [data-so-role="section-heading"] {
  color: var(--so-section-heading-color, var(--so-grid-title-text));
  font-family: var(--so-section-heading-font);
  font-size: var(--so-section-heading-font-size, var(--so-grid-title-size));
  font-weight: var(--so-grid-title-weight);
}

[data-so-role="grid-count"] {
  color: var(--so-grid-count-text);
}

[data-so-role="grid-divider"] {
  border-color: var(--so-grid-divider-color);
  margin: 1rem 0;
}

[data-so-role="carousel-prev"],
[data-so-role="carousel-next"] {
  background-color: var(--so-carousel-btn-bg);
  color: var(--so-carousel-btn-text);
  border-color: var(--so-carousel-btn-bg);
}

[data-so-role="carousel-prev"]:hover,
[data-so-role="carousel-next"]:hover {
  background-color: var(--so-carousel-btn-hover-bg);
  border-color: var(--so-carousel-btn-hover-bg);
}


/* --- Pagination Styling (replaces carousel controls in preview) --- */
[data-so-role="pagination-nav"] {
  margin: 0;
}

[data-so-role="pagination-nav"] .pagination {
  margin: 0;
}

/* Active page — G23 background (dark) + G24 text (light) */
[data-so-role="pagination-inner"] {
  background-color: var(--so-pagination-inner-color) !important;
  border-color: var(--so-pagination-inner-color) !important;
  color: var(--so-pagination-outer-color) !important;
}

/* Inactive pages — G24 background (light) + G23 text (dark) */
[data-so-role="pagination-outer"] {
  color: var(--so-pagination-inner-color) !important;
  background-color: var(--so-pagination-outer-color) !important;
  border-color: #dee2e6 !important;
}

/* Focus ring — derived from active/inner color */
[data-so-role="pagination-inner"]:focus,
[data-so-role="pagination-inner"]:active,
[data-so-role="pagination-outer"]:focus,
[data-so-role="pagination-outer"]:active {
  box-shadow: 0 0 0 0.2rem color-mix(in srgb, var(--so-pagination-inner-color) 30%, transparent) !important;
  outline: none !important;
}

[data-so-role="pagination-outer"]:hover {
  text-decoration: none;
  color: var(--so-pagination-outer-color, #fff) !important;
  background-color: color-mix(in srgb, var(--so-pagination-inner-color, #1B202F) 70%, white) !important;
  border-color: color-mix(in srgb, var(--so-pagination-inner-color, #1B202F) 70%, white) !important;
}


/* --- Product Card Styling ---
   Fallbacks are intentional: if shop-tokens.css fails to load on a given
   surface (e.g. editor canvas iframe lost the :root tokens — 24 May 2026
   featured-products dark-border bug), `var(--undefined)` would otherwise
   resolve to the property's initial value, which for border-color is
   `currentColor` → Bootstrap 5's #212529 body colour → ugly dark line.
   Fallbacks guarantee the categories-page look even when tokens go AWOL. */
[data-so-role="product-card"] {
  background-color: var(--so-product-card-bg, #ffffff);
  border: 1px solid var(--so-product-card-border, #e1e1e1);
  border-radius: var(--so-product-card-radius, 4px);
  box-shadow: var(--so-product-card-shadow, none);
  padding: var(--so-product-card-padding, 10px);
  margin-bottom: var(--so-row-margin-bottom);
  /* Visual consistency: equal height cards */
  display: flex;
  flex-direction: column;
  height: 100%;
}

/* Product Card Hover — CSS-only, no JS required */
.so-shop-page [data-so-role="product-card"]:hover {
  box-shadow: var(--so-product-card-hover-shadow);
}

/* Product Card Info Section — fills card width edge to edge */
[data-so-role="product-card-bg"] {
  margin-left: calc(-1 * var(--so-product-card-padding, 10px));
  margin-right: calc(-1 * var(--so-product-card-padding, 10px));
  margin-bottom: calc(-1 * var(--so-product-card-padding, 10px));
  padding-left: var(--so-product-card-padding, 10px);
  padding-right: var(--so-product-card-padding, 10px);
  padding-bottom: var(--so-product-card-padding, 10px);
  border-radius: 0 0 var(--so-product-card-radius, 4px) var(--so-product-card-radius, 4px);
  transition: background-color 0.2s ease;
}

/* Product Card Info Section Hover — background shading fills to card edges */
.so-shop-page [data-so-role="product-card"]:hover [data-so-role="product-card-bg"] {
  background-color: var(--so-product-card-info-hover-bg);
}


/* --- Product Image Styling --- */
[data-so-role="product-image-wrapper"] {
  background-color: var(--so-product-image-bg);
  text-align: center;
  padding: 10px;
}

[data-so-role="product-image-cell"] {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: var(--so-product-image-max-height);
}

[data-so-role="product-image"] {
  max-height: var(--so-product-image-max-height);
  max-width: 100%;
  height: auto;
  border-radius: var(--so-product-image-radius);
  object-fit: contain;
}


/* --- Product Text Styling --- */
[data-so-role="product-grid-title"] {
  color: var(--so-product-title-color, var(--so-product-title-text));
  font-family: var(--so-product-title-font);
  font-size: var(--so-product-title-font-size, var(--so-product-title-size));
  font-weight: var(--so-product-title-weight);
  line-height: var(--so-product-title-line-height);
  /* Visual consistency: prevent title overflow */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
  min-height: calc(var(--so-product-title-font-size, var(--so-product-title-size)) * var(--so-product-title-line-height) * 2);
}

[data-so-role="price-current"] {
  color: var(--so-product-price-color, var(--so-product-price-text));
  font-family: var(--so-product-price-font);
  font-size: var(--so-product-price-font-size, var(--so-product-price-size));
  font-weight: var(--so-product-price-weight);
}

[data-so-role="price-was"] {
  color: var(--so-product-was-price-text);
  text-decoration: line-through;
  font-size: 0.9em;
}

[data-so-role="price-from"] {
  color: var(--so-product-from-text);
  font-size: 0.9em;
  font-style: italic;
}

[data-so-role="product-info"] {
  /* Visual consistency: push price info to bottom */
  margin-top: auto;
  padding-top: 10px;
}


/* --- Stock Badge Styling --- */
[data-so-role="stock-badge"] {
  position: absolute;
  top: 5px;
  right: 5px;
  padding: var(--so-stock-badge-padding);
  border-radius: var(--so-stock-badge-radius);
  font-size: var(--so-stock-badge-size);
  font-weight: 600;
  text-transform: uppercase;
  z-index: 1;
}

[data-so-role="stock-badge"][data-stock-status="in-stock"] {
  background-color: var(--so-stock-in-bg);
  color: var(--so-stock-in-text);
}

[data-so-role="stock-badge"][data-stock-status="out-of-stock"] {
  background-color: var(--so-stock-out-bg);
  color: var(--so-stock-out-text);
}


/* --- Per-Page Selector Styling --- */
[data-so-role="perpage-text"] {
  color: var(--so-perpage-text);
}

[data-so-role="perpage-select"] {
  background-color: var(--so-perpage-select-bg);
  border-color: var(--so-perpage-select-border);
  color: var(--so-perpage-select-text);
}


/* =============================================
   VISUAL CONSISTENCY IMPROVEMENTS
   CSS-only enhancements for balanced layout
   ============================================= */

/* Consistent product card column spacing */
.so-shop-page [data-so-role="product-card-col"] {
  margin-bottom: var(--so-card-gap);
  display: flex;
}

/* Ensure all product links fill their column */
.so-shop-page [data-so-role="product-link"] {
  display: flex;
  flex-direction: column;
  width: 100%;
  text-decoration: none;
}

/* Product row spacing */
.so-shop-page [data-so-role="product-row"] {
  margin-left: calc(var(--so-card-gap) / -2);
  margin-right: calc(var(--so-card-gap) / -2);
}

.so-shop-page [data-so-role="product-card-col"] {
  padding-left: calc(var(--so-card-gap) / 2);
  padding-right: calc(var(--so-card-gap) / 2);
}

/* Product info price area centering */
[data-so-role="product-info-price"] {
  text-align: center;
}

/* =============================================
   PRODUCT DETAIL PAGE TOKENS (PD1-PD7)
   ============================================= */

/* Product Image Gallery — first image large, rest thumbnails */
.fancy-box-container > a:first-child {
  display: block;
  text-align: center;
  max-width: 100%;
  max-height: 400px;
  margin-bottom: 10px;
}
.fancy-box-container > a:first-child img {
  max-width: 380px;
  max-height: 380px;
  display: inline-block;
  margin: 0;
  border: none;
  padding: 0;
}
/* Thumbnail wrapper — centre under main image */
.fancy-box-container > div {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  margin-top: 12px;
}
/* Thumbnail images (all gallery images except the first) */
.fancy-box-container .so-product-thumbnails a img,
.fancy-box-container > a:not(:first-child) img,
.fancy-box-container > div a img {
  width: 80px;
  height: 80px;
  max-height: none;
  max-width: none;
  border: 1px solid #ddd;
  padding: 4px;
  margin: 0;
  cursor: pointer;
  object-fit: cover;
  border-radius: 4px;
  transition: border-color 0.2s;
}
.fancy-box-container > div a img:hover {
  border-color: var(--theme-accent, #609CEC);
}
/* Thumbnail overflow: hide extras beyond cap, +N overlay on last visible */
.fancy-box-container .so-thumb-hidden { display: none !important; }
.fancy-box-container .so-thumb-more { position: relative; cursor: pointer; }
.fancy-box-container .so-thumb-more-overlay {
  position: absolute; top: 0; left: 0; width: 80px; height: 80px;
  background: rgba(0,0,0,0.6); color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-size: 18px; font-weight: 700; pointer-events: none;
  border-radius: 4px;
}

/* PD1 — Product Title */
[data-so-role="product-title"] {
  font-family: var(--so-pd-title-font, Josefin Sans, sans-serif) !important;
  font-size: var(--so-pd-title-font-size, 28px) !important;
  color: var(--so-pd-title-color, #777D80) !important;
  font-weight: normal !important;
}

/* PD1 — Price Text (shared styling with title) */
[data-so-role="product-price"] {
  font-family: var(--so-pd-title-font, Josefin Sans, sans-serif) !important;
  font-size: var(--so-pd-title-font-size, 28px) !important;
  color: var(--so-pd-title-color, #777D80) !important;
  font-weight: normal !important;
}

/* PD2 — Section Headings ("Product Description", "Other Items You Might Like") */
[data-so-role="product-section-heading"],
[data-so-role="product-sectionheading"] { /* second spelling = compatibility alias for previously saved content (#222) — canonical is product-section-heading */
  font-family: var(--so-pd-sectionheading-font, Hanuman, serif) !important;
  font-size: var(--so-pd-sectionheading-font-size, 28px) !important;
  color: var(--so-pd-sectionheading-color, #578DD5) !important;
  font-weight: normal !important;
}

/* PD3 — Panel Heading ("Shipping", etc.) */
[data-so-role="product-panel-heading"] {
  font-family: var(--so-pd-panel-heading-font, Hanuman, serif) !important;
  font-size: var(--so-pd-panel-heading-font-size, 20px) !important;
  color: var(--so-pd-panel-heading-color, #BCBCBC) !important;
  font-weight: normal !important;
}

/* PD4 — Product Details Labels — Primary Font, Accent colour, 14px */
/* Bold is NOT global — applied locally where spreadsheet specifies FORCE BOLD */
[data-so-role="product-details-label"] {
  font-family: var(--so-pd-details-label-font, Nobile, sans-serif);
  font-size: var(--so-pd-details-label-font-size, 14px);
  color: var(--so-pd-details-label-color, #609CEC);
  font-weight: bold !important; /* PD4 workbook lock (REV G.4 "bold") — #222 */
}

/* PD4 — Product SKU — caps per spreadsheet */
[data-so-role="product-sku"] {
  font-family: var(--so-pd-details-label-font, Nobile, sans-serif);
  font-size: var(--so-pd-details-label-font-size, 14px);
  color: var(--so-pd-details-label-color, #609CEC);
  text-transform: uppercase;
  font-weight: normal;
}

/* PD5 — Tab Text */
[data-so-role="product-tab-text"] {
  font-family: var(--so-pd-tab-text-font, Nobile, sans-serif);
  font-size: var(--so-pd-tab-text-font-size, 14px);
  color: var(--so-pd-tab-text-color, #609CEC);
}

/* PD1 — "(Incl. VAT)" text — force Accent colour, PD1 size (28px), not bold */
.product_details_text,
[data-so-role="product-vat-text"] {
  font-family: var(--so-pd-title-font, Josefin Sans, sans-serif) !important;
  font-size: var(--so-pd-title-font-size, 28px) !important;
  color: var(--so-pd-details-label-color, #609CEC) !important;
  font-weight: normal !important;
}

/* Prevent product detail data flash — hide until variant JS completes */
.so-shop-page .product_title_price,
.so-shop-page #product_stock_availability {
  transition: opacity 0.15s ease;
}

/* G6 — Paragraph Text — Secondary Font, Text colour, 16px.
   #285 (4 Sep 2026): SYSTEM-SCOPED. The bare global form of this rule was the
   accidental hard lock that silently defeated merchant typography edits AND
   16 block-template authored values (contract §5). The !important locks now
   apply ONLY on explicit system surfaces: .so-shop-page (every shop system
   page wrapper) and .cart_product_row (the cart row partial, which renders
   outside .so-shop-page). Editable canvas/published block text is governed
   by Text Style presets (typography) + data-so-theme-role (colour) instead —
   see EDITOR4_STYLE_OWNERSHIP_AND_RESET_CONTRACT.md. NO bare canvas rule is
   retained by ruling. */
.so-shop-page [data-so-role="paragraph-text"],
.so-shop-page [data-so-role="paragraph-text"] strong,
.so-shop-page [data-so-role="paragraph-text"] p,
.cart_product_row [data-so-role="paragraph-text"],
.cart_product_row [data-so-role="paragraph-text"] strong,
.cart_product_row [data-so-role="paragraph-text"] p {
  font-family: var(--so-paragraph-text-font, Josefin Sans, sans-serif) !important;
  font-size: var(--so-paragraph-text-font-size, 16px) !important;
  color: var(--so-paragraph-text-color, #777D80) !important;
}

/* G6 — "See Shipping Info below" — italic, Secondary Font, Text colour */
[data-so-role="product-info-text"] {
  font-family: var(--so-paragraph-text-font, Josefin Sans, sans-serif);
  font-size: 16px;
  color: var(--so-paragraph-text-color, #777D80);
  font-style: italic;
}

/* G6 — "Stock Available" — forced green/red per spreadsheet.
   JC 28 Aug: the colour is CLASS-driven (so-stock-in / so-stock-out) so the
   editor sample, saved shell HTML and the live variant JS all agree — an
   inline style is no longer the only carrier (it went missing on saved pages
   and "Out of Stock" rendered black). */
[data-so-role="product-stock-text"] {
  font-size: 14px;
}
[data-so-role="product-stock-text"].so-stock-in,
#product_stock_availability.so-stock-in { color: #22b14c !important; }
[data-so-role="product-stock-text"].so-stock-out,
#product_stock_availability.so-stock-out { color: #FF0000 !important; }   /* same red as the live variant JS */

/* PD6 — Tab Background */
[data-so-role="product-tab"] {
  background-color: var(--so-pd-tab-bg, #FFFFFF);
  cursor: pointer;
}

/* PD7 — Tab Background Hover */
[data-so-role="product-tab"]:hover {
  background-color: var(--so-pd-tab-hover-bg, #F5F5F5);
}

/* PD3 — Tab Content Sub-Headings ("GENERAL", "DIMENSIONS") — FORCE CAPITALS */
[data-so-role="pd-sub-heading"] {
  font-family: var(--so-pd-panel-heading-font, Hanuman, serif) !important;
  font-size: var(--so-pd-panel-heading-font-size, 20px) !important;
  color: var(--so-pd-panel-heading-color, #BCBCBC) !important;
  text-transform: uppercase !important;
  font-weight: normal !important;
}

/* PD5 — Details Tab Table Label (Left Column) — Primary Font, Accent, PD7 bg */
[data-so-role="pd-table-label"] {
  font-family: var(--so-pd-tab-text-font, Nobile, sans-serif) !important;
  font-size: var(--so-pd-tab-text-font-size, 14px) !important;
  color: var(--so-pd-tab-text-color, #609CEC) !important;
  background-color: var(--so-pd-tab-hover-bg, #F5F5F5) !important;
}
[data-so-role="pd-table-label"] p {
  font-family: inherit !important;
  font-size: inherit !important;
  color: inherit !important;
}

/* G6 — Details Tab Table Value (Right Column) — Secondary Font, Text */
[data-so-role="pd-table-value"] {
  font-family: var(--so-paragraph-text-font, Josefin Sans, sans-serif) !important;
  font-size: var(--so-paragraph-text-font-size, 16px) !important;
  color: var(--so-paragraph-text-color, #777D80) !important;
}
[data-so-role="pd-table-value"] p {
  font-family: inherit !important;
  font-size: inherit !important;
  color: inherit !important;
}

/* PD7 — Accordion Header Background — #F5F5F5 */
.product-shipping-accordian .accordion-button,
.product-shipping-accordian .accordion-header {
  background-color: var(--so-pd-tab-hover-bg, #F5F5F5) !important;
}

/* PD3 — Accordion Content Headings (method names inside accordion body) */
[data-so-role="pd-accordion-heading"] {
  font-family: var(--so-pd-panel-heading-font, Hanuman, serif) !important;
  font-size: var(--so-pd-panel-heading-font-size, 20px) !important;
  color: var(--so-pd-panel-heading-color, #BCBCBC) !important;
  font-weight: normal !important;
}

/* G6 — Accordion Content Text (prices, descriptions inside accordion body) */
[data-so-role="pd-accordion-text"] {
  font-family: var(--so-paragraph-text-font, Josefin Sans, sans-serif) !important;
  font-size: var(--so-paragraph-text-font-size, 16px) !important;
  color: var(--so-paragraph-text-color, #777D80) !important;
}

/* G11 — Process Button (shared across all process buttons) */
[data-so-role="button-process"] {
  background-color: var(--so-button-process-bg, #609CEC);
  border-color: var(--so-button-process-bg, #609CEC);
  color: var(--so-button-process-color, #FFFFFF);
  font-size: var(--so-button-process-font-size, 14px);
}

/* Restore .btn-block (removed in Bootstrap 5, still used across all shop pages) */
.btn-block {
  display: block;
  width: 100%;
}

/* Product detail Add to Cart — max-width cap (inline style gets stripped by GrapesJS on save) */
#product_add_cart {
  max-width: 300px;
}
[data-so-role="button-process"]:hover {
  background-color: var(--so-button-process-hover-bg, #578DD5);
  border-color: var(--so-button-process-hover-bg, #578DD5);
  color: var(--so-button-process-hover-color, #FFFFFF);
}

/* G11-G14 — Process Button focus/active states (override BS .btn-success green halo).
   !important is needed because BS5's :not(.btn-check)+.btn:active and
   .btn:first-child:active rules have specificity 0,0,3,0 — higher than plain
   [data-so-role="button-process"]:active. */
[data-so-role="button-process"]:focus,
[data-so-role="button-process"]:focus-visible,
[data-so-role="button-process"]:active,
[data-so-role="button-process"].active {
  background-color: var(--so-button-process-hover-bg, #578DD5) !important;
  border-color:     var(--so-button-process-hover-bg, #578DD5) !important;
  color:            var(--so-button-process-hover-color, #FFFFFF) !important;
  box-shadow:       0 0 0 0.25rem rgba(96, 156, 236, 0.5) !important;
  outline: 0 !important;
}

/* Add to Cart / Select Options button — Accent outline, inverts on hover */
[data-so-role="add-to-cart-btn"] {
  background: transparent !important;
  color: var(--theme-accent, #609CEC) !important;
  border: 1px solid var(--theme-accent, #609CEC) !important;
  border-radius: 4px;
  padding: 5px 14px;
  font-size: 13px;
  cursor: pointer;
  transition: all 0.2s ease;
  position: relative;
  z-index: 2;
}
[data-so-role="add-to-cart-btn"]:hover {
  background: var(--theme-accent, #609CEC) !important;
  color: #fff !important;
  border-color: var(--theme-accent, #609CEC) !important;
}

/* Section spacing */
.so-shop-page [data-so-role="main-content-row"] {
  padding-top: var(--so-section-spacing-y);
  padding-bottom: var(--so-section-spacing-y);
}

/* =============================================
   CART MODAL TOKENS (PA1, PA2, G6, G9, G10, G15-G18)
   ============================================= */

/* PA1 — Cart Modal Heading ("Item Added to Cart!") — Display Font, Text, 28px
   (was 20px since commit c3a1704 — transcription error, fixed 18 Apr 2026 to match Rev G spec) */
[data-so-role="cartmodal-heading"] {
  /* PA1 — own token (#222); fallback chain keeps the pre-#222 rendering */
  font-family: var(--so-cartmodal-heading-font, var(--so-section-heading-font, Hanuman, serif)) !important;
  font-size: var(--so-cartmodal-heading-font-size, 28px) !important;
  color: var(--so-cartmodal-heading-color, var(--so-paragraph-text-color, #777D80)) !important;
  font-weight: normal !important;
}

/* PA2 — Cart Modal Product Title — Display Font, Secondary, 28px */
[data-so-role="cartmodal-product-title"] {
  /* PA2 — shared by product title + price (#222); fallback chain = pre-#222 rendering */
  font-family: var(--so-cartmodal-title-font, var(--so-pd-sectionheading-font, Hanuman, serif)) !important;
  font-size: var(--so-cartmodal-title-font-size, 28px) !important;
  color: var(--so-cartmodal-title-color, var(--so-section-heading-color, #578DD5)) !important;
  font-weight: normal !important;
}

/* PA2 — Cart Modal Price — Display Font, Secondary, 28px */
[data-so-role="cartmodal-product-price"] {
  /* PA2 — shared by product title + price (#222); fallback chain = pre-#222 rendering */
  font-family: var(--so-cartmodal-title-font, var(--so-pd-sectionheading-font, Hanuman, serif)) !important;
  font-size: var(--so-cartmodal-title-font-size, 28px) !important;
  color: var(--so-cartmodal-title-color, var(--so-section-heading-color, #578DD5)) !important;
  font-weight: normal !important;
}

/* G6 — Cart Modal Description Text — Secondary Font, Text, 16px */
[data-so-role="cartmodal-description"] {
  font-family: var(--so-paragraph-text-font, Josefin Sans, sans-serif) !important;
  font-size: var(--so-paragraph-text-font-size, 16px) !important;
  color: var(--so-paragraph-text-color, #777D80) !important;
}

/* G6 — Cart Modal Description Label ("Product Description") — bold, Secondary Font, Text, 16px */
[data-so-role="cartmodal-description-label"] {
  font-family: var(--so-paragraph-text-font, Josefin Sans, sans-serif) !important;
  font-size: var(--so-paragraph-text-font-size, 16px) !important;
  color: var(--so-paragraph-text-color, #777D80) !important;
  font-weight: bold !important;
}

/* G6 — Cart Modal SKU — caps, Secondary Font, Accent (forced), 16px */
[data-so-role="cartmodal-sku"] {
  font-family: var(--so-paragraph-text-font, Josefin Sans, sans-serif) !important;
  font-size: var(--so-paragraph-text-font-size, 16px) !important;
  color: var(--so-pd-details-label-color, #609CEC) !important;
  text-transform: uppercase;
  font-weight: normal !important;
}

/* G9/G10 — Cart Modal Border (shares the product-card border token so the
   cart modal stays visually consistent with product cards). */
[data-so-role="cartmodal-border"] {
  border-color: var(--so-product-card-border, #E1E1E1) !important;
}

/* Cart Modal Image — constrain height so tall/portrait product photos don't
   stretch the column beyond the text content height. Preserves aspect ratio
   via object-fit:contain — no distortion, just a bounded max-height. */
#cartModal .modal-body .col-md-4 img {
  max-height: 320px;
  height: auto;
  width: auto;
  max-width: 100%;
  object-fit: contain;
  display: block;
  margin: 0 auto;
}

/* Cart Modal Layout — BootstrapSkin.css zeroes .row gutters globally (for the
   editor canvas), which also strips spacing inside the live cart modal.
   Restore standard BS5 spacing here so image + text columns have breathing
   room and content doesn't press against the modal edges. */
#cartModal .modal-header {
  padding: 1rem 1.25rem;
}
#cartModal .modal-body {
  padding: 1.25rem;
}
#cartModal .modal-footer {
  padding: 1rem 1.25rem;
}
#cartModal .modal-body > .row {
  --bs-gutter-x: 1.5rem;
  --bs-gutter-y: 0;
  margin-right: calc(var(--bs-gutter-x) * -0.5);
  margin-left:  calc(var(--bs-gutter-x) * -0.5);
}
#cartModal .modal-body > .row > [class*="col-"] {
  padding-right: calc(var(--bs-gutter-x) * 0.5);
  padding-left:  calc(var(--bs-gutter-x) * 0.5);
}

/* G15 — Default Button Background (Continue Shopping) */
[data-so-role="button-default"] {
  background-color: var(--so-button-default-bg, #FFFFFF);
  border: 1px solid var(--so-button-default-hover-bg, #BCBCBC);
  color: var(--so-button-default-color, #1B202F);
  font-family: var(--so-button-default-font, Nobile, sans-serif);
  font-size: var(--so-button-default-font-size, 14px);
}

/* G16 — Default Button Hover */
[data-so-role="button-default"]:hover {
  background-color: var(--so-button-default-hover-bg, #BCBCBC);
  border-color: var(--so-button-default-bg, #FFFFFF);
  color: var(--so-button-default-hover-color, #1B202F);
  text-decoration: none;
}

/* G19 — Primary Button Background */
[data-so-role="button-primary"] {
  background-color: var(--so-button-primary-bg, #1B202F);
  border-color: var(--so-button-primary-bg, #1B202F);
  color: var(--so-button-primary-color, #FFFFFF);
  font-family: var(--so-button-primary-font, Nobile, sans-serif);
  font-size: var(--so-button-primary-font-size, 14px);
}

/* Progress bar — setup-panel steps need explicit block display + padding
   since they use bare <a> tags without .nav-link class */
.setup-panel [data-so-role="button-primary"] {
  display: flex !important;
  flex-direction: column !important;
  align-items: center !important;
  justify-content: center !important;
  padding: 10px 15px !important;
  text-align: center !important;
  text-decoration: none !important;
  border-radius: 4px !important;
  min-height: 70px !important;
}
/* G21/G22 — Progress bar step number: Display Font, Surface, 20px */
.setup-panel .list-group-item-heading {
  font-family: var(--so-pd-sectionheading-font, Hanuman, serif) !important;
  font-size: 20px !important;
  color: var(--so-button-primary-color, #FFFFFF) !important;
  height: auto !important;
  line-height: 1.2 !important;
  margin: 0 !important;
}

/* G21/G22 — Progress bar step label: Secondary Font, Surface, 16px */
.setup-panel .list-group-item-text {
  font-family: var(--so-paragraph-text-font, Josefin Sans, sans-serif) !important;
  font-size: 16px !important;
  color: var(--so-button-primary-color, #FFFFFF) !important;
  margin: 0 !important;
}

/* Cart product name links — no underline */
.so-page-cart a[data-so-role="page-link"] {
  text-decoration: none !important;
}
.so-page-cart a[data-so-role="page-link"]:hover {
  text-decoration: none !important;
}

/* Progress bar — kill default button-primary hover bg/color change on ALL steps.
   Only passed steps (real URLs starting with shop/) get a subtle scale-up hover. */
.setup-panel [data-so-role="button-primary"]:hover {
  background-color: var(--so-button-primary-bg, #1B202F) !important;
  border-color: var(--so-button-primary-bg, #1B202F) !important;
  color: var(--so-button-primary-color, #FFFFFF) !important;
  cursor: default !important;
}
.setup-panel .nav-item.active [data-so-role="button-primary"]:hover {
  background-color: var(--so-button-process-bg, #609CEC) !important;
  border-color: var(--so-button-process-bg, #609CEC) !important;
  color: var(--so-button-primary-color, #FFFFFF) !important;
  cursor: default !important;
}

/* Passed steps (href starts with shop/) — text-expand on hover + hand cursor */
.setup-panel [data-so-role="button-primary"][href^="shop/"],
.setup-panel [data-so-role="button-primary"][href^="/shop/"] {
  transition: transform 0.2s ease;
}
.setup-panel [data-so-role="button-primary"][href^="shop/"]:hover,
.setup-panel [data-so-role="button-primary"][href^="/shop/"]:hover {
  transform: scale(1.06);
  cursor: pointer !important;
}

/* Progress bar active step: Accent bg */
.setup-panel .nav-item.active [data-so-role="button-primary"] {
  background-color: var(--so-button-process-bg, #609CEC) !important;
  border-color: var(--so-button-process-bg, #609CEC) !important;
  color: var(--so-button-primary-color, #FFFFFF) !important;
}

/* G20 — Primary Button Hover */
[data-so-role="button-primary"]:hover {
  background-color: var(--so-button-primary-hover-bg, #609CEC);
  border-color: var(--so-button-primary-hover-bg, #609CEC);
  color: var(--so-button-primary-hover-color, #FFFFFF);
}

/* Cart totals row — Secondary Font, Text, 28px */
[data-so-role="cart-total-heading"] {
  font-family: var(--so-paragraph-text-font, Josefin Sans, sans-serif) !important;
  font-size: 28px !important;
  color: var(--so-paragraph-text-color, #777D80) !important;
}

/* =============================================
   LOGIN/AUTH PAGE TOKENS (G4, G7, G9, LP1-LP3)
   ============================================= */

/* G4 — Page Title ("Log in to your account") — Primary Font, Primary, 48px */
[data-so-role="page-title"] {
  font-family: var(--so-page-title-font, Nobile, sans-serif) !important;
  font-size: var(--so-page-title-font-size, 48px) !important;
  color: var(--so-page-title-color, #1B202F) !important;
  font-weight: normal !important;
}

/* G7 — Form Field Labels ("Email Address", "Password") — Primary Font, Accent, 14px */
[data-so-role="form-label"] {
  font-family: var(--so-form-label-font, Nobile, sans-serif) !important;
  font-size: var(--so-form-label-font-size, 14px) !important;
  color: var(--so-form-label-color, #609CEC) !important;
}

/* G6/G8 — Meta/helper text ("Showing X orders", "Total Items: 24") —
   Secondary Font, Text, 16px. The CSS vars were defined but no selector
   consumed them until now — pages had the data-so-role attribute wired
   but the token wasn't producing any visible effect. */
[data-so-role="meta-text"] {
  font-family: var(--so-meta-text-font, Josefin Sans, sans-serif);
  font-size: var(--so-meta-text-font-size, 16px);
  color: var(--so-meta-text-color, #777D80);
}

/* G1/G2 — strip underline globally on page-link anchors in both default
   and hover states. Browsers/Bootstrap underline <a> by default, which
   looked wrong on themed page links (e.g. order-number links in profile
   order history, reset-password link). Colour change on hover remains
   the affordance. Existing .so-shop-page and .so-page-cart scoped rules
   only covered a subset of pages. */
a[data-so-role="page-link"],
a[data-so-role="page-link"]:hover,
a[data-so-role="page-link"]:focus {
  text-decoration: none;
}

/* LP1 — Panel Heading Background */
[data-so-role="auth-panel-heading"] {
  background-color: var(--so-auth-panel-heading-bg, #f7f7f7) !important;
}

/* LP2 — Panel Heading Text — Display Font, Accent, 28px */
[data-so-role="auth-panel-heading"] h3,
[data-so-role="auth-panel-heading"] {
  font-family: var(--so-auth-panel-heading-font, Hanuman, serif) !important;
  font-size: var(--so-auth-panel-heading-font-size, 28px) !important;
  color: var(--so-auth-panel-heading-color, #609CEC) !important;
}

/* LP3 — Form Input Focus — Accent shadow */
/* G6 — Form Input Text: Secondary Font, Text, 16px */
[data-so-role="form-input"] {
  font-family: var(--so-paragraph-text-font, Josefin Sans, sans-serif);
  font-size: var(--so-paragraph-text-font-size, 16px);
  color: var(--so-form-input-color, #495057);
  background-color: var(--so-form-input-bg, #ffffff);
}
[data-so-role="form-input"]:focus {
  border-color: var(--so-form-input-focus-shadow, #609CEC) !important;
  box-shadow: 0 0 0 0.2rem rgba(96, 156, 236, 0.25) !important;
}

/* G9 — Card Border (panels on auth page) */
[data-so-role="card-border"] {
  border-color: var(--so-card-border-color, #E1E1E1) !important;
}

/* Remove underline on all themed buttons */
[data-so-role="button-process"],
[data-so-role="button-default"],
[data-so-role="button-primary"] {
  text-decoration: none !important;
}
[data-so-role="button-process"]:hover,
[data-so-role="button-default"]:hover,
[data-so-role="button-primary"]:hover {
  text-decoration: none !important;
}

/* Card needs relative positioning for stock badge */
[data-so-role="product-card"] {
  position: relative;
}


/* =============================================
   PAGE LINKS: Login state toggle
   ============================================= */
a[data-show-when="logged-in"],
span[data-show-when="logged-in"] {
  display: none !important;
}
.user-logged-in a[data-show-when="logged-in"],
.user-logged-in span[data-show-when="logged-in"] {
  display: inline !important;
}
.user-logged-in a[data-show-when="logged-out"],
.user-logged-in span[data-show-when="logged-out"] {
  display: none !important;
}

/* Logged-in user display name (injected into .so-page-links at runtime).
   Positioned absolutely so it superimposes over whatever is directly
   below the links row (Shop2 pattern — doesn't reflow content). */
.so-page-links.user-logged-in {
  position: relative;
}
.so-user-display-name {
  display: none;
  position: absolute;
  top: 100%;
  right: 0;
  padding-top: 2px;
  font-family: var(--so-page-link-font, Josefin Sans, sans-serif);
  font-size:   var(--so-page-link-font-size, 18px);
  color:       var(--so-page-link-hover, #609CEC);
  white-space: nowrap;
  pointer-events: none;
  z-index: 5;
}
.so-page-links.user-logged-in .so-user-display-name {
  display: block;
}

/* =============================================
   ORDER SUMMARY CARD — clip corners (BS3/4 .panel-info
   legacy + BS5 .card border-radius mismatch causes gaps)
   ============================================= */
.card.panel-info {
  overflow: hidden;
}

/* =============================================
   PROGRESS BAR — base cursor (all steps)
   Default everything to arrow; the shop/-href rule
   up above re-enables pointer on passed steps only.
   Covers cart.php (#step-N), checkout/payment (javascript:…).
   ============================================= */
.setup-panel .nav-item a {
  cursor: default !important;
}
.setup-panel .nav-item a[href^="shop/"],
.setup-panel .nav-item a[href^="/shop/"] {
  cursor: pointer !important;
}

/* =============================================
   RESPONSIVE ADJUSTMENTS
   Token-aware breakpoint handling
   ============================================= */

@media (max-width: 768px) {
  :root {
    --so-grid-title-size: 1.25rem;
    --so-product-image-max-height: 150px;
  }

  [data-so-role="grid-count"] {
    text-align: left;
    padding-top: 0.5rem;
  }

  [data-so-role="carousel-controls"],
  [data-so-role="pagination-nav"] {
    margin-top: 0.5rem;
  }
}

@media (max-width: 576px) {
  :root {
    --so-product-title-size: 13px;
    --so-product-price-size: 1rem;
    --so-stock-badge-size: 10px;
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   #285 CANVAS THEME ROLES (4 Sep 2026) — COLOUR ONLY, by contract.
   EDITOR4_STYLE_OWNERSHIP_AND_RESET_CONTRACT.md §2/§3 is the authority:
   - data-so-theme-role governs COLOUR and nothing else (typography belongs
     exclusively to the so-text-style--* presets). Adding a font-family,
     font-size or any other typography declaration here is a contract
     violation — pins enforce it. (NEVER write the two characters star-slash
     inside a comment: on 5 Sep 2026 "font-*" + "/size" closed this comment
     early and the browser dropped the first colour rule below — J1 FAIL.)
   - No !important: theme colour flows until a merchant's local #id
     declaration wins (specificity 1-0-0 over 0-1-0). That is the design.
   - data-so-theme-context="inverse" on a block/container remaps its governed
     text to the theme surface for contrast (0-2-0 still loses to #id).
     Nested coloured overlays may declare their own context; an element moved
     between contexts adapts — intentional behaviour.
   - Role "none" (or no attribute) = deliberately ungoverned.
   These attributes are invisible technical markers — merchants see only the
   colour controls. Vars resolve on ALL surfaces (canvas/preview/published)
   via theme_css.php's :root block.
   ═══════════════════════════════════════════════════════════════════════ */
[data-so-theme-role="section-heading"],
[data-so-theme-role="hero-statement"] {
  color: var(--theme-secondary);
}
[data-so-theme-role="eyebrow"] {
  color: var(--theme-primary);
}
[data-so-theme-role="card-heading"],
[data-so-theme-role="body"],
[data-so-theme-role="caption"] {
  color: var(--theme-text);
}

/* Inverse context — all governed roles resolve to the theme surface. */
[data-so-theme-context="inverse"] [data-so-theme-role="section-heading"],
[data-so-theme-context="inverse"] [data-so-theme-role="hero-statement"],
[data-so-theme-context="inverse"] [data-so-theme-role="eyebrow"],
[data-so-theme-context="inverse"] [data-so-theme-role="card-heading"],
[data-so-theme-context="inverse"] [data-so-theme-role="body"],
[data-so-theme-context="inverse"] [data-so-theme-role="caption"] {
  color: var(--theme-surface);
}
