/*
 * Salesio universal template — base.css
 *
 * Theme tokens (set by runtime.js from data/theme.json onto :root),
 * reset, typography, layout primitives, button/badge system. All
 * section-specific styles live in sections.css.
 *
 * Naming convention: every utility/component class is prefixed `sx-`
 * so we never collide with user-injected HTML (rare) or third-party
 * embeds (instagram feed, google maps).
 *
 * Fonts: self-hosted Inter + Playfair Display. No fonts.googleapis.com
 * <link> in the HTML shell — this @import wires up the @font-face
 * declarations, which point at raw_templates/_universal/fonts/.
 */

@import url('../fonts/fonts.css');
/* Italianno (signature script for props.layout="signature") is now SELF-HOSTED
   inside fonts.css — the external fonts.googleapis.com @import that lived here
   was render-blocking on the critical path AND its late load reflowed the
   signature, shifting the footer (the 0.117 CLS culprit). */
/* Opt-in motion + visual library (entrance / hover / idle / bg /
   text effects). Nothing applies by default — templates opt in
   per-section via props (entrance, hover, idle, bg_fx). Doc:
   /docs/EFFECTS_CATALOG.md */
@import url('./effects.css');

:root {
  /* Defaults — runtime.js overrides these per-site from theme.json. */
  --sx-color-primary:      #e85d5d;
  --sx-color-primary-dark: #c64949;
  --sx-color-on-primary:   #ffffff;
  --sx-color-accent:       #e85d5d;
  --sx-color-bg:           #ffffff;
  --sx-color-bg-alt:       #f6f3ef;
  --sx-color-surface:      #ffffff;
  --sx-color-ink:          #1c1c1c;
  --sx-color-ink-soft:     #555555;
  --sx-color-border:       #e8e3dd;
  /* Alias of ink-soft, kept only as a FALLBACK for the five rules written as
     `var(--sx-color-ink-soft, var(--sx-color-muted))`. Nothing reads it on its
     own any more, and it must stay that way: a custom property whose value is
     itself a `var()` is substituted in the element where it is DECLARED, so
     this one freezes to whatever `--sx-color-ink-soft` resolves to at :root.
     A section that re-points `--sx-color-ink-soft` for its own surface cannot
     move it — `.sx-pub__subtitle` kept the page-background grey inside a
     dark `bg_alt` band (2.38:1 on auto-repair) for exactly that reason.
     Reference `--sx-color-ink-soft` directly instead. */
  --sx-color-muted:        var(--sx-color-ink-soft);

  /* ── Contrast pairs ───────────────────────────────────────────────
     Two tokens exist because the ones above are NOT safe for every job,
     and both failure modes were measured on real renders:

     1. INVERSE — a panel that is deliberately the opposite of the page
        (dark editorial band on a light site). Sections used to paint it
        with `background: var(--sx-color-ink); color: #fff`. That works
        on a light site, where ink is dark. On a DARK site ink is LIGHT,
        so the panel turned near-white while its text stayed white:
        measured 1.02:1 on `advantage`, i.e. invisible. The same trap was
        already patched ad-hoc for `.sx-footer` further down this file.
        This pair flips as a unit, so background and text can never drift
        apart. Use it for any always-contrasting panel.

     2. PRIMARY-INK — the brand colour as small TEXT. `--sx-color-primary`
        is tuned for fills (with on-primary over it); as type on the page
        background the shipped default measures 3.41:1, under the 4.5:1 AA
        floor, and it is used for the eyebrow on ~50 section types.
        runtime.js recomputes this per theme, darkening or lightening the
        brand hue until it clears 4.5:1 against the actual page bg; the
        value here is only the no-JS fallback. */
  --sx-color-inverse-bg:       #14131c;
  --sx-color-inverse-ink:      #ffffff;
  --sx-color-inverse-ink-soft: rgba(255, 255, 255, 0.78);
  --sx-color-inverse-border:   rgba(255, 255, 255, 0.16);
  /* Brand-as-text, resolved against the page background… */
  /* Body text resolved PER SURFACE. `ink` is one colour for the whole site,
     but `bg`, `bg_alt` and `surface` are three independent values a template
     author picks separately — and nothing forced them to agree. A palette can
     ship a light `bg` (so the theme reads as light, ink stays dark) next to a
     DARK `bg_alt`, and every `bg_style: soft|neutral|dots` band then paints
     dark text on a dark background: measured 1.04:1 on auto-repair, 1.09:1 on
     videographer, and the mirror case 1.15:1 on bartender-party (light
     `surface` under a dark theme's light ink). runtime.js sets each of these
     to `ink` when `ink` is legible on that surface, and to the readable
     opposite when it is not, so a mixed palette can no longer produce
     invisible copy. */
  --sx-color-ink-on-alt:              #1c1c1c;
  --sx-color-ink-soft-on-alt:         #555555;
  --sx-color-ink-on-surface:          #1c1c1c;
  --sx-color-ink-soft-on-surface:     #555555;
  /* The brand-as-text values need the same per-surface treatment: on a mixed
     palette no single accent reads on both a light band and a dark one. */
  --sx-color-accent-ink-on-alt:       #b23c3c;
  --sx-color-primary-ink-on-alt:      #b23c3c;
  --sx-color-accent-ink-on-surface:   #b23c3c;
  --sx-color-primary-ink-on-surface:  #b23c3c;
  --sx-color-primary-ink:      #b23c3c;
  --sx-color-accent-ink:       #b23c3c;
  /* …and against an inverse panel, where the page-tuned value would be
     wrong in the other direction (a darkened accent on a dark panel). */
  --sx-color-accent-on-inverse: #f2a09b;
  /* The rating gold, which is a THIRD brand-as-text role: the score a
     customer is meant to read. It needs the same per-surface treatment as
     `accent-ink`, because the two golds are opposites — a dark gold on light
     surfaces, a light one on dark. bartender-party is a dark theme with a
     WHITE `surface`, so every review card kept the dark theme's light gold on
     white paper: 1.62:1, the least legible thing on the card. Like the other
     `-on-*` defaults here these are the LIGHT-mode values; runtime.js,
     shell-preview.ts and contrast_audit.mjs derive the real ones per surface. */
  --sx-color-stars:             #8a6100;
  --sx-color-stars-on-alt:      #8a6100;
  --sx-color-stars-on-surface:  #8a6100;

  --sx-font-display: 'Playfair Display', 'Playfair Fallback', Georgia, serif;
  --sx-font-body:    'Inter', 'Inter Fallback', system-ui, -apple-system, sans-serif;

  --sx-radius-sm:   4px;
  --sx-radius-md:   6px;
  --sx-radius-lg:   12px;
  --sx-radius-xl:   24px;
  --sx-radius-pill: 999px;

  --sx-section-y:        96px;
  --sx-section-y-mobile: 56px;
  --sx-container:        1240px;

  --sx-shadow-card:     0 1px 2px rgba(0,0,0,0.04), 0 8px 24px rgba(0,0,0,0.06);
  --sx-shadow-elevated: 0 4px 12px rgba(0,0,0,0.08), 0 16px 48px rgba(0,0,0,0.12);
}

/* ── Reset ────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
/* `overflow-x: clip` kills any accidental horizontal scroll (a wide
   off-canvas panel, a translateX element, an over-wide image) without
   the side effects of `overflow: hidden` — `clip` does NOT create a
   scroll container, so it never breaks `position: sticky` descendants
   like the header. Defense-in-depth: nothing should ever make the
   page draggable sideways on mobile. */
html, body { margin: 0; padding: 0; overflow-x: clip; }
body {
  font-family: var(--sx-font-body);
  font-size: 16px;
  line-height: 1.55;
  color: var(--sx-color-ink);
  background: var(--sx-color-bg);
  -webkit-font-smoothing: antialiased;
}
body.sx-page-bg-marble {
  background-color: var(--sx-color-bg);
  background-image:
    radial-gradient(92% 74% at 18% 14%, rgba(255,255,255,0.98) 0%, rgba(255,255,255,0) 60%),
    radial-gradient(84% 68% at 84% 10%, rgba(221,224,228,0.18) 0%, transparent 62%),
    radial-gradient(88% 72% at 18% 84%, rgba(214,217,221,0.16) 0%, transparent 64%),
    radial-gradient(108% 86% at 82% 78%, rgba(255,255,255,0.9) 0%, transparent 58%),
    linear-gradient(118deg, transparent 0 22%, rgba(164,170,176,0.07) 24%, rgba(255,255,255,0) 29%, transparent 100%),
    linear-gradient(33deg, transparent 0 38%, rgba(212,205,194,0.1) 40%, rgba(255,255,255,0) 45%, transparent 100%),
    linear-gradient(144deg, transparent 0 60%, rgba(149,155,161,0.06) 62%, rgba(255,255,255,0) 67%, transparent 100%),
    linear-gradient(14deg, rgba(255,255,255,0.88) 0%, rgba(248,247,244,0.97) 48%, rgba(255,255,255,0.9) 100%);
  background-attachment: fixed;
}
img, picture, video, iframe { display: block; max-width: 100%; height: auto; }
button { font-family: inherit; cursor: pointer; }
a { color: inherit; }
h1, h2, h3, h4, h5, h6 {
  font-family: var(--sx-font-display);
  font-weight: 700;
  line-height: 1.1;
  margin: 0;
  letter-spacing: -0.01em;
}
p { margin: 0; }

/* ── Layout primitives ────────────────────────────────────────── */
.sx-container {
  width: 100%;
  max-width: var(--sx-container);
  margin: 0 auto;
  padding: 0 24px;
}
.sx-section {
  padding: var(--sx-section-y) 0;
  position: relative;
}
.sx-section--alt {
  background: var(--sx-color-bg-alt);
  /* Same trap as the bg_style bands, same fix: re-point the ink TOKENS for
     this surface so every rule inside inherits the corrected value, whatever
     its specificity. `ink-on-alt` equals `ink` on coherent palettes, so this
     is a no-op for the ~160 templates that pick agreeing colours. Renderers
     that hardcode this class (insurance_safety, google_reviews,
     loyalty_program…) get it for free. */
  --sx-color-ink: var(--sx-color-ink-on-alt);
  --sx-color-ink-soft: var(--sx-color-ink-soft-on-alt, var(--sx-color-ink-on-alt));
  /* The BRAND-as-text pair needs the same re-point, and omitting it here was
     the last mixed-palette hole: `.sx-eyebrow` reads `--sx-color-accent-ink`,
     which is tuned against the PAGE background, so on auto-repair's dark
     `bg_alt` the darkened amber measured 3.78:1 on every renderer that
     hardcodes this class, and `.sx-rating-summary__value` — the score the
     customer is meant to read — landed at 1.02:1. */
  --sx-color-accent-ink: var(--sx-color-accent-ink-on-alt, var(--sx-color-accent-ink));
  --sx-color-primary-ink: var(--sx-color-primary-ink-on-alt, var(--sx-color-primary-ink));
  --sx-color-stars: var(--sx-color-stars-on-alt, var(--sx-color-stars));
  color: var(--sx-color-ink);
}
.sx-section__head {
  text-align: center;
  max-width: 720px;
  margin: 0 auto 56px;
}
.sx-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font-family: var(--sx-font-body);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.25em;
  text-transform: uppercase;
  /* accent-ink, not accent: the eyebrow is 12px uppercase type, and the
     shipped brand default measured 3.41:1 on white — under the 4.5:1 AA
     floor, on roughly 50 section types. accent-ink is the same hue pushed
     until it clears the floor against the actual page background. */
  color: var(--sx-color-accent-ink, var(--sx-color-accent));
  margin-bottom: 16px;
}
.sx-eyebrow::before {
  content: "";
  display: inline-block;
  width: 28px;
  height: 2px;
  background: var(--sx-color-accent-fill, var(--sx-color-accent));
  border-radius: 2px;
}
/* Inside an inverse panel the page-tuned accent is darkened against the
   PAGE, which is the wrong direction for the panel. Re-point both the text
   and the rule at the panel-tuned value. */
.sx-advantage .sx-eyebrow,
.sx-rfp__panel .sx-eyebrow,
.sx-warranty--photo .sx-eyebrow,
.sx-cta-mid .sx-eyebrow {
  color: var(--sx-color-accent-on-inverse, var(--sx-color-accent));
}
.sx-advantage .sx-eyebrow::before,
.sx-rfp__panel .sx-eyebrow::before,
.sx-warranty--photo .sx-eyebrow::before,
.sx-cta-mid .sx-eyebrow::before {
  background: var(--sx-color-accent-on-inverse, var(--sx-color-accent));
}
.sx-h1 { font-size: clamp(36px, 5vw, 64px); }
.sx-h2 { font-size: clamp(28px, 3.5vw, 44px); margin-bottom: 12px; font-weight: 800; }
.sx-h3 { font-size: 22px; }
.sx-lead {
  font-size: 17px;
  color: var(--sx-color-ink-soft);
  line-height: 1.6;
}

/* ── Rich text effects — OPT-IN via .sx-text-fx on a section ──
   Same pattern as overlay_style="transparent" / number_style="outline"
   / card_style="cards" / background prop: the renderer adds this
   class when props.text_fx === true, so ONLY that opt-in section
   gets the animated entrance + hover effects. The 50+ existing
   templates that don't set text_fx keep the plain typography
   above — no behavior change. */
.sx-text-fx .sx-eyebrow {
  transition: letter-spacing 0.6s cubic-bezier(0.16, 1, 0.3, 1);
}
.sx-text-fx .sx-reveal:not(.sx-revealed) .sx-eyebrow,
.sx-text-fx.sx-reveal:not(.sx-revealed) .sx-eyebrow { letter-spacing: 0.4em; }
.sx-text-fx .sx-eyebrow::before {
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.65s cubic-bezier(0.16, 1, 0.3, 1);
}
.sx-text-fx .sx-revealed .sx-eyebrow::before,
.sx-text-fx.sx-revealed .sx-eyebrow::before { transform: scaleX(1); }
/* H2 hover underline grows in the brand accent color. inline-block
   keeps the underline width = text width (not full container). */
/* `width: fit-content` keeps the underline pseudo tied to the
   actual text width (block-level inline-block parity) while
   ensuring the h2 still starts on its own line — preventing it from
   flowing inline next to a preceding inline-flex eyebrow. */
.sx-text-fx .sx-h2 { position: relative; display: block; width: fit-content; max-width: 100%; }
/* Centered section heads need the auto margin to keep h2 centered. */
.sx-section__head .sx-text-fx .sx-h2,
.sx-section__head.sx-text-fx .sx-h2 { margin-left: auto; margin-right: auto; }
.sx-text-fx .sx-h2::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -4px;
  height: 3px;
  width: 0;
  background: var(--sx-color-accent-fill, var(--sx-color-accent));
  border-radius: 3px;
  transition: width 0.5s cubic-bezier(0.16, 1, 0.3, 1);
}
.sx-text-fx .sx-h2:hover::after { width: 100%; }
/* Lead paragraph blurs in on reveal — "comes into focus". */
.sx-text-fx .sx-lead { transition: filter 0.7s cubic-bezier(0.16, 1, 0.3, 1); }
.sx-text-fx .sx-reveal:not(.sx-revealed) .sx-lead,
.sx-text-fx.sx-reveal:not(.sx-revealed) .sx-lead { filter: blur(2px); }
.sx-text-fx .sx-revealed .sx-lead,
.sx-text-fx.sx-revealed .sx-lead { filter: none; }

/* ── Buttons ──────────────────────────────────────────────────── */
.sx-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 14px 28px;
  border-radius: var(--sx-radius-md);
  font-family: var(--sx-font-body);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  text-decoration: none;
  border: 1px solid transparent;
  cursor: pointer;
  transition: transform 0.15s ease, background 0.2s ease, color 0.2s ease, border-color 0.2s ease;
  white-space: nowrap;
}
.sx-btn:active { transform: scale(0.97); }
.sx-btn--primary {
  background: var(--sx-color-primary-fill, var(--sx-color-primary));
  color: var(--sx-color-on-primary);
}
.sx-btn--primary:hover {
  background: var(--sx-color-primary-dark);
  color: var(--sx-color-on-primary);
}
/* The secondary button is an inverse surface: on a dark site it has to
   become light with dark type, or it renders white-on-white (measured
   1.04:1 inside pricing). */
.sx-btn--secondary {
  background: var(--sx-color-inverse-bg);
  color: var(--sx-color-inverse-ink);
}
.sx-btn--secondary:hover {
  background: color-mix(in srgb, var(--sx-color-inverse-bg) 88%, var(--sx-color-inverse-ink));
}
.sx-btn--ghost {
  background: transparent;
  color: var(--sx-color-ink);
  border-color: var(--sx-color-border);
}
.sx-btn--ghost:hover {
  background: var(--sx-color-ink);
  color: #fff;
  border-color: var(--sx-color-ink);
}
.sx-btn--text {
  padding: 8px 0;
  background: transparent;
  color: var(--sx-color-primary-ink, var(--sx-color-primary));
  letter-spacing: 0.1em;
}
.sx-btn--text:hover { color: var(--sx-color-primary-dark); }

/* ── Badge / pill ─────────────────────────────────────────────── */
.sx-badge {
  display: inline-block;
  padding: 4px 10px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  border-radius: var(--sx-radius-pill);
  background: var(--sx-color-primary-fill, var(--sx-color-primary));
  /* NOT #fff: a light-primary theme (e.g. the B&W fashion one, primary
     #F2F2F2) made the badge white-on-white. on-primary always pairs. */
  color: var(--sx-color-on-primary, #fff);
}

/* ── Card primitive ───────────────────────────────────────────── */
.sx-card {
  background: var(--sx-color-surface);
  border: 1px solid var(--sx-color-border);
  border-radius: var(--sx-radius-lg);
  overflow: hidden;
  transition: transform 0.2s ease, box-shadow 0.2s ease;
  --sx-color-ink: var(--sx-color-ink-on-surface);
  --sx-color-ink-soft: var(--sx-color-ink-soft-on-surface, var(--sx-color-ink-on-surface));
  --sx-color-accent-ink: var(--sx-color-accent-ink-on-surface, var(--sx-color-accent-ink));
  --sx-color-primary-ink: var(--sx-color-primary-ink-on-surface, var(--sx-color-primary-ink));
  --sx-color-stars: var(--sx-color-stars-on-surface, var(--sx-color-stars));
  color: var(--sx-color-ink);
}
.sx-card:hover {
  transform: translateY(-3px);
  box-shadow: var(--sx-shadow-elevated);
}

/* ── Star rating display (reused: testimonials, reviews) ──────── */
/* Rating stars. The old #f5a623 measured 2.03:1 on white — the score a
   customer is meant to read at a glance was the least legible thing on
   the card. A deeper gold clears the floor and still reads as gold; on a
   dark page it goes the other way. */
.sx-stars { display: inline-flex; gap: 2px; color: var(--sx-color-stars, #8a6100); font-size: 14px; }

/* ── Reveal-on-scroll utility (IntersectionObserver in runtime) ─ */
.sx-reveal {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.7s cubic-bezier(0.16, 1, 0.3, 1), transform 0.7s cubic-bezier(0.16, 1, 0.3, 1), filter 0.7s ease;
}
.sx-reveal.sx-revealed {
  opacity: 1;
  transform: translateY(0);
  filter: none;
}
/* Section-level fade — OPACITY ONLY (no translateY) so the layout
   never shifts and a stuck observer never hides the section badly.
   Runtime auto-attaches this to every <section> except the hero.
   Reduced-motion users see everything visible immediately. */
.sx-reveal-section {
  opacity: 0;
  transition: opacity 0.7s cubic-bezier(0.16, 1, 0.3, 1);
  will-change: opacity;
}
.sx-reveal-section.sx-revealed { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .sx-reveal-section { opacity: 1; }
}
/* Reveal variants — additive, default `.sx-reveal` keeps current fade-up.
   Used by sections (e.g. hero word stagger, card grids) to differentiate
   entry feel without re-implementing the IntersectionObserver hook. */
.sx-reveal--left   { transform: translateX(-32px); }
.sx-reveal--right  { transform: translateX( 32px); }
.sx-reveal--scale  { transform: scale(0.94); }
.sx-reveal--blur   { filter: blur(10px); }
.sx-reveal--left.sx-revealed,
.sx-reveal--right.sx-revealed,
.sx-reveal--scale.sx-revealed { transform: none; }

/* Stagger children — drop the parent into `.sx-reveal sx-stagger` and
   each direct child fades up in sequence the moment the parent enters
   the viewport. Children don't need their own `.sx-reveal` class; this
   wrapper handles their hidden state too. Capped at 12 explicit slots
   (children #13+ all fire at the last delay). */
.sx-stagger > * {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.65s cubic-bezier(0.16, 1, 0.3, 1), transform 0.65s cubic-bezier(0.16, 1, 0.3, 1);
}
.sx-stagger.sx-revealed > * {
  opacity: 1;
  transform: none;
}
.sx-stagger.sx-revealed > *:nth-child(1)  { transition-delay:  60ms; }
.sx-stagger.sx-revealed > *:nth-child(2)  { transition-delay: 140ms; }
.sx-stagger.sx-revealed > *:nth-child(3)  { transition-delay: 220ms; }
.sx-stagger.sx-revealed > *:nth-child(4)  { transition-delay: 300ms; }
.sx-stagger.sx-revealed > *:nth-child(5)  { transition-delay: 380ms; }
.sx-stagger.sx-revealed > *:nth-child(6)  { transition-delay: 460ms; }
.sx-stagger.sx-revealed > *:nth-child(7)  { transition-delay: 540ms; }
.sx-stagger.sx-revealed > *:nth-child(8)  { transition-delay: 620ms; }
.sx-stagger.sx-revealed > *:nth-child(9)  { transition-delay: 700ms; }
.sx-stagger.sx-revealed > *:nth-child(10) { transition-delay: 780ms; }
.sx-stagger.sx-revealed > *:nth-child(11) { transition-delay: 860ms; }
.sx-stagger.sx-revealed > *:nth-child(12) { transition-delay: 940ms; }
.sx-stagger.sx-revealed > *:nth-child(n+13) { transition-delay: 1020ms; }

/* Word-by-word reveal for headings (opt-in via .sx-words on a heading).
   runtime.js splits the text on space and wraps each token in
   <span class="sx-word">. Each word slides up + fades in with a stagger. */
.sx-words .sx-word {
  display: inline-block;
  opacity: 0;
  transform: translateY(0.6em);
  transition: opacity 0.55s cubic-bezier(0.16, 1, 0.3, 1), transform 0.55s cubic-bezier(0.16, 1, 0.3, 1);
}
.sx-words.sx-revealed .sx-word { opacity: 1; transform: none; }
.sx-words.sx-revealed .sx-word:nth-child(1)  { transition-delay:  50ms; }
.sx-words.sx-revealed .sx-word:nth-child(2)  { transition-delay: 110ms; }
.sx-words.sx-revealed .sx-word:nth-child(3)  { transition-delay: 170ms; }
.sx-words.sx-revealed .sx-word:nth-child(4)  { transition-delay: 230ms; }
.sx-words.sx-revealed .sx-word:nth-child(5)  { transition-delay: 290ms; }
.sx-words.sx-revealed .sx-word:nth-child(6)  { transition-delay: 350ms; }
.sx-words.sx-revealed .sx-word:nth-child(7)  { transition-delay: 410ms; }
.sx-words.sx-revealed .sx-word:nth-child(8)  { transition-delay: 470ms; }
.sx-words.sx-revealed .sx-word:nth-child(9)  { transition-delay: 530ms; }
.sx-words.sx-revealed .sx-word:nth-child(10) { transition-delay: 590ms; }
.sx-words.sx-revealed .sx-word:nth-child(11) { transition-delay: 650ms; }
.sx-words.sx-revealed .sx-word:nth-child(12) { transition-delay: 710ms; }
.sx-words.sx-revealed .sx-word:nth-child(n+13) { transition-delay: 770ms; }

@media (prefers-reduced-motion: reduce) {
  .sx-reveal, .sx-reveal--left, .sx-reveal--right, .sx-reveal--scale, .sx-reveal--blur,
  .sx-stagger > *, .sx-words .sx-word {
    transition: none !important;
    transform: none !important;
    filter: none !important;
    opacity: 1 !important;
  }
}

/* ── Header ───────────────────────────────────────────────────── */
/*
 * Sticky over EVERYTHING. z-index 100 (above any in-page modal except
 * full-screen flows like the cart drawer at z-index 100 and the
 * mobile menu at 110). The blur backdrop softens scroll content
 * underneath so the nav stays readable on busy hero photos.
 */
.sx-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: saturate(180%) blur(8px);
  -webkit-backdrop-filter: saturate(180%) blur(8px);
  border-bottom: 1px solid var(--sx-color-border);
}
/* site.header.surface_style="glass-soft" — lighter, more transparent
   header for templates that sit over strong hero media. Opt-in only,
   so the shared default remains untouched. */
.sx-header.sx-header--glass-soft {
  background: rgba(255, 255, 255, 0.45);
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  border-bottom-color: rgba(255, 255, 255, 0.20);
  border-bottom-color: color-mix(in srgb, var(--sx-color-border) 40%, transparent);
}
.sx-header.sx-header--glass-soft.is-scrolled {
  background: rgba(255, 255, 255, 0.65);
}
/* site.header.surface_style="transparent" — fully see-through header.
   No bg, no border, no blur. Ideal for templates with a full-bleed
   hero video/image where the menu should float on top with zero
   visual chrome. Once the user scrolls past the hero, falls back
   to a subtle solid bg for legibility on regular content sections. */
.sx-header.sx-header--transparent {
  position: fixed !important;
  top: 0;
  left: 0;
  right: 0;
  background: transparent !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  border-bottom: 0 !important;
}
/* Pull the page content UP under the fixed transparent header so the
   hero starts at viewport top (no white body strip showing). */
body:has(.sx-header.sx-header--transparent) main { margin-top: 0; }
body:has(.sx-header.sx-header--transparent) > .sx-header { box-shadow: none; }
/* AT TOP (over hero): text white + subtle dark shadow for legibility
   even when the hero background is bright (grass, sky, etc.). */
.sx-header.sx-header--transparent:not(.is-scrolled) .sx-header__logo,
.sx-header.sx-header--transparent:not(.is-scrolled) .sx-header__nav a {
  color: #ffffff !important;
  text-shadow: 0 1px 6px rgba(0,0,0,0.45), 0 0 2px rgba(0,0,0,0.55) !important;
}
/* ON SCROLL: tinted glass with theme primary + white text.
   Keeps the on-brand feel and readable text without going to solid white. */
.sx-header.sx-header--transparent.is-scrolled {
  background: color-mix(in srgb, var(--sx-color-primary) 32%, transparent) !important;
  backdrop-filter: saturate(180%) blur(14px) !important;
  -webkit-backdrop-filter: saturate(180%) blur(14px) !important;
  border-bottom: 1px solid rgba(255,255,255,0.18) !important;
}
.sx-header.sx-header--transparent.is-scrolled .sx-header__logo,
.sx-header.sx-header--transparent.is-scrolled .sx-header__nav a {
  color: #ffffff !important;
}
.sx-header.sx-header--transparent.is-scrolled .sx-header__nav a:hover {
  color: rgba(255,255,255,0.78) !important;
}
.sx-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  /* Horizontal padding must match .sx-container (24px). Both classes
     sit on the same element and .sx-header__inner is defined LATER in
     the stylesheet, so a `0` here would override the container's 24px
     and slam the logo + hamburger flush against the viewport edge. */
  padding: 14px 24px;
}
@media (min-width: 720px) {
  .sx-header__inner { gap: 24px; padding: 16px 24px; }
}
.sx-header__logo {
  font-family: var(--sx-font-display);
  font-weight: 700;
  font-size: 18px;
  line-height: 1.15;
  letter-spacing: -0.01em;
  color: var(--sx-color-ink);
  text-decoration: none;
  /* FIXED brand column. A long name WRAPS onto extra lines (the header
     grows downward) instead of overflowing into the nav, and is NEVER
     truncated — no ellipsis, no clipping. Proportions stay consistent via
     the fixed width + tight line-height. overflow-wrap:anywhere only kicks
     in for a single word longer than the column (multi-word names wrap at
     spaces normally). The brand never gets squeezed out by the nav —
     brand-first hierarchy. */
  white-space: normal;
  overflow-wrap: anywhere;
  /* NATURAL width capped by max-width — the box hugs the text, so a SHORT
     name ("MYRA") stays compact and flush-left with NO empty gap, while a
     LONG name wraps downward within the cap (never overflows into the nav,
     never truncated). A fixed width was wrong here: it left short logos
     floating in dead space. */
  max-width: 200px;
  flex-shrink: 0;
  min-width: 0;
  display: inline-flex;
  align-items: center;
}
@media (min-width: 720px) {
  .sx-header__logo { font-size: 22px; max-width: 220px; }
}
/* Image logo (customer-uploaded). ADDITIVE — only applies to the
   .sx-header__logo--img variant the renderer emits when a logo image
   exists; text logos are untouched. The <img> fits the header height
   and scales down on small screens. */
.sx-header__logo--img {
  /* SAME fixed brand slot as the text logo (width matches the values in
     .sx-header__logo above) so text and image occupy an identical box and
     the nav never shifts between the two. The <img> is contained inside,
     left-aligned and vertically centered, proportions preserved. */
  display: flex;
  align-items: center;
  justify-content: center;   /* CENTERED in the fixed slot, like the text */
  padding: 1px 0;
  flex-shrink: 0;
  flex-grow: 0;
  width: 180px;
}
.sx-header__logo-img {
  height: var(--sx-logo-h, 46px);   /* Logo Studio sets --sx-logo-h inline */
  width: auto;
  max-width: 100%;
  object-fit: contain;   /* preserve the logo's own proportions */
  display: block;
}
@media (min-width: 720px) {
  .sx-header__logo--img { width: 240px; }
  .sx-header__logo-img { height: var(--sx-logo-h, 56px); }
}
/* Logo Studio — light/dark variant swap. ADDITIVE: only fires when the
   renderer emitted BOTH a --light (color) and --dark (white) <img>. Show
   the color logo by default; over a TRANSPARENT header on the hero (not
   yet scrolled) show the white one so it never disappears on a dark hero.
   A single-variant logo has neither class, so these rules never touch it. */
.sx-header__logo-img--dark { display: none; }
.sx-header.sx-header--transparent:not(.is-scrolled) .sx-header__logo-img--light { display: none; }
.sx-header.sx-header--transparent:not(.is-scrolled) .sx-header__logo-img--dark { display: block; }
/* Backdrop chip — when the owner picked a light/dark card in Logo Studio.
   Hugs the logo (drops the fixed brand-slot width) so it reads as an
   intentional badge instead of a floating box. */
.sx-header__logo--img.sx-header__logo--bd { width: auto; padding: 5px 9px; border-radius: 10px; }
.sx-header__logo--bd-light { background: #ffffff; }
.sx-header__logo--bd-dark  { background: #160f2e; }
/* Footer image logo — same additive pattern, slightly larger. min-height
   reserves the logo's vertical space before the <img> paints, so the footer
   doesn't shift up when it loads (CLS). */
.sx-footer__logo--img { display: inline-flex; align-items: center; min-height: var(--sx-footer-logo-h, 104px); }
.sx-footer__logo-img {
  height: var(--sx-footer-logo-h, 104px);
  width: auto;
  max-width: 340px;
  object-fit: contain;
  display: block;
}

/* Desktop nav — hidden below 1180px, hamburger takes over there.
   Bumped from 1024px because a typical template ships 6-8 nav items
   PLUS lang toggle + branded CTA button; under 1180px the row
   couldn't fit without crushing the logo to "Locksmith Pr…". The
   nav itself shrinks within the remaining space (min-width: 0 +
   tighter gaps) and the labels stay nowrap. */
/* Todos los enlaces caben: la barra APRIETA, no esconde.
 *
 * Antes, con más de siete páginas, las últimas se iban a un desplegable
 * "More" — y media navegación quedaba detrás de un clic. Las webs de negocio
 * no hacen eso: un visitante que no ve "Contacto" asume que no hay.
 *
 * `flex-wrap: nowrap` + un espaciado que se encoge con `clamp` mantienen la
 * fila en una línea hasta bien entrado el rango de escritorio; por debajo de
 * 1024 px manda el menú móvil, que ya los mostraba todos. */
.sx-header__nav {
  display: none;
  /* `column-gap` aprieta entre enlaces; `row-gap` sólo entra en juego si la
     barra se parte, y entonces conviene que respire. */
  column-gap: clamp(9px, 1.1vw, 14px);
  row-gap: 6px;
  min-width: 0;
  flex: 0 1 auto;
  /* SE PARTE ANTES QUE DESBORDARSE.
   *
   * Con `nowrap`, una plantilla con etiquetas largas —"THE VOLT DETAIL
   * FINISH", "SIMPLE PACKAGES"— hacía que la fila creciera por encima del
   * selector de idioma y del botón de reserva: los enlaces quedaban cortados a
   * media palabra y encima del CTA, que es el elemento que factura.
   *
   * Envolver es lo único que no pierde nada: no esconde enlaces como el
   * desplegable "More", no los corta, y sólo cuesta una segunda línea de
   * cabecera en las plantillas que de verdad la necesitan. */
  flex-wrap: wrap;
  justify-content: flex-end;
}
.sx-header__nav a {
  text-decoration: none;
  font-size: clamp(11px, 0.85vw, 12px);
  font-weight: 600;
  letter-spacing: 0.02em;
  white-space: nowrap;
  color: var(--sx-color-ink);
  text-transform: uppercase;
  transition: color 0.2s ease;
  white-space: nowrap;
}
.sx-header__nav a:hover { color: var(--sx-color-primary-ink, var(--sx-color-primary)); }
@media (min-width: 1180px) {
  .sx-header__nav { display: flex; gap: 16px; }
}

/* Dark-theme header variant — some templates intentionally run on
   near-black canvases (e.g. neon / nightlife / premium tech). The
   default white frosted header makes their nav disappear once the
   theme flips `ink` to a light tone. When runtime.js detects a dark
   theme it adds `.sx-theme-dark` to <html>/<body>; these overrides
   keep the menu legible without affecting light templates. */
html.sx-theme-dark .sx-header {
  background: transparent;
  border-bottom-color: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
html.sx-theme-dark .sx-header.is-scrolled {
  background: #000;
  border-bottom-color: rgba(255, 255, 255, 0.08);
  backdrop-filter: saturate(180%) blur(8px);
  -webkit-backdrop-filter: saturate(180%) blur(8px);
}
html.sx-theme-dark .sx-header__logo,
html.sx-theme-dark .sx-header__nav a,
html.sx-theme-dark .sx-header__cart,
html.sx-theme-dark .sx-header__lang-chip {
  color: #fff;
}
html.sx-theme-dark .sx-header__burger span { background: #fff; }
html.sx-theme-dark .sx-header__nav a:hover { color: var(--sx-color-accent-ink, var(--sx-color-accent)); }
html.sx-theme-dark .sx-header__burger:hover { background: color-mix(in srgb, var(--sx-color-accent) 10%, var(--sx-color-bg-alt)); }
html.sx-theme-dark .sx-header .sx-btn--primary {
  background: var(--sx-color-accent-fill, var(--sx-color-accent));
  color: var(--sx-color-on-primary);
  border-color: var(--sx-color-accent-ink, var(--sx-color-accent));
}
html.sx-theme-dark .sx-header .sx-btn--primary:hover {
  background: transparent;
  color: var(--sx-color-accent-ink, var(--sx-color-accent));
  border-color: var(--sx-color-accent-ink, var(--sx-color-accent));
}

/* El grupo de la derecha NO cede: idioma y botón de reserva son lo que
   factura, y son lo primero que tapaba la barra al desbordarse. */
.sx-header__actions { display: flex; align-items: center; gap: 8px; flex-shrink: 0; min-width: 0; }
@media (min-width: 720px) {
  .sx-header__actions { gap: 12px; }
}

/* Hide some actions on mobile/tablet (lang toggle + CTA move into the
   mobile menu drawer instead, so the header stays uncluttered). The
   cart icon stays visible on every breakpoint — it's a high-intent
   action and the count badge is part of conversion. */
@media (max-width: 1179px) {
  .sx-header__lang { display: none !important; }
  .sx-header__actions > .sx-btn { display: none !important; }
}

/* Hamburger button — only below 1180px. 44×44 tap target (iOS HIG).
   Three bars animate into an X when the menu is open. */
.sx-header__burger {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  width: 44px;
  height: 44px;
  border: 0;
  background: transparent;
  cursor: pointer;
  padding: 0;
  border-radius: 8px;
  transition: background 0.15s;
}
.sx-header__burger:hover { background: var(--sx-color-bg-alt); }
.sx-header__burger span {
  display: block;
  width: 22px;
  height: 2px;
  border-radius: 2px;
  background: var(--sx-color-ink);
  transition: transform 0.25s ease, opacity 0.2s ease;
}
@media (min-width: 1180px) {
  .sx-header__burger { display: none; }
}

/* ── Mobile menu drawer ───────────────────────────────────────── */
/*
 * Full-screen overlay that slides in from the right on mobile/iPad.
 * Sits at z-index 110 — above the sticky header AND above the cart
 * drawer (100) so it can never be visually trapped. Contains:
 *   • Logo + close button at the top
 *   • Full-bleed nav (one link per row, large tap targets)
 *   • Bottom: language toggle + CTA (Reservar / Book)
 *
 * Only mounts on mobile-width screens — hidden entirely on desktop.
 */
.sx-mobile-menu {
  position: fixed;
  inset: 0;
  z-index: 110;
  visibility: hidden;
  pointer-events: none;
}
.sx-mobile-menu.is-open {
  visibility: visible;
  pointer-events: auto;
}
@media (min-width: 1180px) {
  /* Mobile menu has no place on desktop. */
  .sx-mobile-menu { display: none !important; }
}
.sx-mobile-menu__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.45);
  opacity: 0;
  transition: opacity 0.3s ease;
}
.sx-mobile-menu.is-open .sx-mobile-menu__backdrop { opacity: 1; }
.sx-mobile-menu__panel {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(360px, 88vw);
  background: var(--sx-color-bg);
  display: flex;
  flex-direction: column;
  box-shadow: -20px 0 60px rgba(0, 0, 0, 0.2);
  transform: translateX(100%);
  transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1);
  /* iOS safe-area for the bottom (home indicator) */
  padding-bottom: env(safe-area-inset-bottom, 0);
}
.sx-mobile-menu.is-open .sx-mobile-menu__panel { transform: translateX(0); }
.sx-mobile-menu__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px 20px;
  border-bottom: 1px solid var(--sx-color-border);
  flex-shrink: 0;
}
.sx-mobile-menu__head .sx-header__logo {
  font-size: 20px;
  /* Inside the drawer, drop the fixed slot — use available width and leave
     room for the 40px close button (+ gap) so a long name wraps within the
     panel instead of colliding with the X. */
  width: auto;
  max-width: calc(100% - 56px);
}
.sx-mobile-menu__close {
  width: 40px;
  height: 40px;
  border: 0;
  background: transparent;
  border-radius: 999px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--sx-color-ink);
  transition: background 0.15s;
}
.sx-mobile-menu__close:hover { background: var(--sx-color-bg-alt); }
.sx-mobile-menu__nav {
  flex: 1;
  overflow-y: auto;
  padding: 16px 0;
}
.sx-mobile-menu__nav a {
  display: block;
  padding: 16px 24px;
  font-family: var(--sx-font-body);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--sx-color-ink);
  text-decoration: none;
  border-bottom: 1px solid var(--sx-color-border);
  transition: color 0.15s, background 0.15s;
}
.sx-mobile-menu__nav a:hover {
  color: var(--sx-color-primary-ink, var(--sx-color-primary));
  background: var(--sx-color-bg-alt);
}
html.sx-theme-dark .sx-mobile-menu__nav a:hover { color: var(--sx-color-accent-ink, var(--sx-color-accent)); }
.sx-mobile-menu__nav a:last-child { border-bottom: 0; }
.sx-mobile-menu__foot {
  padding: 20px 24px;
  border-top: 1px solid var(--sx-color-border);
  display: flex;
  flex-direction: column;
  gap: 14px;
  align-items: stretch;
  flex-shrink: 0;
}
.sx-mobile-menu__foot .sx-header__lang {
  display: inline-flex !important;
  align-self: center;
}
.sx-mobile-menu__foot .sx-btn {
  display: inline-flex !important;
  width: 100%;
  justify-content: center;
}
html.sx-theme-dark .sx-mobile-menu__close:hover { background: color-mix(in srgb, var(--sx-color-accent) 10%, var(--sx-color-bg-alt)); }
html.sx-theme-dark .sx-mobile-menu__foot .sx-btn--primary {
  background: var(--sx-color-accent-fill, var(--sx-color-accent));
  color: var(--sx-color-on-primary);
  border-color: var(--sx-color-accent-ink, var(--sx-color-accent));
}
html.sx-theme-dark .sx-mobile-menu__foot .sx-btn--primary:hover {
  background: transparent;
  color: var(--sx-color-accent-ink, var(--sx-color-accent));
  border-color: var(--sx-color-accent-ink, var(--sx-color-accent));
}
/* Body lock when mobile menu is open (prevents background scroll). */
body.sx-no-scroll { overflow: hidden; }
/* Hide the floating widget rail (mail/phone/share/chat) and the chat
   launcher while the mobile menu drawer is open. The drawer is its own
   full-screen action surface — having a second action bar pinned at the
   bottom of the viewport crashes visually with the drawer's footer
   (lang toggle + CTAs) and the iOS home indicator. Widget reappears
   automatically when the drawer closes. !important is required because
   .sxw-rail's styles are injected dynamically AFTER this stylesheet by
   the widget bundle, with display:flex via the injected rule. */
body.sx-no-scroll #sxw-rail,
body.sx-no-scroll .sxw-rail,
body.sx-no-scroll .sxw-launcher { display: none !important; }
/* Reserve enough space at the bottom of the mobile-menu panel so the
   footer CTA (Call button + lang toggle) stays clear of:
   1. the iOS home indicator (env safe-area-inset-bottom)
   2. the floating widget rail (.sxw-rail) which sits at ~6px + 56px
      from the bottom edge in production. Even though we hide the rail
      while the menu is open, adding the clearance defends against
      future changes that may keep it visible (e.g. an "Always show
      Call" rail toggle the customer enables) and makes the close →
      rail-reappear transition visually clean.
   Total reserved height: safe-area + 88px ≈ rail height (56px) +
   visual breathing room (32px). Universal across templates. */
.sx-mobile-menu__foot { padding-bottom: calc(env(safe-area-inset-bottom, 0px) + 88px) !important; }

/* Language toggle (ES / EN chips in header) */
.sx-header__lang {
  display: inline-flex;
  align-items: center;
  background: var(--sx-color-bg-alt);
  border: 1px solid var(--sx-color-border);
  border-radius: var(--sx-radius-pill);
  padding: 2px;
  gap: 2px;
  --sx-color-ink: var(--sx-color-ink-on-alt);
  --sx-color-ink-soft: var(--sx-color-ink-soft-on-alt, var(--sx-color-ink-on-alt));
  --sx-color-accent-ink: var(--sx-color-accent-ink-on-alt, var(--sx-color-accent-ink));
  --sx-color-primary-ink: var(--sx-color-primary-ink-on-alt, var(--sx-color-primary-ink));
  --sx-color-stars: var(--sx-color-stars-on-alt, var(--sx-color-stars));
  color: var(--sx-color-ink);
}
.sx-header__lang-chip {
  border: 0;
  background: transparent;
  font-family: var(--sx-font-body);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.1em;
  color: var(--sx-color-ink-soft);
  padding: 6px 12px;
  border-radius: var(--sx-radius-pill);
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
  min-width: 38px;
}
.sx-header__lang-chip:hover { color: var(--sx-color-ink); }
.sx-header__lang-chip.is-active {
  background: var(--sx-color-ink);
  /* text = the toggle's own surface (bg-alt); ink↔bg-alt are derived to
     contrast ≥4.5, so the active chip stays legible even when a dark bg_alt
     flips --sx-color-ink to a light value (was hardcoded #fff → white-on-white). */
  color: var(--sx-color-bg-alt);
}
html.sx-theme-dark .sx-header__lang-chip.is-active {
  background: #000;
  color: #fff;
}
/* Cart icon in the header */
.sx-header__cart {
  position: relative;
  width: 40px;
  height: 40px;
  border-radius: 999px;
  background: transparent;
  border: 1px solid transparent;
  color: var(--sx-color-ink);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
}
.sx-header__cart:hover { background: var(--sx-color-bg-alt); border-color: var(--sx-color-border); }
.sx-header__cart svg { width: 20px; height: 20px; }
.sx-header__cart-count {
  position: absolute;
  top: 2px;
  right: 2px;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: 999px;
  background: var(--sx-color-primary-fill, var(--sx-color-primary));
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  display: none;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}
.sx-header__cart.has-items .sx-header__cart-count { display: inline-flex; }

/* Cart drawer */
.sx-cart-drawer {
  position: fixed;
  inset: 0;
  z-index: 100;
  pointer-events: none;
  visibility: hidden;
}
.sx-cart-drawer.is-open {
  visibility: visible;
  pointer-events: auto;
}
.sx-cart-drawer__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.4);
  opacity: 0;
  transition: opacity 0.25s ease;
}
.sx-cart-drawer.is-open .sx-cart-drawer__backdrop { opacity: 1; }
.sx-cart-drawer__panel {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(420px, 100vw);
  background: var(--sx-color-bg);
  box-shadow: -20px 0 60px rgba(0, 0, 0, 0.18);
  display: flex;
  flex-direction: column;
  transform: translateX(100%);
  transition: transform 0.3s ease;
}
.sx-cart-drawer.is-open .sx-cart-drawer__panel { transform: translateX(0); }
.sx-cart-drawer__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 20px 24px;
  border-bottom: 1px solid var(--sx-color-border);
}
.sx-cart-drawer__head h3 { font-family: var(--sx-font-display); font-size: 20px; }
.sx-cart-drawer__close {
  background: transparent;
  border: 0;
  width: 36px;
  height: 36px;
  border-radius: 999px;
  cursor: pointer;
  color: var(--sx-color-ink-soft);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.sx-cart-drawer__close:hover { background: var(--sx-color-bg-alt); color: var(--sx-color-ink); }
.sx-cart-drawer__body {
  flex: 1;
  overflow-y: auto;
  padding: 16px 24px;
}
.sx-cart-drawer__empty {
  text-align: center;
  padding: 64px 16px;
  color: var(--sx-color-ink-soft);
  font-size: 14px;
}
.sx-cart-line {
  display: flex;
  gap: 12px;
  padding: 16px 0;
  border-bottom: 1px solid var(--sx-color-border);
}
.sx-cart-line:last-child { border-bottom: 0; }
.sx-cart-line__img {
  width: 64px;
  height: 64px;
  border-radius: var(--sx-radius-md);
  background: var(--sx-color-bg-alt);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  flex-shrink: 0;
  --sx-color-ink: var(--sx-color-ink-on-alt);
  --sx-color-ink-soft: var(--sx-color-ink-soft-on-alt, var(--sx-color-ink-on-alt));
  --sx-color-accent-ink: var(--sx-color-accent-ink-on-alt, var(--sx-color-accent-ink));
  --sx-color-primary-ink: var(--sx-color-primary-ink-on-alt, var(--sx-color-primary-ink));
  --sx-color-stars: var(--sx-color-stars-on-alt, var(--sx-color-stars));
  color: var(--sx-color-ink);
}
.sx-cart-line__img img { max-width: 80%; max-height: 80%; object-fit: contain; }
.sx-cart-line__body { flex: 1; min-width: 0; }
.sx-cart-line__title { font-size: 13px; font-weight: 700; margin-bottom: 4px; }
.sx-cart-line__cat { font-size: 11px; color: var(--sx-color-ink-soft); text-transform: uppercase; letter-spacing: 0.1em; margin-bottom: 6px; }
.sx-cart-line__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.sx-cart-line__qty {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--sx-color-border);
  border-radius: var(--sx-radius-md);
  overflow: hidden;
}
.sx-cart-line__qty button {
  width: 28px; height: 28px;
  background: transparent; border: 0;
  cursor: pointer;
  color: var(--sx-color-ink-soft);
}
.sx-cart-line__qty button:hover { background: var(--sx-color-bg-alt); color: var(--sx-color-ink); }
.sx-cart-line__qty span {
  min-width: 32px;
  text-align: center;
  font-size: 13px;
  font-weight: 600;
}
.sx-cart-line__price { font-weight: 700; font-size: 14px; }
.sx-cart-line__remove {
  background: transparent; border: 0;
  color: var(--sx-color-ink-soft);
  cursor: pointer;
  padding: 4px;
}
.sx-cart-line__remove:hover { color: #c00; }
.sx-cart-drawer__foot {
  padding: 20px 24px;
  border-top: 1px solid var(--sx-color-border);
  background: var(--sx-color-bg-alt);
  --sx-color-ink: var(--sx-color-ink-on-alt);
  --sx-color-ink-soft: var(--sx-color-ink-soft-on-alt, var(--sx-color-ink-on-alt));
  --sx-color-accent-ink: var(--sx-color-accent-ink-on-alt, var(--sx-color-accent-ink));
  --sx-color-primary-ink: var(--sx-color-primary-ink-on-alt, var(--sx-color-primary-ink));
  --sx-color-stars: var(--sx-color-stars-on-alt, var(--sx-color-stars));
  color: var(--sx-color-ink);
}
.sx-cart-drawer__total {
  display: flex;
  justify-content: space-between;
  font-size: 16px;
  font-weight: 700;
  margin-bottom: 16px;
}
.sx-cart-drawer__total small { font-size: 11px; font-weight: 500; color: var(--sx-color-ink-soft); display: block; margin-top: 2px; }
.sx-cart-drawer__checkout {
  width: 100%;
  padding: 16px;
  background: var(--sx-color-primary-fill, var(--sx-color-primary));
  color: #fff;
  border: 0;
  border-radius: var(--sx-radius-md);
  font-family: var(--sx-font-body);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 0.2s ease, transform 0.1s ease;
}
.sx-cart-drawer__checkout:hover { background: var(--sx-color-primary-dark); }
.sx-cart-drawer__checkout:active { transform: scale(0.98); }
.sx-cart-drawer__powered {
  text-align: center;
  margin-top: 12px;
  font-size: 10px;
  color: var(--sx-color-ink-soft);
}

/* Coupon row in the cart drawer */
.sx-cart-coupon { display: flex; gap: 8px; margin-bottom: 12px; }
.sx-cart-coupon input {
  flex: 1; min-width: 0; padding: 10px 12px;
  border: 1px solid var(--sx-color-border); border-radius: var(--sx-radius-md);
  font-family: var(--sx-font-body); font-size: 13px; background: #fff;
}
.sx-cart-coupon > button {
  padding: 0 16px; border: 1px solid var(--sx-color-primary); background: transparent;
  color: var(--sx-color-primary-ink, var(--sx-color-primary)); border-radius: var(--sx-radius-md);
  font-family: var(--sx-font-body); font-size: 11px; font-weight: 700;
  letter-spacing: 0.1em; text-transform: uppercase; cursor: pointer; white-space: nowrap;
}
.sx-cart-coupon > button:hover { background: var(--sx-color-primary-fill, var(--sx-color-primary)); color: #fff; }
.sx-cart-coupon--on {
  align-items: center; justify-content: space-between;
  font-size: 13px; font-weight: 600; color: var(--sx-color-ink);
}
.sx-cart-coupon--on > button {
  padding: 0; border: 0; background: none; color: var(--sx-color-ink-soft);
  text-transform: none; letter-spacing: 0; font-weight: 500; text-decoration: underline; cursor: pointer;
}
.sx-cart-coupon--on > button:hover { color: var(--sx-color-ink); }
.sx-cart-coupon__msg { font-size: 12px; color: #b91c1c; margin: -6px 0 12px; }
.sx-cart-coupon__msg:empty { display: none; margin: 0; }

/* Thank-you modal (post-Stripe-checkout redirect) */
.sx-thanks-modal {
  position: fixed;
  inset: 0;
  z-index: 110;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  opacity: 0;
  transition: opacity 0.25s ease;
  pointer-events: none;
}
.sx-thanks-modal.is-open { opacity: 1; pointer-events: auto; }
.sx-thanks-modal__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0,0,0,0.5);
  backdrop-filter: blur(6px);
}
.sx-thanks-modal__card {
  position: relative;
  background: var(--sx-color-surface);
  border-radius: var(--sx-radius-xl);
  padding: 48px 40px;
  max-width: 480px;
  text-align: center;
  box-shadow: 0 30px 80px rgba(0,0,0,0.25);
  transform: translateY(20px);
  transition: transform 0.25s ease;
  --sx-color-ink: var(--sx-color-ink-on-surface);
  --sx-color-ink-soft: var(--sx-color-ink-soft-on-surface, var(--sx-color-ink-on-surface));
  --sx-color-accent-ink: var(--sx-color-accent-ink-on-surface, var(--sx-color-accent-ink));
  --sx-color-primary-ink: var(--sx-color-primary-ink-on-surface, var(--sx-color-primary-ink));
  --sx-color-stars: var(--sx-color-stars-on-surface, var(--sx-color-stars));
  color: var(--sx-color-ink);
}
.sx-thanks-modal.is-open .sx-thanks-modal__card { transform: translateY(0); }
.sx-thanks-modal__icon {
  width: 80px;
  height: 80px;
  margin: 0 auto 24px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--sx-color-primary) 15%, transparent);
  color: var(--sx-color-primary-ink, var(--sx-color-primary));
  display: flex;
  align-items: center;
  justify-content: center;
}
.sx-thanks-modal h2 {
  font-family: var(--sx-font-display);
  font-size: 28px;
  margin-bottom: 12px;
}
.sx-thanks-modal p {
  color: var(--sx-color-ink-soft);
  margin-bottom: 28px;
  line-height: 1.55;
}

/* Product detail modal (opens when a card image/title is clicked) */
.sx-pd-modal {
  position: fixed;
  inset: 0;
  z-index: 105;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.25s ease, visibility 0.25s;
}
.sx-pd-modal.is-open { opacity: 1; visibility: visible; }
.sx-pd-modal__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0,0,0,0.55);
}
.sx-pd-modal__card {
  position: relative;
  background: var(--sx-color-bg);
  border-radius: var(--sx-radius-xl);
  width: min(960px, 100%);
  max-height: 92vh;
  overflow: hidden;
  display: grid;
  grid-template-columns: 1fr;
  box-shadow: 0 30px 80px rgba(0,0,0,0.3);
  transform: translateY(20px);
  transition: transform 0.25s ease;
}
.sx-pd-modal.is-open .sx-pd-modal__card { transform: translateY(0); }
@media (min-width: 720px) {
  .sx-pd-modal__card { grid-template-columns: 1fr 1fr; }
}

/* ── URGENT storefront popup fixes ──────────────────────────────────────
   (1) Every popup must sit ABOVE the chat widget (z-index 2147483646),
       which otherwise covers the popup + the Add-to-cart button.
   (2) On phones the product modal must SCROLL — long descriptions + the
       Add-to-cart were clipped by the card's overflow:hidden with no scroll. */
.sx-pd-modal, .sx-cart-drawer, .sx-thanks-modal { z-index: 2147483647; }

@media (max-width: 719px) {
  /* Stack the card and let the BODY scroll within the viewport; cap the image
     so the description + buy button always have room and are reachable. */
  .sx-pd-modal__card { display: flex; flex-direction: column; max-height: 90vh; }
  .sx-pd-modal__gallery { min-height: 0; max-height: 32vh; flex: 0 0 auto; }
  .sx-pd-modal__main-img { min-height: 0; }
  .sx-pd-modal__body { flex: 1 1 auto; min-height: 0; padding: 20px; -webkit-overflow-scrolling: touch; }
}
.sx-pd-modal__close {
  position: absolute;
  top: 16px;
  right: 16px;
  z-index: 1;
  width: 40px;
  height: 40px;
  border-radius: 999px;
  background: rgba(255,255,255,0.95);
  border: 1px solid var(--sx-color-border);
  color: var(--sx-color-ink);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.sx-pd-modal__close:hover { background: var(--sx-color-ink); color: #fff; }
.sx-pd-modal__gallery {
  background: var(--sx-color-bg-alt);
  display: flex;
  flex-direction: column;
  min-height: 320px;
  overflow: hidden;
  --sx-color-ink: var(--sx-color-ink-on-alt);
  --sx-color-ink-soft: var(--sx-color-ink-soft-on-alt, var(--sx-color-ink-on-alt));
  --sx-color-accent-ink: var(--sx-color-accent-ink-on-alt, var(--sx-color-accent-ink));
  --sx-color-primary-ink: var(--sx-color-primary-ink-on-alt, var(--sx-color-primary-ink));
  --sx-color-stars: var(--sx-color-stars-on-alt, var(--sx-color-stars));
  color: var(--sx-color-ink);
}
.sx-pd-modal__main-img {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 32px;
}
.sx-pd-modal__main-img img {
  max-width: 100%;
  max-height: 400px;
  object-fit: contain;
}
.sx-pd-modal__thumbs {
  display: flex;
  gap: 8px;
  padding: 0 16px 16px;
  flex-wrap: wrap;
  justify-content: center;
}
.sx-pd-modal__thumb {
  width: 56px;
  height: 56px;
  border-radius: 10px;
  overflow: hidden;
  padding: 0;
  border: 2px solid transparent;
  background: #fff;
  cursor: pointer;
  flex: 0 0 auto;
  transition: border-color 0.15s ease;
}
.sx-pd-modal__thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.sx-pd-modal__thumb:hover { border-color: var(--sx-color-ink-soft); }
.sx-pd-modal__thumb.is-active { border-color: var(--sx-color-primary, var(--sx-color-ink)); }
.sx-pd-modal__body {
  padding: 32px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}
.sx-pd-modal__cat {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--sx-color-ink-soft);
  margin-bottom: 8px;
}
.sx-pd-modal__title {
  font-family: var(--sx-font-display);
  font-size: 28px;
  margin-bottom: 8px;
}
.sx-pd-modal__sub {
  color: var(--sx-color-ink-soft);
  font-size: 14px;
  margin-bottom: 20px;
}
.sx-pd-modal__price {
  font-size: 22px;
  font-weight: 700;
  margin-bottom: 8px;
  display: inline-flex;
  align-items: baseline;
  gap: 10px;
}
.sx-pd-modal__price--old {
  font-size: 16px;
  font-weight: 500;
  color: var(--sx-color-ink-soft);
  text-decoration: line-through;
}
.sx-pd-modal__price--sale { color: var(--sx-color-primary-ink, var(--sx-color-primary)); }
.sx-pd-modal__desc {
  margin: 20px 0;
  color: var(--sx-color-ink);
  font-size: 14px;
  line-height: 1.65;
}
.sx-pd-modal__actions {
  margin-top: auto;
  display: flex;
  gap: 12px;
  align-items: center;
}
.sx-pd-modal__qty {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--sx-color-border);
  border-radius: var(--sx-radius-md);
  overflow: hidden;
  flex-shrink: 0;
}
.sx-pd-modal__qty button {
  width: 36px; height: 44px;
  background: transparent; border: 0;
  cursor: pointer;
  color: var(--sx-color-ink-soft);
  font-size: 18px;
}
.sx-pd-modal__qty button:hover { background: var(--sx-color-bg-alt); color: var(--sx-color-ink); }
.sx-pd-modal__qty span {
  min-width: 40px;
  text-align: center;
  font-weight: 600;
}
.sx-pd-modal__add { flex: 1; }

/* Variant pickers — option rows with chip buttons */
.sx-pd-modal__optrow { margin: 16px 0; }
.sx-pd-modal__optname {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--sx-color-ink-soft);
  margin-bottom: 8px;
}
.sx-pd-modal__optchips { display: flex; flex-wrap: wrap; gap: 8px; }
.sx-pd-modal__chip {
  padding: 8px 16px;
  border: 1.5px solid var(--sx-color-border);
  border-radius: var(--sx-radius-md);
  background: var(--sx-color-surface);
  color: var(--sx-color-ink);
  font-family: var(--sx-font-body);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s, color 0.15s, transform 0.1s;
  --sx-color-ink: var(--sx-color-ink-on-surface);
  --sx-color-ink-soft: var(--sx-color-ink-soft-on-surface, var(--sx-color-ink-on-surface));
  --sx-color-accent-ink: var(--sx-color-accent-ink-on-surface, var(--sx-color-accent-ink));
  --sx-color-primary-ink: var(--sx-color-primary-ink-on-surface, var(--sx-color-primary-ink));
  --sx-color-stars: var(--sx-color-stars-on-surface, var(--sx-color-stars));
  color: var(--sx-color-ink);
}
.sx-pd-modal__chip:hover {
  border-color: var(--sx-color-ink-soft);
}
.sx-pd-modal__chip:active { transform: scale(0.97); }
/* Colors & sizes: a color option shows its real swatch next to the name.
   Sizes have no swatch, so the dot simply never renders for them. */
.sx-pd-modal__dot {
  display: inline-block;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  margin-right: 7px;
  vertical-align: -1px;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.18);
}
.sx-pd-modal__chip.is-selected {
  border-color: var(--sx-color-primary-ink, var(--sx-color-primary));
  background: var(--sx-color-primary-fill, var(--sx-color-primary));
  color: #fff;
}

/* Thank-you modal — itemized receipt body */
.sx-thanks-order {
  text-align: left;
  width: 100%;
  margin-bottom: 24px;
}
.sx-thanks-order__num {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--sx-color-ink-soft);
  margin-bottom: 16px;
}
.sx-thanks-order__lines {
  border-top: 1px solid var(--sx-color-border);
  padding: 4px 0;
}
.sx-thanks-line {
  display: grid;
  grid-template-columns: 36px 1fr auto;
  gap: 12px;
  align-items: center;
  padding: 10px 0;
  border-bottom: 1px solid var(--sx-color-border);
}
.sx-thanks-line__qty {
  font-size: 13px;
  font-weight: 700;
  color: var(--sx-color-ink-soft);
}
.sx-thanks-line__title { font-size: 14px; font-weight: 500; min-width: 0; }
.sx-thanks-line__price { font-size: 14px; font-weight: 700; }
.sx-thanks-order__totals { font-size: 13px; margin-top: 16px; }
.sx-thanks-order__totals > div { display: flex; justify-content: space-between; padding: 4px 0; color: var(--sx-color-ink-soft); }
.sx-thanks-order__total {
  border-top: 1px solid var(--sx-color-border);
  padding-top: 12px !important;
  margin-top: 8px;
  color: var(--sx-color-ink) !important;
  font-size: 17px !important;
  font-weight: 800 !important;
}
.sx-thanks-email { font-size: 13px; color: var(--sx-color-ink-soft); margin-top: 16px; }
.sx-thanks-email strong { color: var(--sx-color-ink); margin-left: 3px; }
.sx-thanks-actions {
  display: flex;
  gap: 10px;
  justify-content: center;
  flex-wrap: wrap;
}

/* ── Footer ───────────────────────────────────────────────────── */
.sx-footer {
  background: var(--sx-color-ink);
  color: rgba(255,255,255,0.7);
  padding: 64px 0 32px;
  /* No margin-top here — the last content section's own padding
     handles the spacing. A 96px margin on the footer created a
     visible white block between cream-bg sections (contact) and the
     dark footer, which looked like a bug. */
}
.sx-footer__top {
  display: grid;
  grid-template-columns: 1fr;
  gap: 40px;
  margin-bottom: 40px;
}
@media (min-width: 720px) {
  .sx-footer__top { grid-template-columns: 1.4fr 1fr 1fr; }
}
.sx-footer__brand h4 {
  font-family: var(--sx-font-display);
  color: #fff;
  font-size: 22px;
  margin-bottom: 12px;
}
.sx-footer h5 {
  font-family: var(--sx-font-body);
  text-transform: uppercase;
  letter-spacing: 0.18em;
  font-size: 11px;
  color: rgba(255,255,255,0.5);
  margin-bottom: 16px;
}
.sx-footer ul { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 10px; }
.sx-footer a { text-decoration: none; color: rgba(255,255,255,0.85); font-size: 14px; transition: color 0.2s; }
.sx-footer a:hover { color: var(--sx-color-primary-ink, var(--sx-color-primary)); }
.sx-footer__bottom {
  border-top: 1px solid rgba(255,255,255,0.08);
  padding-top: 24px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  align-items: center;
  font-size: 12px;
  color: rgba(255,255,255,0.5);
}
@media (min-width: 720px) {
  .sx-footer__bottom { flex-direction: row; justify-content: space-between; }
}
/* "Made with Salesio" backlink — subtle but discoverable. Inherits
   the lighter `.sx-footer a` color so it pops out of the 50%-opacity
   bottom-row text, with an underline on hover so it reads as a link
   (the surrounding "© 2026 Tony Brannum" stays plain text). */
.sx-footer__credit { font-weight: 500; }
.sx-footer__credit:hover { text-decoration: underline; }
.sx-footer__socials { display: flex; gap: 14px; }
.sx-footer__socials a {
  width: 36px; height: 36px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 999px;
  background: rgba(255,255,255,0.08);
  transition: background 0.2s ease;
}
/* Hover: fill the pill with the brand color AND flip the icon to the on-primary
   color. Without the explicit color, `.sx-footer a:hover { color: primary }`
   (the footer-link hover) made the svg's `stroke:currentColor` = primary on a
   primary background → the icon vanished and the pill looked like a solid blob. */
.sx-footer__socials a:hover { background: var(--sx-color-primary-fill, var(--sx-color-primary)); color: var(--sx-color-on-primary, #fff); }
.sx-footer__socials svg { width: 16px; height: 16px; }

/* ── Dark mode: flip the inverse pair ────────────────────────────────
   On a dark site an "always-contrasting" panel has to become LIGHT, and
   its text dark, or it disappears into the page. Flipping both halves
   together here is what makes the pair safe: no section can end up with
   a light background and light text, because neither half is chosen
   independently. Tuned off the page background rather than pure white so
   the panel reads as a designed surface, not a hole in the page. */
html.sx-theme-dark {
  --sx-color-inverse-bg:       #f4f4f6;
  --sx-color-inverse-ink:      #14131c;
  --sx-color-inverse-ink-soft: rgba(20, 19, 28, 0.72);
  --sx-color-inverse-border:   rgba(20, 19, 28, 0.14);
  /* The inverse panel is now LIGHT, so the accent on it must go darker,
     not lighter — the opposite adjustment from light mode. runtime.js
     computes the real value from the site's own brand hue. */
  --sx-color-accent-on-inverse: #8a2f2f;
  --sx-color-stars:             #f5c46a;
}

/* Dark-theme footer: the default `background: var(--sx-color-ink)` rule
   assumes ink == dark text color (light theme convention). In dark themes
   ink is light, so the footer comes out white-on-white. Use bg_alt — the
   deepest neutral in dark palettes — instead. */
/* Footer gets a subtle primary tint over bg_alt — so it reads as its
   own "footer chrome" surface instead of fading into the adjacent
   section bg. The 10% mix is gentle enough that it stays dark + on-
   brand (no jarring color shift). */
html.sx-theme-dark .sx-footer {
  background: color-mix(in srgb, var(--sx-color-primary) 10%, var(--sx-color-bg-alt));
}

/* Preview-only — visual breathing room between stacked footer demos */
.sx-footer-preview {
  padding: 48px 0;
  margin: 48px 0;
  position: relative;
}

/* ── footer variant: "centered" ───────────────────────────────── */
.sx-footer__wrap.sx-footer--centered .sx-footer__top {
  grid-template-columns: 1fr;
  text-align: center;
  gap: 28px;
}
.sx-footer__wrap.sx-footer--centered .sx-footer__top ul {
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: center;
  gap: 20px;
}
.sx-footer__wrap.sx-footer--centered .sx-footer__socials { justify-content: center; }
.sx-footer__wrap.sx-footer--centered .sx-footer__brand p { max-width: 480px; margin-inline: auto; }
.sx-footer__wrap.sx-footer--centered .sx-footer__bottom { justify-content: center; flex-direction: column; }

/* ── footer variant: "dark-premium" ───────────────────────────── */
.sx-footer__wrap.sx-footer--dark-premium {
  background: color-mix(in srgb, var(--sx-color-primary) 88%, #000);
  margin: 0 calc(-1 * var(--sx-container-px, 0px));
  padding: 64px 32px 32px;
}
.sx-footer__wrap.sx-footer--dark-premium .sx-footer__brand h4 { font-size: 28px; letter-spacing: -0.01em; }

/* ── footer variant: "glass" ──────────────────────────────────── */
.sx-footer__wrap.sx-footer--glass {
  background: linear-gradient(135deg, color-mix(in srgb, var(--sx-color-primary) 70%, #000) 0%, color-mix(in srgb, var(--sx-color-primary) 40%, #000) 100%);
  position: relative;
  padding: 48px 0 32px;
}
.sx-footer__wrap.sx-footer--glass .sx-footer__top {
  background: rgba(255,255,255,0.06);
  backdrop-filter: blur(18px) saturate(140%);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
  border: 1px solid rgba(255,255,255,0.14);
  border-radius: 18px;
  padding: 32px 28px;
  margin: 28px 0;
}

/* ── footer variant: "split-large" ────────────────────────────── */
.sx-footer__wrap.sx-footer--split-large .sx-footer__top {
  grid-template-columns: 1fr;
  gap: 40px;
}
@media (min-width: 820px) {
  .sx-footer__wrap.sx-footer--split-large .sx-footer__top {
    grid-template-columns: 1.6fr 1fr;
    gap: 64px;
  }
  .sx-footer__wrap.sx-footer--split-large .sx-footer__top > div:nth-child(2),
  .sx-footer__wrap.sx-footer--split-large .sx-footer__top > div:nth-child(3) {
    grid-column: 2;
  }
  .sx-footer__wrap.sx-footer--split-large .sx-footer__top > div:nth-child(3) { margin-top: 24px; }
}
.sx-footer__wrap.sx-footer--split-large .sx-footer__brand h4 {
  font-size: 32px;
  line-height: 1.1;
}
.sx-footer__wrap.sx-footer--split-large .sx-footer__brand p {
  font-size: 16px;
  max-width: 42ch;
  line-height: 1.6;
}

/* ── footer variant: "luxury-brand" ───────────────────────────── */
.sx-footer__wrap.sx-footer--luxury-brand {
  padding: 96px 0 48px;
  background: color-mix(in srgb, var(--sx-color-ink) 95%, #000);
}
.sx-footer__wrap.sx-footer--luxury-brand .sx-footer__top {
  grid-template-columns: 1fr;
  gap: 48px;
  text-align: center;
}
.sx-footer__wrap.sx-footer--luxury-brand .sx-footer__brand h4 {
  font-family: var(--sx-font-display);
  font-weight: 400;
  font-size: 36px;
  letter-spacing: -0.01em;
}
.sx-footer__wrap.sx-footer--luxury-brand h5 {
  font-family: var(--sx-font-display);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.32em;
  font-size: 10px;
}
.sx-footer__wrap.sx-footer--luxury-brand ul {
  flex-direction: row;
  justify-content: center;
  gap: 24px;
  flex-wrap: wrap;
}
.sx-footer__wrap.sx-footer--luxury-brand .sx-footer__socials { justify-content: center; }
.sx-footer__wrap.sx-footer--luxury-brand a { letter-spacing: 0.05em; font-style: italic; }

/* ── footer variant: "social-focus" ───────────────────────────── */
.sx-footer__wrap.sx-footer--social-focus .sx-footer__top {
  grid-template-columns: 1fr;
  text-align: center;
  gap: 36px;
}
.sx-footer__wrap.sx-footer--social-focus .sx-footer__socials {
  justify-content: center;
  gap: 18px;
}
.sx-footer__wrap.sx-footer--social-focus .sx-footer__socials a {
  width: 56px;
  height: 56px;
  background: rgba(255,255,255,0.06);
  border: 1px solid rgba(255,255,255,0.16);
}
.sx-footer__wrap.sx-footer--social-focus .sx-footer__socials a:hover {
  background: var(--sx-color-primary-fill, var(--sx-color-primary));
  color: var(--sx-color-on-primary, #fff);
  transform: translateY(-3px);
  box-shadow: 0 12px 28px color-mix(in srgb, var(--sx-color-primary) 50%, transparent);
}
.sx-footer__wrap.sx-footer--social-focus .sx-footer__socials svg { width: 22px; height: 22px; }
.sx-footer__wrap.sx-footer--social-focus h5 { display: none; }
.sx-footer__wrap.sx-footer--social-focus ul {
  flex-direction: row;
  justify-content: center;
  gap: 24px;
  flex-wrap: wrap;
}

/* ── footer variant: "inline-row" ─────────────────────────────── */
.sx-footer__wrap.sx-footer--inline-row .sx-footer__top {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  margin-bottom: 20px;
  border-bottom: 1px solid rgba(255,255,255,0.08);
  padding-bottom: 20px;
}
.sx-footer__wrap.sx-footer--inline-row .sx-footer__top > div { display: contents; }
.sx-footer__wrap.sx-footer--inline-row .sx-footer__brand { display: flex !important; align-items: center; gap: 16px; }
.sx-footer__wrap.sx-footer--inline-row .sx-footer__brand h4 { margin: 0; font-size: 16px; }
.sx-footer__wrap.sx-footer--inline-row .sx-footer__brand p { display: none; }
.sx-footer__wrap.sx-footer--inline-row h5 { display: none; }
.sx-footer__wrap.sx-footer--inline-row ul {
  flex-direction: row;
  gap: 22px;
  flex-wrap: wrap;
}
.sx-footer__wrap.sx-footer--inline-row .sx-footer__socials { gap: 10px; }
.sx-footer__wrap.sx-footer--inline-row .sx-footer__socials a { width: 32px; height: 32px; }

/* ── footer variant: "bento" ──────────────────────────────────── */
.sx-footer__wrap.sx-footer--bento .sx-footer__top {
  grid-template-columns: 1fr;
  gap: 12px;
}
@media (min-width: 720px) {
  .sx-footer__wrap.sx-footer--bento .sx-footer__top {
    grid-template-columns: 2fr 1fr 1fr;
    grid-auto-rows: minmax(140px, auto);
  }
}
.sx-footer__wrap.sx-footer--bento .sx-footer__top > div {
  background: rgba(255,255,255,0.04);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 14px;
  padding: 24px;
}
.sx-footer__wrap.sx-footer--bento .sx-footer__brand h4 { font-size: 26px; }

/* ── footer variant: "wave" ───────────────────────────────────── */
.sx-footer__wrap.sx-footer--wave {
  position: relative;
  padding-top: 100px;
}
.sx-footer__wrap.sx-footer--wave::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 80px;
  background-color: var(--sx-color-ink);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 80' preserveAspectRatio='none'%3E%3Cpath d='M0,40 C360,80 1080,0 1440,40 L1440,80 L0,80 Z' fill='%23000'/%3E%3C/svg%3E") no-repeat center / 100% 100%;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 80' preserveAspectRatio='none'%3E%3Cpath d='M0,40 C360,80 1080,0 1440,40 L1440,80 L0,80 Z' fill='%23000'/%3E%3C/svg%3E") no-repeat center / 100% 100%;
  transform: translateY(-100%);
  pointer-events: none;
}

/* ── footer variant: "floating-card" ──────────────────────────── */
.sx-footer__wrap.sx-footer--floating-card {
  background: transparent;
}
.sx-footer__wrap.sx-footer--floating-card .sx-container {
  background: color-mix(in srgb, var(--sx-color-primary) 90%, #000);
  border-radius: 22px;
  padding: 48px 40px;
  margin: 0 16px;
  max-width: calc(100% - 32px);
  box-shadow: 0 24px 56px rgba(0,0,0,0.18);
}
@media (max-width: 720px) {
  .sx-footer__wrap.sx-footer--floating-card .sx-container { padding: 36px 24px; }
}

/* ── Template preview mode ────────────────────────────────────────
 * Applied as `body.sx-preview-mode` by runtime.js when the runtime
 * config has `is_template_preview: true`. This kicks in for the
 * marketplace previews served from templates.salesio.app/<key>/ —
 * where the page is a *demo*, not a real customer shop.
 *
 * We belt-and-suspenders both: runtime.js skips handler attachment
 * AND css hides the controls so even a renderer overriding the JS
 * still ends up with no clickable cart UI. Customer sites
 * (cliente.salesio.app) don't get this class, so they keep full
 * interactivity.
 */
body.sx-preview-mode [data-sx-cart-open],
body.sx-preview-mode .sx-cart-drawer {
  display: none !important;
}
body.sx-preview-mode [data-sx-add-to-cart] {
  pointer-events: none;
  opacity: 0.55;
  cursor: not-allowed;
}


/* ── Image lightbox (universal, opt-in via R.gallery wrapper) ──── */
.sx-gallery__trigger {
  appearance: none;
  background: transparent;
  border: 0;
  padding: 0;
  margin: 0;
  cursor: pointer;
  display: block;
  width: 100%;
  height: 100%;
  border-radius: inherit;
  overflow: hidden;
}
.sx-gallery__trigger:focus-visible {
  outline: 3px solid var(--sx-color-accent);
  outline-offset: 2px;
}
.sx-gallery__grid--zoom .sx-gallery__img {
  transition: transform 0.5s cubic-bezier(0.2, 0.8, 0.2, 1), filter 0.4s ease;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.sx-gallery__grid--zoom .sx-gallery__trigger:hover .sx-gallery__img {
  transform: scale(1.06);
  filter: saturate(1.08);
}
.sx-gallery__grid--zoom .sx-gallery__trigger::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, color-mix(in srgb, var(--sx-color-ink) 35%, transparent), transparent 45%);
  opacity: 0;
  transition: opacity 0.3s ease;
  pointer-events: none;
}
.sx-gallery__grid--zoom .sx-gallery__item { position: relative; overflow: hidden; border-radius: var(--sx-radius-md); }
.sx-gallery__grid--zoom .sx-gallery__trigger:hover::after { opacity: 1; }

.sx-lightbox {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  animation: sxLightboxIn 0.22s ease-out;
}
@keyframes sxLightboxIn {
  from { opacity: 0; transform: scale(0.985); }
  to   { opacity: 1; transform: scale(1); }
}
.sx-lightbox__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(10, 10, 14, 0.92);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}
.sx-lightbox__close,
.sx-lightbox__nav {
  position: absolute;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border: 0;
  border-radius: var(--sx-radius-pill);
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
  font-size: 28px;
  line-height: 1;
  cursor: pointer;
  transition: background 0.2s ease, transform 0.15s ease;
}
.sx-lightbox__close:hover,
.sx-lightbox__nav:hover {
  background: var(--sx-color-accent-fill, var(--sx-color-accent));
  color: var(--sx-color-on-primary);
}
.sx-lightbox__close:active,
.sx-lightbox__nav:active { transform: scale(0.95); }
.sx-lightbox__close { top: 20px; right: 20px; font-size: 32px; }
.sx-lightbox__nav--prev { left: 20px; top: 50%; transform: translateY(-50%); font-size: 32px; }
.sx-lightbox__nav--next { right: 20px; top: 50%; transform: translateY(-50%); font-size: 32px; }
.sx-lightbox__nav--prev:active { transform: translateY(-50%) scale(0.95); }
.sx-lightbox__nav--next:active { transform: translateY(-50%) scale(0.95); }
.sx-lightbox__nav[hidden] { display: none; }
.sx-lightbox__stage {
  position: relative;
  z-index: 1;
  max-width: 92vw;
  max-height: 88vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
}
.sx-lightbox__figure {
  max-width: 100%;
  max-height: calc(88vh - 60px);
  display: flex;
  align-items: center;
  justify-content: center;
}
.sx-lightbox__figure img {
  max-width: 100%;
  max-height: calc(88vh - 60px);
  width: auto;
  height: auto;
  object-fit: contain;
  border-radius: var(--sx-radius-md);
  box-shadow: 0 24px 80px rgba(0, 0, 0, 0.55);
}
.sx-lightbox__meta {
  display: flex;
  align-items: center;
  gap: 16px;
  color: rgba(255, 255, 255, 0.86);
  font-size: 14px;
  letter-spacing: 0.04em;
}
.sx-lightbox__counter {
  font-variant-numeric: tabular-nums;
  opacity: 0.7;
}
@media (max-width: 720px) {
  .sx-lightbox__close { top: 12px; right: 12px; width: 40px; height: 40px; }
  .sx-lightbox__nav { width: 40px; height: 40px; }
  .sx-lightbox__nav--prev { left: 8px; }
  .sx-lightbox__nav--next { right: 8px; }
}
@media (prefers-reduced-motion: reduce) {
  .sx-lightbox { animation: none; }
  .sx-gallery__grid--zoom .sx-gallery__img { transition: none; }
}

/* ── Tickets / "Próximas fechas" section ────────────────────────── */
.sx-events__heading {
  font-size: clamp(1.6rem, 3vw, 2.4rem);
  font-weight: 800;
  text-align: center;
  margin: 0 0 28px;
}
.sx-events__list {
  display: flex;
  flex-direction: column;
  gap: 12px;
  max-width: 720px;
  margin: 0 auto;
}
.sx-event-card {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 16px 20px;
  border: 1px solid var(--sx-color-line, #e6e6ef);
  border-radius: 14px;
  background: var(--sx-color-surface, #fff);
  --sx-color-ink: var(--sx-color-ink-on-surface);
  --sx-color-ink-soft: var(--sx-color-ink-soft-on-surface, var(--sx-color-ink-on-surface));
  --sx-color-accent-ink: var(--sx-color-accent-ink-on-surface, var(--sx-color-accent-ink));
  --sx-color-primary-ink: var(--sx-color-primary-ink-on-surface, var(--sx-color-primary-ink));
  --sx-color-stars: var(--sx-color-stars-on-surface, var(--sx-color-stars));
  color: var(--sx-color-ink);
}
.sx-event-card__date {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  flex: none;
  min-width: 76px;
  padding: 8px 10px;
  border-radius: 10px;
  background: var(--sx-color-bg-alt, #f5f4fb);
  text-align: center;
  --sx-color-ink: var(--sx-color-ink-on-alt);
  --sx-color-ink-soft: var(--sx-color-ink-soft-on-alt, var(--sx-color-ink-on-alt));
  --sx-color-accent-ink: var(--sx-color-accent-ink-on-alt, var(--sx-color-accent-ink));
  --sx-color-primary-ink: var(--sx-color-primary-ink-on-alt, var(--sx-color-primary-ink));
  --sx-color-stars: var(--sx-color-stars-on-alt, var(--sx-color-stars));
  color: var(--sx-color-ink);
}
.sx-event-card__day { font-weight: 800; font-size: 14px; line-height: 1.2; }
.sx-event-card__time { font-size: 12px; color: var(--sx-color-ink-soft, #6b7280); }
.sx-event-card__body { flex: 1; min-width: 0; }
.sx-event-card__title { font-size: 17px; font-weight: 700; margin: 0 0 2px; }
.sx-event-card__venue { font-size: 13px; color: var(--sx-color-ink-soft, #6b7280); }
.sx-event-card__from { font-size: 13px; font-weight: 600; color: var(--sx-color-primary, #6d28d9); margin-top: 3px; }
.sx-event-card__cta {
  flex: none;
  padding: 10px 18px;
  border-radius: 999px;
  background: var(--sx-color-primary, #6d28d9);
  color: #fff;
  font-weight: 700;
  font-size: 14px;
  text-decoration: none;
  white-space: nowrap;
  transition: opacity .15s ease;
}
.sx-event-card__cta:hover { opacity: .9; }
.sx-event-card__cta.is-out {
  background: var(--sx-color-bg-alt, #ececf3);
  color: var(--sx-color-ink-soft, #9ca3af);
  pointer-events: none;
  --sx-color-ink: var(--sx-color-ink-on-alt);
  --sx-color-ink-soft: var(--sx-color-ink-soft-on-alt, var(--sx-color-ink-on-alt));
  --sx-color-accent-ink: var(--sx-color-accent-ink-on-alt, var(--sx-color-accent-ink));
  --sx-color-primary-ink: var(--sx-color-primary-ink-on-alt, var(--sx-color-primary-ink));
  --sx-color-stars: var(--sx-color-stars-on-alt, var(--sx-color-stars));
  color: var(--sx-color-ink);
}
@media (max-width: 560px) {
  .sx-event-card { flex-wrap: wrap; }
  .sx-event-card__cta { width: 100%; text-align: center; }
}

/* ── Header nav overflow ───────────────────────────────────────────
   Six links show inline; the rest fold into this dropdown. Label
   lengths vary wildly between templates ("Home" vs "Thinking about
   selling"), so the row is capped by COUNT and the panel absorbs the
   difference — rather than letting long labels slide under the language
   toggle and the CTA, which is what happened before. */
.sx-nav-more { position: relative; display: inline-block; }
.sx-nav-more__btn {
  display: inline-flex; align-items: center; gap: .35em;
  background: none; border: 0; padding: 0; margin: 0;
  font: inherit; color: inherit; cursor: pointer; white-space: nowrap;
}
.sx-nav-more__btn svg { transition: transform .18s ease; }
.sx-nav-more.is-open .sx-nav-more__btn svg { transform: rotate(180deg); }
.sx-nav-more__panel {
  position: absolute; top: calc(100% + .6rem); right: 0; z-index: 60;
  min-width: 13rem; padding: .45rem;
  display: none; flex-direction: column;
  background: var(--sx-color-surface, #fff);
  border: 1px solid var(--sx-color-border, rgba(0,0,0,.12));
  border-radius: 12px; box-shadow: 0 12px 32px rgba(0,0,0,.14);
}
.sx-nav-more.is-open .sx-nav-more__panel { display: flex; }
.sx-nav-more__panel a {
  display: block; padding: .55rem .7rem; border-radius: 8px;
  color: var(--sx-color-ink, #1a1a1a); text-decoration: none; white-space: nowrap;
}
.sx-nav-more__panel a:hover,
.sx-nav-more__panel a:focus-visible { background: var(--sx-color-bg-alt, rgba(0,0,0,.05)); }
/* The drawer already scrolls and shows every link, so the dropdown has
   no job there. */
@media (max-width: 1023px) { .sx-nav-more { display: none; } }
