/**
 * Event-microsite frame & body-pattern presets.
 *
 * Served from the wactivity public dir; linked by the event renderer.
 * Every visual parameter is a CSS custom property with a sensible default,
 * so a microsite's theme JSON can override any knob without editing this
 * file or the renderer.
 *
 * Token contract (consumed by selectors below, emitted by event-renderer.ts):
 *
 *   Palette (from theme.palette)
 *     --brand, --brand-dark, --brand-light
 *     --accent, --accent-light
 *     --surface, --surface-alt
 *     --ink, --ink-muted
 *     --body-bg
 *
 *   Typography (from theme.typography — font stacks, not URLs)
 *     --font-display, --font-heading, --font-body, --font-accent
 *
 *   Radius / shadow scales
 *     --radius, --shadow
 *
 *   Frame geometry (from theme.frameConfig — all optional)
 *     --frame-max-width       (default: 920px)
 *     --frame-top-margin      (default: 75px)
 *     --frame-padding-block   (default: 40px)
 *     --frame-padding-inline  (default: 32px)
 *     --frame-inset           (default: 20px)   double-border inset
 *     --frame-inset-inner     (default: 4px)    inner of the double
 *     --frame-border-color    (default: var(--accent))
 *     --frame-border-outer-opacity  (default: 0.4)
 *     --frame-border-inner-opacity  (default: 0.2)
 *     --frame-border-shadow-rgb     (default: 74,20,25)  stacked shadow tint
 *
 *   Section defaults (consumed by block CSS inside the frame)
 *     --section-padding-block   (default: 4rem)
 *     --section-max-inner-width (default: 850px)
 *
 * Block-level CSS (headings, descriptions, buttons) reads the vars above;
 * none of the block styles live in this file. This file only defines what
 * "frame X" and "pattern Y" mean.
 *
 * Changing a frame preset here updates every microsite using it on the next
 * page load — cache headers below make the impact predictable.
 */

/* ---------- Baseline inside the frame ---------- */

.pb-themed {
  color: var(--ink, #1a1a1a);
  background: var(--surface, transparent);
  font-family: var(--font-body, Georgia, serif);
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  /* Generous bottom padding so the cream/page bg keeps going AFTER the
     paper's margin-bottom and BEFORE the shell footer (.wac-footer)
     starts. Without this the cream ends abruptly and the shell's
     burgundy footer-bg meets the paper-edge with no transition. */
  padding-bottom: clamp(60px, 8vh, 140px);
  /* Defence-in-depth against iOS-Safari sideways drift: if any
     descendant (full-bleed band, hero with letter-spacing, a stray
     100vw element) tries to push the layout past the frame, clip it
     here too. The shell already clips at <html>/<body>, but this
     scopes the same protection to event content rendered without
     the shell (preview iframes, the member-gate fallback chrome). */
  overflow-x: clip;
  /* Always cover the viewport so the page-as-paper bg meets the bottom
     of the screen — without this, when the content is short the body's
     burgundy/dark bg shows through under the paper and breaks the
     "page on a desk" metaphor. dvh handles iOS Safari URL bar resize. */
  min-height: 100vh;
  min-height: 100dvh;
}

.pb-themed .pb-page {
  /* Undo the generic .pb-page defaults — we want the frame to drive size
     and padding, not the page-builder generic wrapper. */
  background: transparent;
  color: inherit;
  font-family: inherit;
  padding: 0;
  max-width: none;
}

.pb-themed h2,
.pb-themed h3 {
  font-family: var(--font-heading, Georgia, serif);
  color: var(--brand-dark, var(--brand, inherit));
  line-height: 1.3;
}

/* H1 inside an event frame is hero-level display (couple names, event title).
   Uses --hero-font with a sensible fallback chain so a theme without a
   display font still looks correct. Microsites that prefer H1 = regular
   heading can set `--hero-font: var(--font-heading)` in theme.frameConfig. */
.pb-themed h1,
.pb-themed .pb-heading-display {
  font-family: var(--hero-font, var(--font-display, var(--font-heading, Georgia, serif)));
  /* Display-sized by default so H1 actually reads as a hero title — without
     this, a stand-alone heading block on a CMS page (no cover above) falls
     back to the browser's `2em`, which looks tiny next to the body type.
     Themes can dial via `--hero-size` per event. */
  font-size: var(--hero-size, clamp(2.4rem, 5.5vw, 3.8rem));
  color: var(--brand-dark, var(--brand, inherit));
  line-height: 1.15;
  font-weight: 400;
}

.pb-themed .pb-heading {
  font-family: var(--font-heading, Georgia, serif);
  color: var(--brand-dark, var(--brand, inherit));
}
/* H1-tagged .pb-heading gets the display treatment explicitly (the heading
   block renders `<h1 class="pb-heading">…</h1>` — the element selector above
   applies, but we repeat it here for specificity when custom CSS tries to
   override). */
.pb-themed h1.pb-heading {
  font-family: var(--hero-font, var(--font-display, var(--font-heading, Georgia, serif)));
}

/* Business pages (spaces / venues / catalogs CMS) use `pb-themed pb-page`
 * wrapper. They are NOT event microsites — the operator wants a sober H1,
 * not a wedding-style hero. Theme can still override via `--hero-size`. */
.pb-themed.pb-page h1,
.pb-themed.pb-page h1.pb-heading {
  font-size: var(--hero-size, clamp(1.75rem, 3vw, 2.5rem));
}

/* Anchor styling policy (per Pedro 2026-05-07): anchors inside a themed
 * page inherit the surrounding text color, never look like a separate
 * "link blue" or theme color by default. Specificity uses :link/:visited
 * to defeat the UA stylesheet without bumping !important.
 *
 * Hint affordances are reserved for *inline* anchors inside body text
 * (description / text / html blocks): subtle underline + a brand-tinted
 * hover. Structural anchors (cards, gallery tiles, nav chrome) get
 * neither — their container shape already communicates clickability. */
.pb-themed a:link,
.pb-themed a:visited {
  color: inherit;
  text-decoration: none;
}

/* Inline anchors in body text: underline as the *only* default cue;
 * hover/focus tints to the theme accent for a richer affordance. */
.pb-themed .pb-description a,
.pb-themed .pb-text a,
.pb-themed .pb-html a {
  text-decoration: underline;
  text-underline-offset: 0.2em;
  text-decoration-thickness: 1px;
}
.pb-themed .pb-description a:hover,
.pb-themed .pb-text a:hover,
.pb-themed .pb-html a:hover,
.pb-themed .pb-description a:focus-visible,
.pb-themed .pb-text a:focus-visible,
.pb-themed .pb-html a:focus-visible {
  color: var(--link-hover-color, var(--brand-dark, var(--brand, var(--primary-color, currentColor))));
  text-decoration-thickness: 2px;
}

.pb-themed .pb-description {
  color: var(--ink, inherit);
  line-height: 1.9;
  /* Sensible reading width for un-variant descriptions — keeps the
     line length comfortable on wide papers instead of stretching
     edge-to-edge. Each variant below overrides via its own
     `--description-max-width`; this is the universal default. */
  max-width: var(--description-max-width, 720px);
  margin: var(--description-margin, 1rem auto);
  text-align: var(--description-align, center);
}

/* Story variant — marcoysonia long-form narrative look.
   Every value is a CSS var so individual events can dial it in via
   `description.settings.style.<key>` (the block emits --description-<key>). */
.pb-themed .pb-description--story {
  font-family: var(--description-family, var(--font-heading, Georgia, serif));
  /* Was 1.35rem — too dominant against the body type at standard
     reading widths; the story variant should still read as prose, not
     as a pull-quote. Slight bump over body (1rem) is enough to
     register the "narrative" intent. Per-event override stays available
     via `description.settings.style.size`. */
  font-size: var(--description-size, 1.1rem);
  /* Default `normal` — italics on long narrative bodies hurt readability
     and confused operators (the rich-editor's italic toggle wasn't doing
     anything because the variant style was forcing it on). Themes that
     actually want italic can set `--description-italic: italic` per
     event. */
  font-style: var(--description-italic, normal);
  font-weight: var(--description-weight, 300);
  line-height: var(--description-line-height, 2.2);
  text-align: var(--description-align, center);
  max-width: var(--description-max-width, 700px);
  /* Top margin = 0 by default. The story variant almost always sits
     under a section-header (which already contributes 2rem of
     bottom-margin), so 2rem here stacked against that read as a
     ~64px void between the heading and the prose. Bottom margin
     stays generous so the next section breathes. Per-event override
     still available via `description.settings.style.margin`. */
  margin: var(--description-margin, 0 auto 2rem);
  color: var(--ink, inherit);
}
.pb-themed .pb-description--story p {
  margin: 0 0 var(--description-paragraph-gap, 2rem);
}
.pb-themed .pb-description--story p:last-child {
  margin-bottom: 0;
}

/* Tip variant — short centered heads-up with a brand-colored left border.
   Visual cousin of quote but with semantic intent "call attention, short".
   All values variable so themes can swap colors/borders without forking. */
.pb-themed .pb-description--tip {
  font-style: var(--description-italic, normal);
  font-size: var(--description-size, 0.85rem);
  line-height: var(--description-line-height, 1.8);
  color: var(--description-color, var(--ink-muted, var(--ink, inherit)));
  border-left: var(--description-tip-border, 2px solid var(--brand, currentColor));
  padding: var(--description-tip-padding, 0.5rem 0 0.5rem 1rem);
  margin: var(--description-margin, 1.25rem auto);
  max-width: var(--description-max-width, 620px);
  text-align: var(--description-align, center);
}
.pb-themed .pb-description--tip p {
  margin: 0 0 0.5rem;
}
.pb-themed .pb-description--tip p:last-child { margin-bottom: 0; }
.pb-themed .pb-description--tip strong {
  font-style: normal;
  color: var(--description-tip-label-color, var(--brand, inherit));
  text-transform: var(--description-tip-label-transform, none);
  font-size: var(--description-tip-label-size, 1em);
}

/* Quote variant — a short highlighted note. Border-left accent in gold,
   italic body, muted color — typical sidenote usage ("see timetables…"). */
.pb-themed .pb-description--quote {
  font-style: var(--description-italic, normal);
  font-size: var(--description-size, 0.9rem);
  line-height: var(--description-line-height, 1.9);
  color: var(--description-color, var(--ink-muted, var(--ink, inherit)));
  border-left: var(--description-quote-border, 2px solid var(--accent, currentColor));
  padding: var(--description-quote-padding, 0.5rem 0 0.5rem 1rem);
  /* auto side-margins center the quote box inside a centered section; the
     text INSIDE remains left-aligned so the border-left feels natural. */
  margin: var(--description-margin, 1rem auto);
  max-width: var(--description-max-width, 600px);
  text-align: var(--description-align, left);
}
.pb-themed .pb-description--quote p {
  margin: 0 0 0.6rem;
}
.pb-themed .pb-description--quote p:last-child { margin-bottom: 0; }

/* Lead variant — short prose under a section header. Defaults match the
   legacy "section intro" pattern: body font (Lora), small (~17px),
   italic, weight 300, muted color, generous line-height — readable but
   visually subordinate to the heading above. Heavier "callout intros"
   (the bigger Playfair text in iban / whatsapp blocks) are NOT this
   variant; they live as block-specific tokens (--iban-intro-*, etc.). */
.pb-themed .pb-description--lead {
  font-family: var(--description-family, var(--font-body, Georgia, serif));
  font-size: var(--description-size, 1.05rem);
  font-style: var(--description-italic, normal);
  font-weight: var(--description-weight, 300);
  line-height: var(--description-line-height, 1.7);
  text-align: var(--description-align, center);
  max-width: var(--description-max-width, 650px);
  margin: var(--description-margin, 1.5rem auto);
  color: var(--description-color, var(--ink-muted, var(--ink, inherit)));
}

/* ---------- Frame: none ---------- */
/* No visible frame — content flows at full width of the shell content area. */

.pb-themed-frame-none {
  width: 100%;
}

/* ---------- Frame: minimal ---------- */
/* Centered column, no decorative borders. Good for modern / corporate. */

.pb-themed-frame-minimal {
  max-width: var(--frame-max-width, 920px);
  margin: var(--frame-top-margin, 0) auto;
  padding: var(--frame-padding-block, 3rem) var(--frame-padding-inline, 2rem);
  background: var(--surface, transparent);
  border-radius: var(--radius, 0);
  box-shadow: var(--shadow, none);
}

/* ---------- Frame: paper ---------- */
/* Centered card with double gold-line border + stacked shadow.
   All geometry driven by CSS vars — the ":paper" preset just picks the
   defaults that make this look "invitation-like". */

.pb-themed-frame-paper {
  position: relative;
  max-width: var(--frame-max-width, 920px);
  /* Same trick as restaurapro's .rp-menu: ensure the paper always
     covers at least the viewport so the last block has cream/page bg
     beneath it, simulating a full sheet of paper. Without this, when
     the content is short, the body's burgundy/dark bg shows under the
     paper edge and breaks the metaphor. */
  min-height: 100vh;
  min-height: 100dvh;
  /* Top margin = reserved nav slot + any extra gap the theme wants.
     Default gap preserves Phase-1 look when no nav is configured.
     When a nav does exist (Phase 2), set --frame-top-margin: 0 in the theme
     and the paper will sit flush below the fixed nav.
     Bottom margin matches frame-top-margin so the paper "floats" with
     symmetric breathing room above/below — the page-as-paper metaphor
     reads as a finished sheet, not a slab cut at the bottom. Override
     via --frame-bottom-margin in the theme if needed. */
  margin: calc(var(--shell-nav-height, 0px) + var(--frame-top-margin, 0px)) auto
          var(--frame-bottom-margin, var(--frame-top-margin, 75px));
  /* Paper padding: top is the configured frame-padding-block; bottom is
     intentionally generous so the last block has substantial breathing
     room before the paper edge — same "tail of the page" feel that
     restaurapro's .rp-menu has via its 100vh min-height + small bottom
     padding. Reads as "page closing gracefully", not "content cut off". */
  padding: var(--frame-padding-block, 40px)
           var(--frame-padding-inline, 32px)
           clamp(120px, 18vh, 280px);
  background-color: var(--surface, #F8F4ED);
  /* Three concentric rings around the paper — each independently tintable
     so a theme can go subtle (marcoysonia default) or bold. `--frame-border-*`
     tokens drive the ::before/::after inset borders (see below); these ring
     tokens drive the stacked box-shadow, which is a separate visual system. */
  box-shadow:
    0 0 0 1px var(--frame-shadow-outer-ring-color, rgba(196,162,101,0.3)),
    0 0 0 6px rgba(var(--frame-border-shadow-rgb, 74,20,25), var(--frame-shadow-mid-ring-alpha, 0.15)),
    0 0 0 7px var(--frame-shadow-inner-ring-color, rgba(196,162,101,0.2)),
    var(--shadow, 0 25px 80px rgba(0,0,0,0.5));
}

/* Double inner border (the "gold frame"). Purely decorative. */
.pb-themed-frame-paper::before {
  content: '';
  position: absolute;
  inset: var(--frame-inset, 20px);
  border: 1px solid var(--frame-border-color, var(--accent, currentColor));
  opacity: var(--frame-border-outer-opacity, 0.4);
  pointer-events: none;
}
.pb-themed-frame-paper::after {
  content: '';
  position: absolute;
  inset: calc(var(--frame-inset, 20px) + var(--frame-inset-inner, 4px));
  border: 1px solid var(--frame-border-color, var(--accent, currentColor));
  opacity: var(--frame-border-inner-opacity, 0.2);
  pointer-events: none;
}

/* Mobile: when the viewport is at or below the paper's max-width, the
   "floating sheet" metaphor breaks down — the paper already spans 100%
   of the screen, so the vertical breathing room above/below stops
   reading as elegant separation and just looks like an awkward gap
   between the cream paper and the burgundy bands. Collapse the outer
   margins so the paper meets the surrounding bands flush. The gold
   inset frame (::before/::after) and the ring-shadow stay — that's
   the actual decoration of the card, not the spacing around it. */
@media (max-width: 920px) {
  .pb-themed-frame-paper {
    margin-top: 0;
    margin-bottom: 0;
  }
  /* Same logic as the side-margin: at full-bleed widths the cream
     "tail" between the paper edge and the next surrounding band stops
     reading as elegant negative space — it just looks like a gap.
     Override the desktop default (clamp 60-140px) to 0. Themes can
     reintroduce via --themed-mobile-padding-bottom if needed. */
  .pb-themed {
    padding-bottom: var(--themed-mobile-padding-bottom, 0);
  }
}

/* ---------- Frame: edge-to-edge ---------- */
/* Full-viewport width, no side padding. For immersive photo-first sites. */

.pb-themed-frame-edge-to-edge {
  width: 100%;
  max-width: none;
  margin: 0;
  padding: 0;
  background: var(--surface, transparent);
}

/* ---------- Body patterns ---------- */
/* Applied to .pb-themed; stacks on top of --surface. */

.pb-themed-pattern-none {
  /* no-op */
}

.pb-themed-pattern-subtle-noise {
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.75' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='300' height='300' filter='url(%23n)' opacity='0.035'/%3E%3C/svg%3E"),
    linear-gradient(180deg, rgba(255,255,255,0.4) 0%, transparent 8%, transparent 92%, rgba(0,0,0,0.02) 100%);
}

.pb-themed-pattern-paper-grain {
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.2' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23g)' opacity='0.08'/%3E%3C/svg%3E");
}

/* `pb-themed-hero` removed 2026-04-30 — subsumed by `.pb-cover-with-text`
   at the bottom of this file. The `--pb-themed-hero-offset` variable is
   no longer used by anything but kept here as a token in case other
   blocks want to reference how-much-room-the-frame-takes. */
.pb-themed {
  --pb-themed-hero-offset:
    calc(var(--shell-nav-height, 0px)
         + var(--frame-top-margin, 75px)
         + 2 * var(--frame-padding-block, 40px));
}

/* ---------- Heading variants (sub-section titles) ----------
   Styled here so the heading block stays generic. Vars let themes tweak
   sizes/colors per-microsite. */

.pb-themed .pb-heading--minor-title {
  font-family: var(--heading-family, var(--font-heading, Georgia, serif));
  font-size: var(--heading-size, 1.6rem);
  font-weight: var(--heading-weight, 400);
  color: var(--heading-color, var(--brand-dark, var(--brand, inherit)));
  text-align: var(--heading-align, center);
  margin: var(--heading-margin, 3rem 0 0);
  line-height: var(--heading-line-height, 1.3);
}

.pb-themed .pb-heading--minor-subtitle {
  font-family: var(--heading-family, var(--font-heading, Georgia, serif));
  font-size: var(--heading-size, 1.1rem);
  /* Italic only when explicitly opted-in via the rich editor — variants
     no longer force a font-style. Per-event override still possible
     with `--heading-italic: italic`. */
  font-style: var(--heading-italic, normal);
  font-weight: var(--heading-weight, 400);
  color: var(--heading-color, var(--brand, inherit));
  text-align: var(--heading-align, center);
  letter-spacing: var(--heading-tracking, 0.05em);
  margin: var(--heading-margin, 2rem 0 0.8rem);
  line-height: var(--heading-line-height, 1.4);
}

/* ---------- Icon list (directions-style rows) ----------
   A <ul> where each <li> is icon + uppercase label + description, either
   inline (one row) or stacked (icon above text). Lives inside the venue
   "Cómo llegar" section in marcoysonia; reusable for feature lists etc. */

.pb-themed .pb-icon-list {
  list-style: none;
  padding: 0;
  margin: 0.8rem auto 0;
  max-width: var(--icon-list-max-width, 600px);
  display: flex;
  flex-direction: column;
  gap: var(--icon-list-row-gap, 0.6rem);
  font-size: var(--icon-list-body-size, 0.9rem);
  line-height: var(--icon-list-line-height, 1.9);
  color: var(--icon-list-body-color, var(--ink-muted, var(--ink, inherit)));
  text-align: left;
}

.pb-themed .pb-icon-list-row {
  display: flex;
  align-items: flex-start;
  gap: 0.35rem;
}

.pb-themed .pb-icon-list-inline .pb-icon-list-icon {
  flex-shrink: 0;
  width: var(--icon-list-icon-size, 1rem);
  height: var(--icon-list-icon-size, 1rem);
  color: var(--icon-list-icon-color, var(--brand-dark, var(--brand, currentColor)));
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-top: 0.25rem;   /* visual baseline alignment with the label */
}
.pb-themed .pb-icon-list-inline .pb-icon-list-icon svg,
.pb-themed .pb-icon-list-inline .pb-icon-list-icon img {
  width: 100%;
  height: 100%;
}

.pb-themed .pb-icon-list-text {
  flex: 1;
}
.pb-themed .pb-icon-list-label {
  text-transform: uppercase;
  letter-spacing: var(--icon-list-label-tracking, 0.1em);
  font-weight: 600;
  color: var(--icon-list-label-color, var(--brand-dark, var(--brand, inherit)));
  font-size: var(--icon-list-label-size, 0.8em);
  margin-right: 0.2rem;
}
.pb-themed .pb-icon-list-sep {
  margin: 0 0.2rem;
  color: var(--icon-list-body-color, var(--ink-muted, inherit));
}

/* Stacked variant — icon above the text, useful for feature grids. */
.pb-themed .pb-icon-list-stacked {
  text-align: center;
}
.pb-themed .pb-icon-list-stacked .pb-icon-list-row {
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
}
.pb-themed .pb-icon-list-stacked .pb-icon-list-icon {
  width: var(--icon-list-icon-size-stacked, 2.5rem);
  height: var(--icon-list-icon-size-stacked, 2.5rem);
  color: var(--icon-list-icon-color, var(--brand-dark, var(--brand, currentColor)));
}

/* ---------- Section bands ----------
   Emitted by the event-renderer when a section-header declares data-band=...
   The band spreads to the paper's inner borders by cancelling the frame's
   inline padding — same trick as the countdown 'container' bleed.
   The band has NO background of its own — the visual fondo is driven
   entirely by `block.settings.box.bg` per-block. Padding kept so the
   block chromes inside breathe the same way they did before. */
.pb-themed .pb-themed-band {
  margin-left: calc(-1 * var(--frame-padding-inline, 32px));
  margin-right: calc(-1 * var(--frame-padding-inline, 32px));
  padding: var(--band-padding-block, 1.25rem) var(--frame-padding-inline, 32px);
}

/* ---------- Block anchors ----------
   Invisible inline spans emitted by renderPage() so `#<block-id>` links
   jump to the right section. `scroll-margin-top` accounts for the (future)
   shell nav + a bit of breathing room. */
.pb-themed .pb-block-anchor {
  display: block;
  height: 0;
  width: 0;
  overflow: hidden;
  scroll-margin-top: calc(var(--shell-nav-height, 0px) + var(--anchor-scroll-margin, 1.5rem));
}

/* ---------- Section header (label + title + divider) ---------- */

.pb-themed .pb-section-header {
  /* Was `4rem 0 2rem` — the band/box wrappers and adjacent blocks
     already provide vertical rhythm. Per-event override via
     `--section-header-margin`. */
  margin: var(--section-header-margin, 0);
  text-align: center;
}
.pb-themed .pb-section-label {
  font-size: 0.65rem;
  letter-spacing: 0.35em;
  text-transform: uppercase;
  color: var(--brand, currentColor);
  font-weight: 600;
  margin-bottom: 1.25rem;
}
.pb-themed .pb-section-title {
  font-family: var(--font-heading, Georgia, serif);
  /* Raised to 56px at the top of the clamp range so H2s at 1440px match
     legacy marcoysonia (2.2rem → 3.5rem). Small viewports still scale down. */
  font-size: var(--section-title-size, clamp(2.2rem, 5vw, 3.5rem));
  font-weight: var(--section-title-weight, 400);
  margin: 0;
  color: var(--brand-dark, var(--brand, inherit));
  line-height: var(--section-title-line-height, 1.3);
}
.pb-themed .pb-section-divider {
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 2rem auto 0;
  gap: 1rem;
  max-width: 180px;
}
.pb-themed .pb-section-divider-line {
  flex: 1;
  height: 1px;
  background: var(--accent, currentColor);
  max-width: 60px;
}
.pb-themed .pb-section-divider-dot {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--accent, currentColor);
  opacity: 0.7;
}

/* ---------- Event schedule (icon + time + title + desc grid) ---------- */

.pb-themed .pb-schedule {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 1rem;
  margin: 2rem 0;
}
.pb-themed .pb-schedule-cols-2 { grid-template-columns: repeat(2, 1fr); }
.pb-themed .pb-schedule-cols-3 { grid-template-columns: repeat(3, 1fr); }
.pb-themed .pb-schedule-cols-4 { grid-template-columns: repeat(4, 1fr); }

.pb-themed .pb-schedule-card {
  text-align: center;
  padding: 1.5rem 1rem;
  background: transparent;
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.pb-themed .pb-schedule-card:hover {
  transform: translateY(-4px);
}
.pb-themed .pb-schedule-icon {
  height: 60px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 1.25rem;
  color: var(--brand-dark, var(--brand, currentColor));
}
.pb-themed .pb-schedule-icon svg,
.pb-themed .pb-schedule-icon img {
  /* Default 56px (matches legacy marcoysonia PNG height). SVG lucide icons
     typically come 44px — a theme can override both by setting
     `--event-schedule-icon-size` in theme.frameConfig extras or in a future
     event-schedule-specific style token. */
  width: auto;
  height: var(--event-schedule-icon-size, 56px);
  max-width: 100%;
  object-fit: contain;
}
.pb-themed .pb-schedule-icon img {
  display: block;
}
.pb-themed .pb-schedule-title {
  font-family: var(--font-heading, Georgia, serif);
  font-size: 1.5rem;
  font-weight: 500;
  margin: 0 0 0.5rem;
  color: var(--brand-dark, var(--brand, inherit));
}
.pb-themed .pb-schedule-time {
  font-family: var(--font-body, inherit);
  font-size: 0.95rem;
  color: var(--ink, inherit);
  letter-spacing: 0.05em;
}
.pb-themed .pb-schedule-desc {
  font-size: 0.9rem;
  color: var(--ink-muted, var(--ink, inherit));
  margin-top: 0.35rem;
}

@media (max-width: 640px) {
  .pb-themed .pb-schedule-cols-4 { grid-template-columns: repeat(2, 1fr); }
  .pb-themed .pb-schedule-cols-3 { grid-template-columns: repeat(2, 1fr); }
}

/* ---------- Dress code palette ---------- */

.pb-themed .pb-dress-code {
  max-width: 720px;
  margin: 2rem auto;
  text-align: center;
}
.pb-themed .pb-dress-intro {
  color: var(--ink-muted, var(--ink, inherit));
  line-height: 1.8;
  margin-bottom: 1.5rem;
}
.pb-themed .pb-dress-columns {
  display: flex;
  flex-wrap: wrap;
  gap: 2rem;
  justify-content: center;
  margin: 1.5rem 0;
}
.pb-themed .pb-dress-column {
  flex: 1;
  min-width: 220px;
  max-width: 320px;
  text-align: center;
}
.pb-themed .pb-dress-column h4 {
  font-family: var(--font-heading, Georgia, serif);
  font-size: 1.25rem;
  font-weight: 500;
  color: var(--brand-dark, var(--brand, inherit));
  margin: 0 0 0.5rem;
}
.pb-themed .pb-dress-column p {
  color: var(--ink-muted, var(--ink, inherit));
  line-height: 1.6;
  margin: 0;
}
.pb-themed .pb-dress-swatches {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  justify-content: center;
  max-width: 700px;
  margin: 1.5rem auto;
}
.pb-themed .pb-dress-swatches-color .pb-dress-swatch {
  /* Cuadrado (palette estándar Pinterest / Coolors). Tamaño grande
     suficiente para que el HEX sea legible sin tener que acercarse,
     pero no tanto que dominen el bloque. Escala ligeramente en mobile
     vía media query abajo. */
  width: 96px;
  height: 96px;
  border-radius: 8px;
  /* `inset` paint the white ring INSIDE the chip — no añade tamaño
     y no toca el color visible. La sombra exterior despega el chip
     del papel. */
  box-shadow:
    inset 0 0 0 2px rgba(255, 255, 255, 0.7),
    0 4px 12px rgba(0, 0, 0, 0.12);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  font-size: 0.7rem;
  letter-spacing: 0.05em;
  /* Color del ink se setea inline desde SSR vía pickInk() para
     contraste WCAG. */
}
.pb-themed .pb-dress-swatch-hex {
  /* Texto en la parte inferior del chip — más estético que
     centrado vertical, recuerda a las paletas de diseño. */
  align-self: flex-end;
  margin-bottom: 0.6rem;
  opacity: 0.92;
  user-select: all;
}
.pb-themed .pb-dress-swatches-color[data-border="0"] .pb-dress-swatch {
  /* Borderless mode: drop both the inner white ring and the outer
     drop shadow so the chips read as flat tiles. */
  box-shadow: none;
}
@media (max-width: 640px) {
  .pb-themed .pb-dress-swatches-color .pb-dress-swatch {
    width: 78px;
    height: 78px;
    font-size: 0.65rem;
  }
  .pb-themed .pb-dress-swatch-hex { margin-bottom: 0.45rem; }
}
.pb-themed .pb-dress-link {
  margin-top: 1.5rem;
  color: var(--ink-muted, var(--ink, inherit));
}
.pb-themed .pb-dress-link a {
  color: var(--brand-dark, var(--brand, inherit));
  text-decoration: underline;
  text-underline-offset: 3px;
  white-space: nowrap;
}

/* Phase B body: rich-text body containing intro paragraphs +
   optional table (the new "Ellas / Ellos" replacement) + inline link.
   Mimics the legacy .pb-dress-column h4 / p typography so migrated
   content reads pixel-equivalent to the structured version. */
.pb-themed .pb-dress-body {
  text-align: center;
  color: var(--ink-muted, var(--ink, inherit));
  line-height: 1.8;
  margin: 0 auto 1.5rem;
}
.pb-themed .pb-dress-body p {
  margin: 0 0 1rem;
  line-height: 1.6;
}
.pb-themed .pb-dress-body table {
  width: 100%;
  border-collapse: collapse;
  /* `table-layout: fixed` reparte el ancho a partes iguales entre
     columnas (50/50 con 2, 33/33/33 con 3, etc.) — sin esto, el
     navegador autosize por contenido y un párrafo largo en una
     columna empuja a las demás a un strip estrecho. */
  table-layout: fixed;
  margin: 1.5rem 0;
}
.pb-themed .pb-dress-body table th {
  font-family: var(--font-heading, Georgia, serif);
  font-size: 1.25rem;
  font-weight: 500;
  color: var(--brand-dark, var(--brand, inherit));
  padding: 0 1rem 0.5rem;
  text-align: center;
  border: 0;
  vertical-align: bottom;
}
.pb-themed .pb-dress-body table td {
  padding: 0 1rem;
  vertical-align: top;
  border: 0;
}
.pb-themed .pb-dress-body table td p {
  color: var(--ink-muted, var(--ink, inherit));
  line-height: 1.6;
  margin: 0;
}
.pb-themed .pb-dress-body a {
  color: var(--brand-dark, var(--brand, inherit));
  text-decoration: underline;
  text-underline-offset: 3px;
}
.pb-themed .pb-dress-hint {
  margin-top: 1.25rem;
  font-size: 0.9rem;
  color: var(--ink-muted, var(--ink, inherit));
  border-left: 2px solid var(--brand, currentColor);
  padding-left: 1rem;
  text-align: left;
  line-height: 1.7;
  max-width: 560px;
  margin-left: auto;
  margin-right: auto;
}

/* ---------- Gallery (grid + masonry) ---------- */

/* Layout-agnostic tile defaults — round corners, soft shadow on hover,
   subtle zoom-out reveal so click affordance is obvious without lightbox.
   The image fills its tile with object-fit:cover for grid mode and
   width:100% for masonry mode (where height is natural). */
.pb-themed .pb-gallery {
  --gallery-gap: 8px;
  --gallery-tile-radius: 6px;
  margin: 1rem 0;
}
.pb-themed .pb-gallery-tile {
  display: block;
  position: relative;
  overflow: hidden;
  border-radius: var(--gallery-tile-radius);
  background: #f3f4f6;
  text-decoration: none;
  outline: none;
  transition: transform 0.25s ease, box-shadow 0.25s ease;
}
.pb-themed .pb-gallery-tile:hover,
.pb-themed .pb-gallery-tile:focus-visible {
  transform: translateY(-1px);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.15);
}
.pb-themed .pb-gallery-tile img,
.pb-themed .pb-gallery-tile video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Disable native focus ring on the anchor — the box-shadow on the
     parent already signals focus. */
  border: 0;
}
/* Video tile play-overlay: ▶ icon centered with a soft circular
   backdrop. Contrast doesn't depend on the underlying frame because
   the icon is bright white and the backdrop is semi-transparent black.
   pointer-events:none so the click goes straight to the parent anchor
   (PhotoSwipe lightbox open). */
.pb-themed .pb-gallery-tile-video {
  position: relative;
}
.pb-themed .pb-gallery-play {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  background: linear-gradient(180deg, rgba(0,0,0,0.05) 0%, rgba(0,0,0,0.35) 100%);
  transition: background 0.2s ease, transform 0.2s ease;
}
.pb-themed .pb-gallery-tile-video:hover .pb-gallery-play {
  background: linear-gradient(180deg, rgba(0,0,0,0.15) 0%, rgba(0,0,0,0.5) 100%);
}
.pb-themed .pb-gallery-play svg {
  filter: drop-shadow(0 2px 6px rgba(0,0,0,0.45));
  transition: transform 0.2s ease;
}
.pb-themed .pb-gallery-tile-video:hover .pb-gallery-play svg {
  transform: scale(1.08);
}
/* Video thumbnails (the passive <video preload="metadata"> shown
   inside the tile when no posterUrl) follow the same masonry rules
   as <img>. */
.pb-themed .pb-gallery[data-layout="masonry"] .pb-gallery-tile-video video {
  height: auto;
  object-fit: initial;
}

/* GRID layout — equal-aspect cells. Cells are square by default; an
   override class or inline data-attribute could change ratio later. */
.pb-themed .pb-gallery[data-layout="grid"] {
  display: grid;
  gap: var(--gallery-gap);
}
.pb-themed .pb-gallery[data-layout="grid"] .pb-gallery-tile {
  aspect-ratio: 1 / 1;
}

/* Tile size → column count cascade. sm = many small tiles, lg = few
   large tiles. Mobile collapses one tier from each. */
.pb-themed .pb-gallery[data-layout="grid"][data-tile-size="sm"] { grid-template-columns: repeat(4, 1fr); }
.pb-themed .pb-gallery[data-layout="grid"][data-tile-size="md"] { grid-template-columns: repeat(3, 1fr); }
.pb-themed .pb-gallery[data-layout="grid"][data-tile-size="lg"] { grid-template-columns: repeat(2, 1fr); }

@media (max-width: 900px) {
  .pb-themed .pb-gallery[data-layout="grid"][data-tile-size="sm"] { grid-template-columns: repeat(3, 1fr); }
  .pb-themed .pb-gallery[data-layout="grid"][data-tile-size="md"] { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 560px) {
  .pb-themed .pb-gallery[data-layout="grid"][data-tile-size="sm"] { grid-template-columns: repeat(2, 1fr); }
  .pb-themed .pb-gallery[data-layout="grid"][data-tile-size="lg"] { grid-template-columns: 1fr; }
}

/* MASONRY layout — CSS columns. Each tile keeps its natural aspect
   ratio (height: auto), so different photo orientations slot together
   like Pinterest. break-inside avoids tiles being split mid-flow. */
.pb-themed .pb-gallery[data-layout="masonry"] {
  column-gap: var(--gallery-gap);
  /* `display: block` is the default and what column layout needs. */
}
.pb-themed .pb-gallery[data-layout="masonry"][data-tile-size="sm"] { column-count: 4; }
.pb-themed .pb-gallery[data-layout="masonry"][data-tile-size="md"] { column-count: 3; }
.pb-themed .pb-gallery[data-layout="masonry"][data-tile-size="lg"] { column-count: 2; }

.pb-themed .pb-gallery[data-layout="masonry"] .pb-gallery-tile {
  break-inside: avoid;
  margin-bottom: var(--gallery-gap);
  width: 100%;
}
.pb-themed .pb-gallery[data-layout="masonry"] .pb-gallery-tile img {
  height: auto;
  /* Anchor offset is unnecessary in column flow — the image itself sets
     the tile's height. object-fit isn't relevant in masonry. */
  object-fit: initial;
}

@media (max-width: 900px) {
  .pb-themed .pb-gallery[data-layout="masonry"][data-tile-size="sm"] { column-count: 3; }
  .pb-themed .pb-gallery[data-layout="masonry"][data-tile-size="md"] { column-count: 2; }
}
@media (max-width: 560px) {
  .pb-themed .pb-gallery[data-layout="masonry"][data-tile-size="sm"] { column-count: 2; }
  .pb-themed .pb-gallery[data-layout="masonry"][data-tile-size="lg"] { column-count: 1; }
}

/* ---------- IBAN callout ---------- */

.pb-themed .pb-iban-callout {
  text-align: center;
  margin: 2rem auto;
  max-width: 650px;
}
.pb-themed .pb-iban-intro {
  /* Aligned with .pb-description--lead defaults so prose intros read
     consistently across description / iban-callout / whatsapp-cta:
     body font, 1rem, line-height 1.7, weight 300, non-italic. The
     previous defaults (heading font, 1.2rem, line-height 2) made the
     callout intro feel like a different design language than its
     neighbouring lead descriptions. Tokens kept independent so a
     theme can diverge per-block when needed. */
  font-family: var(--iban-intro-family, var(--font-body, Georgia, serif));
  font-size: var(--iban-intro-size, 1rem);
  font-style: var(--iban-intro-italic, normal);
  font-weight: var(--iban-intro-weight, 300);
  line-height: var(--iban-intro-line-height, 1.7);
  margin-bottom: var(--iban-intro-margin-bottom, 1.5rem);
  color: var(--iban-intro-color, var(--ink-muted, var(--ink, inherit)));
}
.pb-themed .pb-iban-box {
  display: inline-block;
  text-align: left;
  background: var(--surface-alt, var(--surface, #fff));
  padding: 1.5rem 2rem;
  border: 1px solid var(--accent, rgba(0,0,0,0.2));
  max-width: 100%;
}
.pb-themed .pb-iban-row {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.4rem 1.25rem;
  align-items: baseline;
  padding: 0.35rem 0;
}
.pb-themed .pb-iban-row + .pb-iban-row {
  border-top: 1px dashed var(--accent, rgba(0,0,0,0.12));
}
.pb-themed .pb-iban-label {
  font-family: var(--font-heading, Georgia, serif);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-muted, rgba(0,0,0,0.55));
}
.pb-themed .pb-iban-value {
  font-family: var(--font-body, Georgia, serif);
  font-size: 1.05rem;
  letter-spacing: 0.08em;
  color: var(--brand-dark, var(--brand, inherit));
  word-break: keep-all;
  overflow-wrap: anywhere;
}
/* Each space-delimited group of digits sits in its own span so iOS Safari
   does not detect a long contiguous digit run as a phone number. The gap
   between groups is the literal whitespace in the markup. */
.pb-themed .pb-iban-group {
  display: inline-block;
  white-space: nowrap;
}
@media (max-width: 480px) {
  .pb-themed .pb-iban-box {
    padding: 1.25rem 1.25rem;
  }
  .pb-themed .pb-iban-row {
    grid-template-columns: 1fr;
    gap: 0.15rem;
    padding: 0.5rem 0;
  }
  .pb-themed .pb-iban-value {
    font-size: 0.98rem;
    letter-spacing: 0.06em;
  }
}

/* ---------- WhatsApp CTA ---------- */

/* ---------- Access-code form (member gate) ----------
   Inherits the same design language as the legacy hardcoded gate
   template (member-gate-renderer.ts): centred form, capital-letter
   input on a translucent border, uppercase pill-style submit. Reads
   fully from theme tokens (`--brand`, `--accent`, `--surface`,
   `--ink`) so any themed Identity gets the look without per-event
   CSS. */
.pb-themed .pb-access-code-form {
  display: flex;
  flex-direction: column;
  gap: var(--access-code-gap, 0.85rem);
  margin: var(--access-code-margin, 1.5rem auto);
  max-width: var(--access-code-max-width, 360px);
  text-align: center;
}
.pb-themed .pb-access-code-input {
  font-family: var(--access-code-input-font, var(--font-body, Georgia, serif));
  font-size: var(--access-code-input-size, 1rem);
  padding: 0.75rem 1rem;
  border: 1px solid color-mix(in srgb, var(--accent, #C4A265) 55%, transparent);
  border-radius: var(--access-code-radius, 4px);
  background: var(--access-code-input-bg, transparent);
  color: var(--ink, #1f1f1f);
  text-align: center;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  outline: none;
  transition: border-color 0.18s ease, box-shadow 0.18s ease;
}
.pb-themed .pb-access-code-input::placeholder {
  color: color-mix(in srgb, var(--ink, #1f1f1f) 40%, transparent);
  text-transform: none;
  letter-spacing: 0.05em;
}
.pb-themed .pb-access-code-input:focus {
  border-color: var(--brand, currentColor);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand, currentColor) 12%, transparent);
}
.pb-themed .pb-access-code-hint {
  font-size: 0.85rem;
  color: var(--ink-muted, var(--ink, inherit));
  opacity: 0.75;
  margin: 0;
  line-height: 1.5;
}
.pb-themed .pb-access-code-error {
  font-size: 0.85rem;
  color: #b91c1c;
  background: #fee2e2;
  border-radius: var(--access-code-radius, 4px);
  padding: 0.55rem 0.75rem;
  margin: 0;
}
.pb-themed .pb-access-code-submit {
  font-family: var(--access-code-submit-font, var(--font-heading, Georgia, serif));
  font-size: var(--access-code-submit-size, 0.95rem);
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 0.85rem 1.5rem;
  border-radius: var(--access-code-radius, 4px);
  border: 1px solid var(--brand, currentColor);
  cursor: pointer;
  transition: background 0.18s ease, color 0.18s ease, transform 0.12s ease;
}
.pb-themed .pb-access-code-submit[data-style="primary"] {
  background: var(--brand, #4a1419);
  color: var(--surface, #fff);
}
.pb-themed .pb-access-code-submit[data-style="primary"]:hover,
.pb-themed .pb-access-code-submit[data-style="primary"]:focus {
  background: var(--brand-dark, var(--brand, #4a1419));
}
.pb-themed .pb-access-code-submit[data-style="ghost"] {
  background: transparent;
  color: var(--brand, currentColor);
}
.pb-themed .pb-access-code-submit[data-style="ghost"]:hover,
.pb-themed .pb-access-code-submit[data-style="ghost"]:focus {
  background: color-mix(in srgb, var(--brand, currentColor) 8%, transparent);
}
.pb-themed .pb-access-code-submit[data-style="link"] {
  background: transparent;
  border: none;
  color: var(--brand, currentColor);
  text-decoration: underline;
  text-underline-offset: 4px;
  letter-spacing: 0.05em;
  padding: 0.5rem 0;
}

.pb-themed .pb-whatsapp-cta {
  text-align: center;
  margin: 2rem auto;
  max-width: 640px;
}
.pb-themed .pb-whatsapp-cta-intro {
  /* Aligned with .pb-description--lead and .pb-iban-intro: body font,
     1rem, line-height 1.7. Independent tokens so a theme can diverge
     whatsapp from iban if needed (defaults match by intent). */
  font-family: var(--whatsapp-intro-family, var(--font-body, Georgia, serif));
  font-size: var(--whatsapp-intro-size, 1rem);
  font-style: var(--whatsapp-intro-italic, normal);
  font-weight: var(--whatsapp-intro-weight, 300);
  line-height: var(--whatsapp-intro-line-height, 1.7);
  margin-bottom: var(--whatsapp-intro-margin-bottom, 1.5rem);
  color: var(--whatsapp-intro-color, var(--ink-muted, var(--ink, inherit)));
}
.pb-themed .pb-whatsapp-cta-buttons {
  display: flex;
  gap: 1rem;
  flex-wrap: wrap;
  justify-content: center;
}
/* Legacy-style "ghost" button: pale shell + brand-green WA glyph so the
   WhatsApp affordance reads at a glance while the button blends with the
   paper theme. Hover inverts to the ink colour. Every surface is a token
   so non-wedding themes (corporate green-on-white, dark mode, etc.) can
   override without touching the block CSS. */
.pb-themed .pb-whatsapp-cta-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: var(--whatsapp-btn-padding, 0.8rem 1.6rem);
  background: var(--whatsapp-btn-bg, #ffffff);
  color: var(--whatsapp-btn-color, var(--ink, #2a1a1f));
  text-decoration: none;
  font-family: var(--whatsapp-btn-family, inherit);
  font-size: var(--whatsapp-btn-size, 0.95rem);
  font-weight: var(--whatsapp-btn-weight, 600);
  letter-spacing: var(--whatsapp-btn-letter-spacing, normal);
  border: var(--whatsapp-btn-border-width, 1px) solid
          var(--whatsapp-btn-border-color, rgba(196, 162, 101, 0.35));
  border-radius: var(--whatsapp-btn-radius, 4px);
  box-shadow: var(--whatsapp-btn-shadow, 0 2px 10px rgba(107, 29, 42, 0.08));
  transition: background 0.3s, color 0.3s, border-color 0.3s,
              transform 0.3s, box-shadow 0.3s;
  cursor: pointer;
}
.pb-themed .pb-whatsapp-cta-btn:hover,
.pb-themed .pb-whatsapp-cta-btn:focus-visible {
  background: var(--whatsapp-btn-hover-bg, var(--accent, #6b1d2a));
  color: var(--whatsapp-btn-hover-color, var(--paper, #fdfbf7));
  border-color: var(--whatsapp-btn-hover-border-color,
                    var(--whatsapp-btn-hover-bg, var(--accent, #6b1d2a)));
  transform: translateY(-2px);
  box-shadow: var(--whatsapp-btn-hover-shadow, 0 4px 14px rgba(107, 29, 42, 0.2));
  outline: none;
}
.pb-themed .pb-whatsapp-cta-btn svg {
  flex-shrink: 0;
}
@media (prefers-reduced-motion: reduce) {
  .pb-themed .pb-whatsapp-cta-btn {
    transition: none;
  }
  .pb-themed .pb-whatsapp-cta-btn:hover,
  .pb-themed .pb-whatsapp-cta-btn:focus-visible {
    transform: none;
  }
}

/* ---------- Map static ---------- */

/* Wrapper holds the framed map AND the optional description as siblings.
   The bordered/shadowed look stays on `.pb-map-static` only — the
   description sits below, outside the frame, so links and longer
   captions can breathe. */
.pb-themed .pb-map-static-wrap {
  max-width: 680px;
  margin: 2rem auto;
}
.pb-themed .pb-map-static-wrap .pb-map-static {
  margin: 0;
}
.pb-themed .pb-map-description {
  /* Centred default — RichEditor emits inline `text-align` styles on
     individual paragraphs when the user picks a different alignment,
     which override this rule per-paragraph as expected. */
  text-align: center;
  margin: 1rem auto 0;
  color: var(--ink-muted, var(--ink, inherit));
  line-height: 1.55;
  font-size: 0.95rem;
}
.pb-themed .pb-map-description p { margin: 0 0 0.5rem; }
.pb-themed .pb-map-description p:last-child { margin-bottom: 0; }
.pb-themed .pb-map-description a {
  color: var(--brand-dark, var(--brand, inherit));
  text-decoration: underline;
}

.pb-themed .pb-map-static {
  max-width: 680px;
  margin: 2rem auto;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.12);
  overflow: hidden;
  position: relative;
}
.pb-themed .pb-map-static a,
.pb-themed .pb-map-static img {
  display: block;
  width: 100%;
  height: auto;
}
.pb-themed .pb-map-static a {
  cursor: pointer;
}

/* OSM / Google iframe sources. The wrapper height comes from settings.height
   (defaulted to 400px in SSR). Iframe fills it; the open-link sits on top
   of the bottom-right corner. */
.pb-themed .pb-map-static[data-source="osm"],
.pb-themed .pb-map-static[data-source="google"] {
  height: var(--pb-map-height, 400px);
}
.pb-themed .pb-map-static .pb-map-iframe {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
}
.pb-themed .pb-map-static .pb-map-open-link {
  position: absolute;
  right: 12px;
  bottom: 12px;
  background: var(--surface, #fff);
  color: var(--brand-dark, var(--brand, #4a1419));
  padding: 6px 12px;
  border-radius: 999px;
  font-size: 0.78rem;
  letter-spacing: 0.03em;
  text-decoration: none;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.18);
  border: 1px solid color-mix(in srgb, var(--accent, #C4A265) 30%, transparent);
  transition: background 0.18s ease, color 0.18s ease;
}
.pb-themed .pb-map-static .pb-map-open-link:hover,
.pb-themed .pb-map-static .pb-map-open-link:focus {
  background: var(--brand-dark, var(--brand, #4a1419));
  color: var(--surface, #fff);
}

/* ---------- Card grid ---------- */

.pb-themed .pb-card-grid {
  display: grid;
  /* auto-fit with a minimum track width; each card can also be capped by
     --card-max-width so a single card doesn't stretch edge-to-edge. */
  grid-template-columns: repeat(auto-fit, minmax(var(--card-grid-min-col, 280px), 1fr));
  gap: var(--card-grid-gap, 2rem);
  margin: var(--card-grid-margin, 2rem auto);
  max-width: var(--card-grid-max-width, none);
  /* Center the row when it holds fewer items than would fill the row. */
  justify-content: center;
}
.pb-themed .pb-card-grid > .pb-card,
.pb-themed .pb-card-grid > .pb-card-linked {
  max-width: var(--card-max-width, none);
  width: 100%;
  justify-self: center;
}
.pb-themed .pb-card-grid-cols-2 { grid-template-columns: repeat(2, 1fr); }
.pb-themed .pb-card-grid-cols-3 { grid-template-columns: repeat(3, 1fr); }
.pb-themed .pb-card-grid-cols-4 { grid-template-columns: repeat(4, 1fr); }

.pb-themed .pb-card {
  /* Card palette — independent tokens so a theme can differ from the page
     `--surface` (marcoysonia uses pure white cards on a cream page). */
  background: var(--card-bg, #fff);
  padding: var(--card-padding, 2rem);
  /* Border color is intentionally a faded gold (alpha 0.25) so the card
     reads as a subtle frame, not a saturated outline. Same pattern as the
     paper frame shadow rings (§15.x). Override via --card-border. */
  border: var(--card-border, 1px solid rgba(196,162,101,0.25));
  border-radius: var(--card-radius, 0);
  box-shadow: var(--card-shadow, 0 4px 20px rgba(0, 0, 0, 0.06));
  display: flex;
  flex-direction: column;
  text-align: center;
  gap: var(--card-gap, 0.75rem);
  transition: transform 0.3s, box-shadow 0.3s;
}
.pb-themed .pb-card-linked {
  text-decoration: none;
  color: inherit;
}
.pb-themed .pb-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.12);
}
.pb-themed .pb-card-tag {
  font-size: 0.7rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--brand, inherit);
  font-weight: 600;
}
.pb-themed .pb-card-title {
  font-family: var(--card-title-family, var(--font-heading, Georgia, serif));
  font-size: var(--card-title-size, 1.35rem);
  font-weight: var(--card-title-weight, 500);
  margin: 0;
  /* Title color defaults to brand-dark but a theme can override per-section
     (marcoysonia uses olive for accommodation cards). */
  color: var(--card-title-color, var(--brand-dark, var(--brand, inherit)));
}
.pb-themed .pb-card-desc {
  color: var(--ink-muted, var(--ink, inherit));
  font-size: 0.92rem;
  line-height: 1.7;
  margin: 0;
}
.pb-themed .pb-card-cta {
  margin-top: auto;
  font-size: 0.75rem;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--brand, inherit);
  font-weight: 600;
}
.pb-themed .pb-card-cta-btn {
  margin: auto auto 0;   /* push to the bottom, center horizontally */
  display: block;
  width: fit-content;
  max-width: var(--card-cta-max-width, 280px);
  padding: var(--card-cta-padding, 0.6rem 1.4rem);
  background: var(--card-cta-bg, var(--brand, #222));
  color: var(--card-cta-color, var(--surface, #fff));
  text-decoration: none;
  font-size: var(--card-cta-size, 0.95rem);
  font-weight: var(--card-cta-weight, 600);
  border-radius: var(--card-cta-radius, 4px);
  text-align: center;
  transition: background 0.2s, transform 0.2s;
}
.pb-themed .pb-card-cta-btn:hover {
  background: var(--brand-dark, var(--brand, #222));
  transform: translateY(-1px);
}

@media (max-width: 640px) {
  .pb-themed .pb-card-grid-cols-4,
  .pb-themed .pb-card-grid-cols-3 { grid-template-columns: 1fr; }
}

/* ---------- Form widget (theme='inherit' mode) ----------
   The widget JS outputs pelada HTML when the theme is 'inherit'. These rules
   give it the paper-card look inside an event microsite. External embeds
   (marcoysonia-static still using theme='default') are untouched — those get
   the widget's own default stylesheet. */

.pb-themed .wfw-form {
  max-width: var(--form-card-max-width, 560px);
  margin: 2rem auto;
  padding: var(--form-card-padding, 2.5rem 2rem);
  /* Clip the repeater-item pseudo-elements to the card's rounded
   * corners — without this, the band would overshoot the form edges. */
  overflow: hidden;
  /* Dedicated card token — defaults to pure white so the card pops on any
     paper tone. Theme override via --form-card-bg if white is too stark. */
  background: var(--form-card-bg, #fff);
  border: var(--form-card-border, 1px solid rgba(0,0,0,0.08));
  box-shadow: var(--form-card-shadow, 0 4px 20px rgba(0, 0, 0, 0.08));
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
  position: relative;
}

.pb-themed .wfw-heading {
  font-family: var(--font-heading, Georgia, serif);
  font-size: 1.15rem;
  font-weight: 500;
  color: var(--brand-dark, var(--brand, inherit));
  margin: 1rem 0 0.25rem;
}
.pb-themed .wfw-heading:first-child { margin-top: 0; }

.pb-themed .wfw-group {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.pb-themed .wfw-group > label {
  font-size: 0.7rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--brand, inherit);
  margin: 0;
}

/* Exclude radio + checkbox — they're styled separately below. The generic
   `width:100%; padding:0.85rem` rule stretches a radio circle into a full-width
   bar with the label floating around it (the bug that produced the ugly
   attendance layout). */
.pb-themed .wfw-group input:not([type="radio"]):not([type="checkbox"]),
.pb-themed .wfw-group select,
.pb-themed .wfw-group textarea {
  width: 100%;
  padding: 0.85rem 1rem;
  font-family: var(--font-body, inherit);
  font-size: 0.95rem;
  font-weight: 300;
  border: 1px solid var(--form-input-border, var(--accent, rgba(0,0,0,0.2)));
  /* Input bg = paper-alt cream, matches legacy `var(--cream)` recipe. Lives
     inside the white form card so the contrast is paper-on-paper. Override
     via --form-input-bg. */
  background: var(--form-input-bg, var(--surface-alt, #fff));
  color: var(--ink, inherit);
  border-radius: var(--form-input-radius, 0);
  box-sizing: border-box;
  transition: border-color 0.2s, background-color 0.2s, box-shadow 0.2s;
}
.pb-themed .wfw-group input:not([type="radio"]):not([type="checkbox"]):focus,
.pb-themed .wfw-group select:focus,
.pb-themed .wfw-group textarea:focus {
  outline: none;
  border-color: var(--brand, currentColor);
  background: var(--form-input-focus-bg, #fff);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--brand, currentColor) 20%, transparent);
}
.pb-themed .wfw-group textarea {
  min-height: 110px;
  resize: vertical;
}

/* Canonical phone field: country-code select + number input side-by-side.
   Prefix select narrow; number input takes the rest. Both share the cream
   input styling via inherited rules. */
.pb-themed .wfw-phone-row {
  display: flex;
  gap: 0.5rem;
  align-items: stretch;
}
.pb-themed .wfw-phone-row select.wfw-phone-cc {
  flex: 0 0 auto;
  min-width: 6.5rem;
  max-width: 40%;
}
.pb-themed .wfw-phone-row input[type="tel"] {
  flex: 1 1 auto;
  min-width: 0;
}

/* Radio = selectable chip. Hide the native circle (visually-hidden but
   still keyboard/screen-reader reachable), turn the label into a bordered
   pill, highlight on :has(input:checked). */
.pb-themed .wfw-radio-group {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  padding-top: 0.25rem;
}
.pb-themed .wfw-radio {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.55rem 1rem;
  font-size: 0.9rem;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  cursor: pointer;
  color: var(--ink, inherit);
  background: var(--form-input-bg, var(--surface-alt, #fff));
  border: 1px solid var(--form-input-border, var(--accent, rgba(0,0,0,0.2)));
  border-radius: var(--form-input-radius, 0);
  transition: background 0.2s, border-color 0.2s, color 0.2s;
}
.pb-themed .wfw-radio:hover {
  border-color: var(--brand, currentColor);
}
.pb-themed .wfw-radio:has(input:checked) {
  background: var(--brand, #222);
  border-color: var(--brand, #222);
  color: var(--surface-alt, #fff);
}
/* Visually hidden native radio — keeps a11y semantics intact. */
.pb-themed .wfw-radio input[type="radio"] {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  clip: rect(0 0 0 0);
  overflow: hidden;
}

/* Compact pill-radio variant — emitted by the widget when a radio field
   carries `meta.display: 'pills'`. Renders inline-left, smaller chips
   than `.wfw-radio`, no field label competing for space. Used for
   ancillary fields (age bracket, etc.) that should sit alongside the
   identity inputs without dominating the row. The rules use the same
   tokens as `.wfw-radio` so the visual language stays coherent. */
.pb-themed .wfw-pill-row {
  /* Override the `.wfw-group` flex column from above — pills want to
     read as a single inline strip (label + chips) flowing left to right. */
  flex-direction: row !important;
  align-items: center;
  flex-wrap: wrap;
  justify-content: flex-start;
  gap: 0.5rem;
}
.pb-themed .wfw-pill-label {
  font-size: 0.7rem;
  letter-spacing: 0.04em;
  text-transform: none;
  color: var(--ink-muted, var(--ink, inherit));
  font-weight: 500;
  margin: 0;
  display: inline;
}
.pb-themed .wfw-pill-radio-group {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}
.pb-themed .wfw-pill-radio {
  display: inline-flex;
  align-items: center;
  cursor: pointer;
  font-size: 0.8rem;
  line-height: 1;
  padding: 0.35rem 0.7rem;
  border: 1px solid var(--form-input-border, var(--accent, rgba(0,0,0,0.2)));
  border-radius: 999px;
  background: var(--form-input-bg, var(--surface-alt, #fff));
  color: var(--ink, inherit);
  transition: background 0.15s, border-color 0.15s, color 0.15s;
  user-select: none;
}
.pb-themed .wfw-pill-radio:hover {
  border-color: var(--brand, currentColor);
}
.pb-themed .wfw-pill-radio:has(input:checked) {
  background: var(--brand, #222);
  border-color: var(--brand, #222);
  color: var(--surface-alt, #fff);
}
.pb-themed .wfw-pill-radio input[type="radio"] {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  clip: rect(0 0 0 0);
  overflow: hidden;
}

/* Checkbox row (unchanged semantics) */
.pb-themed .wfw-checkbox {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.9rem;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  cursor: pointer;
  color: var(--ink, inherit);
}

/* Submit button */
.pb-themed .wfw-submit {
  text-align: center;
  margin-top: 1rem;
}
.pb-themed .wfw-submit button {
  /* Override widget's injected width:100% — legacy look is an auto-width
     centered block, not a stretched full-width bar. */
  width: var(--form-submit-width, auto);
  padding: 1rem 3rem;
  font-family: var(--font-body, inherit);
  font-size: 0.7rem;
  letter-spacing: 0.25em;
  text-transform: uppercase;
  font-weight: 600;
  background: var(--form-submit-bg, var(--brand, #222));
  /* Button label = cream (matches legacy `var(--cream)`), legible on burgundy. */
  color: var(--form-submit-color, var(--surface-alt, #fff));
  border: 2px solid var(--form-submit-bg, var(--brand, #222));
  cursor: pointer;
  transition: all 0.25s;
  border-radius: var(--form-submit-radius, 0);
}
.pb-themed .wfw-submit button:hover {
  background: var(--brand-dark, var(--brand, #222));
  border-color: var(--brand-dark, var(--brand, #222));
  transform: translateY(-1px);
  box-shadow: 0 6px 20px color-mix(in srgb, var(--brand, currentColor) 30%, transparent);
}
.pb-themed .wfw-submit button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}

/* Post-submit message banner */
.pb-themed .wfw-msg {
  margin-top: 1rem;
  padding: 0.9rem 1.1rem;
  font-size: 0.9rem;
  text-align: center;
  border: 1px solid transparent;
}
.pb-themed .wfw-msg-ok  { background: color-mix(in srgb, var(--brand, currentColor) 6%, transparent); color: var(--brand-dark, var(--brand, inherit)); border-color: var(--accent, currentColor); }
.pb-themed .wfw-msg-err { background: color-mix(in srgb, #c62828 6%, transparent); color: #c62828; border-color: rgba(198,40,40,0.3); }

/* Repeater (companions) — full-bleed: the outer wrapper carries no
 * padding/border so each companion item gets the same horizontal
 * width as the head's fields. Items differentiate themselves with an
 * alternating tinted background (zebra stripe), not by being boxed
 * into a narrower card. The remove button stays absolutely positioned
 * but sits inside the row's own breathing room rather than a fake
 * gutter created by extra padding. */
.pb-themed .wfw-repeater {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  padding: 0;
  background: transparent;
  border: 0;
  margin: 0;
}
.pb-themed .wfw-repeater-label {
  font-size: 0.7rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--brand, inherit);
  margin: 0;
}
.pb-themed .wfw-repeater-items {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.pb-themed .wfw-repeater-item {
  position: relative;
  /* Match the form's own gutter — no inset card. The remove ✕ floats
   * over the top-right and we keep a small right-padding on the
   * first row of fields so labels don't slip under it. */
  padding: 1rem 0 1rem 0;
  background: transparent;
  border: 0;
  border-top: 1px solid color-mix(in srgb, var(--accent, currentColor) 35%, transparent);
  display: flex;
  flex-direction: column;
  gap: 1rem;
}
.pb-themed .wfw-repeater-item:first-child { border-top: 0; }
/* Zebra striping via a soft inset tint that bleeds to the form edges.
 * Pseudo-element so the actual content keeps its full width and the
 * tint only covers the row's vertical band. The negative inline
 * inset matches the form-card horizontal padding (default 2rem,
 * overridable via --form-card-padding-x) so each band visually
 * spans the full width of `.wfw-form`, not just the inner gutter. */
.pb-themed .wfw-form { --form-card-padding-x: 2rem; }
.pb-themed .wfw-repeater-item::before {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(-1 * var(--form-card-padding-x, 2rem));
  right: calc(-1 * var(--form-card-padding-x, 2rem));
  background: color-mix(in srgb, var(--brand, currentColor) 4%, transparent);
  pointer-events: none;
  z-index: 0;
}
.pb-themed .wfw-repeater-item:nth-child(even)::before {
  background: color-mix(in srgb, var(--brand, currentColor) 8%, transparent);
}
.pb-themed .wfw-repeater-item > * {
  position: relative;
  z-index: 1;
}
.pb-themed .wfw-repeater-remove {
  position: absolute;
  top: 0.6rem;
  right: 0;
  background: transparent;
  border: none;
  color: var(--brand, currentColor);
  font-size: 1.2rem;
  line-height: 1;
  cursor: pointer;
  padding: 0.2rem 0.4rem;
  opacity: 0.6;
  z-index: 2;
}
.pb-themed .wfw-repeater-remove:hover { opacity: 1; }
.pb-themed .wfw-repeater-add {
  align-self: flex-start;
  padding: 0.55rem 1.3rem;
  font-family: var(--font-body, inherit);
  font-size: 0.65rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  font-weight: 600;
  background: transparent;
  color: var(--brand, inherit);
  border: 1px solid var(--brand, currentColor);
  cursor: pointer;
  border-radius: 0;
  transition: all 0.2s;
}
.pb-themed .wfw-repeater-add:hover { background: var(--brand, #222); color: var(--surface, #fff); }
.pb-themed .wfw-repeater-add:disabled { opacity: 0.4; cursor: not-allowed; }

/* Dietary-wiki chips inside the form */
.pb-themed .wfw-dietary-wiki {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}
.pb-themed .wfw-dietary-wiki-cat-label {
  font-size: 0.65rem;
  font-weight: 600;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--ink-muted, var(--ink, inherit));
  margin-top: 0.25rem;
}
.pb-themed .wfw-dietary-wiki-group {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 0.5rem;
}
.pb-themed .wfw-dietary-wiki-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.45rem 0.8rem;
  border: 1px solid var(--accent, rgba(0,0,0,0.2));
  border-radius: 999px;
  font-size: 0.82rem;
  cursor: pointer;
  background: var(--surface, #fff);
  text-transform: none;
  letter-spacing: 0;
  font-weight: 400;
  color: var(--ink, inherit);
  transition: background 0.15s, border-color 0.15s;
}
.pb-themed .wfw-dietary-wiki-chip input {
  margin: 0;
  width: auto;
  accent-color: var(--brand, currentColor);
}
.pb-themed .wfw-dietary-wiki-chip:has(input:checked) {
  background: color-mix(in srgb, var(--brand, currentColor) 8%, transparent);
  border-color: var(--brand, currentColor);
}
.pb-themed .wfw-dietary-wiki-info {
  background: transparent;
  border: none;
  color: var(--brand, currentColor);
  font-size: 0.9rem;
  cursor: pointer;
  padding: 0 0.1rem;
  line-height: 1;
}
.pb-themed .wfw-dietary-wiki-info:hover { opacity: 0.7; }

/* Wrapper div used by showIf must not break flex gap */
.pb-themed .wfw-field-wrapper { display: contents; }

/* ---------- Inline language switcher ---------- */
/* Rendered by event-renderer when ≥2 enabled languages exist. Designed to
   sit at the top of the paper frame as a small row of ES | EN | FR buttons. */

.pb-themed .pb-themed-lang-switcher {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 0.25rem;
  padding: 0.25rem 0 1rem;
  margin-top: var(--lang-switcher-offset, -1rem);
}

.pb-themed .pb-themed-lang {
  padding: 0.25rem 0.5rem;
  font-family: var(--font-body, inherit);
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-muted, var(--ink, inherit));
  text-decoration: none;
  border-bottom: 2px solid transparent;
  transition: color 0.2s, border-color 0.2s;
}
.pb-themed .pb-themed-lang:hover {
  color: var(--brand-dark, var(--brand, inherit));
}
.pb-themed .pb-themed-lang-active {
  color: var(--brand-dark, var(--brand, inherit));
  border-bottom-color: var(--accent, currentColor);
  font-weight: 600;
}
.pb-themed .pb-themed-lang-sep {
  color: var(--accent, rgba(0,0,0,0.35));
  font-size: 0.75rem;
  opacity: 0.5;
}

/* ---------- Countdown block ---------- */

.pb-themed .pb-countdown {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: var(--countdown-gap, 3rem);
  margin: var(--countdown-margin, 3rem auto);
  padding: var(--countdown-padding, 2rem 1rem);
  background: var(--countdown-bg, var(--brand, transparent));
  color: var(--countdown-ink, var(--surface, inherit));
  border-top: var(--countdown-border-top, none);
  border-bottom: var(--countdown-border-bottom, none);
  border-radius: var(--radius, 0);
  position: relative;
}

/* Bleed lateral del countdown se gestiona ahora vía la pareja
   `data-width="container"` / `data-width="viewport"` del chrome
   universal (.pb-block-chrome) — mismo mecanismo que el resto de
   bloques. Las reglas dedicadas (`pb-countdown-full-bleed-*`) se
   retiraron 2026-05-01 tras migrar los datos a `box.width`. */

.pb-themed .pb-countdown-cards {
  text-align: center;
}
.pb-themed .pb-countdown-inline {
  gap: var(--countdown-gap-inline, 1.5rem);
  padding: var(--countdown-padding-inline, 1rem);
}

.pb-themed .pb-countdown-cell {
  display: flex;
  flex-direction: column;
  align-items: center;
  min-width: 4rem;
}
.pb-themed .pb-countdown-number {
  /* Defaults to the body font (Lora-like) with +0.1em tracking — visual
     cousin of the IBAN callout's boxed digits. Themes can override via
     `countdown.style.numberFont` / `.numberLetterSpacing`. */
  font-family: var(--countdown-number-font, var(--font-body, Georgia, serif));
  font-size: var(--countdown-number-size, clamp(2.2rem, 6vw, 4rem));
  letter-spacing: var(--countdown-number-letter-spacing, 0.1em);
  line-height: 1;
  font-weight: var(--countdown-number-weight, 400);
  color: var(--countdown-number-color, var(--surface, var(--ink, inherit)));
  text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.15);
}
.pb-themed .pb-countdown-label {
  font-size: 0.65rem;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  margin-top: 0.8rem;
  color: var(--countdown-label-color, var(--accent-light, var(--accent, inherit)));
  font-weight: 500;
}
.pb-themed .pb-countdown-reached {
  font-family: var(--font-heading, Georgia, serif);
  font-size: clamp(1.8rem, 4vw, 2.5rem);
  color: var(--countdown-number-color, var(--surface, inherit));
  text-align: center;
  width: 100%;
}

/* ---------- FAQ accordion ---------- */

.pb-themed .pb-faq {
  max-width: var(--faq-max-width, 750px);
  margin: var(--faq-margin, 2rem auto);
}
.pb-themed .pb-faq-item {
  border-bottom: 1px solid var(--faq-divider, var(--accent, rgba(0,0,0,0.2)));
  padding: 1.5rem 0;
}
.pb-themed .pb-faq-question {
  display: flex;
  justify-content: space-between;
  align-items: center;
  cursor: pointer;
  font-family: var(--font-heading, Georgia, serif);
  font-size: 1.15rem;
  font-weight: 500;
  color: var(--brand-dark, var(--brand, inherit));
  list-style: none;
  /* Hide the default triangle marker across browsers */
}
.pb-themed .pb-faq-question::-webkit-details-marker { display: none; }
.pb-themed .pb-faq-question::marker { content: ''; }
.pb-themed .pb-faq-indicator {
  font-size: 1.5rem;
  font-weight: 300;
  color: var(--accent, var(--brand, inherit));
  transition: transform 0.25s ease;
  line-height: 1;
  width: 1.25em;
  text-align: center;
}
.pb-themed .pb-faq-item[open] .pb-faq-indicator {
  /* Rotation achieves "+ → ×" visually via CSS alone; the JS hydration also
     swaps the text content for browsers that skip the rotation animation. */
  transform: rotate(45deg);
}
.pb-themed .pb-faq-answer {
  padding-top: var(--faq-answer-padding-top, 1rem);
  color: var(--faq-answer-color, var(--ink-muted, var(--ink, inherit)));
  line-height: var(--faq-answer-line-height, 1.9);
  font-size: var(--faq-answer-size, 0.95rem);
}
.pb-themed .pb-faq-answer p:first-child { margin-top: 0; }

/* Reveal animation — applied via a JS-toggled class so it re-fires every
   time <details> opens (native <details> doesn't restart CSS animations
   on display-change alone). The class is added on the `toggle` event
   (see pb-themed-blocks.js) and stays until the next toggle. */
.pb-themed .pb-faq-answer-reveal {
  animation: pb-faq-reveal var(--faq-answer-animation-duration, 0.3s)
             var(--faq-answer-animation-easing, ease-out);
}

@keyframes pb-faq-reveal {
  from {
    opacity: 0;
    transform: translateY(-6px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Respect users who prefer less motion. */
@media (prefers-reduced-motion: reduce) {
  .pb-themed .pb-faq-answer-reveal { animation: none; }
  .pb-themed .pb-faq-indicator { transition: none; }
}

/* ---------- Small screens ---------- */

@media (max-width: 768px) {
  /* Override the inline + block padding TOKENS (not just the resolved
     padding) so any descendant that reads --frame-padding-inline /
     --frame-padding-block (e.g. .pb-block-chrome[data-width=container]
     for its negative-margin bleed, or per-block negative margins) tracks
     the same mobile shrink. Without this, chrome's negative inline
     margin stays at the desktop value and bleeds past the paper edge. */
  .pb-themed-frame-paper {
    /* Inset budget on mobile:
       - paper margin from viewport: 8px
       - paper inline padding (this var): 32px
       - inner gold line at 12px from paper edge (--frame-inset 20 × 0.6)
       - outer gold line at 16px (12 + frame-inset-inner 4)
       Net: text starts ~20px past the inner gold line — enough breathing
       room so the double gold border doesn't visually crowd the content.
       16px and 24px (previous tries) were too tight; the double-line
       border accentuated the lack of space. */
    --frame-padding-inline: var(--frame-mobile-padding-inline, 32px);
    --frame-padding-block: var(--frame-mobile-padding-block, 32px);
    /* Default to flush with the viewport edge — the "floating sheet"
       feel doesn't survive at <=768px wide, and the 8px strip of body
       bg on each side just reads as a visual seam. Themes that still
       want a sliver of breathing room can set --frame-mobile-side-margin
       per event. */
    margin-left: var(--frame-mobile-side-margin, 0);
    margin-right: var(--frame-mobile-side-margin, 0);
  }
  .pb-themed-frame-paper::before {
    inset: calc(var(--frame-inset, 20px) * 0.6);
  }
  .pb-themed-frame-paper::after {
    inset: calc(var(--frame-inset, 20px) * 0.6 + var(--frame-inset-inner, 4px));
  }
  .pb-themed-frame-minimal {
    padding: var(--frame-mobile-padding-block, 2rem)
             var(--frame-mobile-padding-inline, 1.25rem);
  }
}

@media (max-width: 480px) {
  .pb-themed-frame-paper {
    margin-left: 0;
    margin-right: 0;
  }
}

/* ===== Universal Block Chrome (box.ts) =====
   Wraps any block whose settings.box has overrides. Lives BEFORE the
   per-block rules so block-specific selectors can still override (rare).
   Tokens map to surface/brand vars; custom colors arrive via inline
   `style="background:..."` and the rules below skip the bg paint. */

.pb-block-chrome {
  /* Inert by default — only data-* attributes paint anything. */
  display: block;
}

/* ---- Background ---- */
.pb-block-chrome[data-bg="base"]   { background: var(--surface, transparent); }
.pb-block-chrome[data-bg="alt"]    { background: var(--surface-alt, var(--surface, transparent)); }
.pb-block-chrome[data-bg="dark"]   { background: var(--brand-dark, var(--brand, transparent)); }
.pb-block-chrome[data-bg="darker"] { background: var(--brand-darker, var(--brand-dark, transparent)); }
.pb-block-chrome[data-bg="brand"]  { background: var(--brand, transparent); }
/* `data-bg="custom"` paints from inline style — no rule needed here. */

/* ---- Border (4 sides × 3 styles) ---- */
.pb-block-chrome[data-border-top="hairline"]    { border-top: 1px solid color-mix(in srgb, var(--accent, #C4A265) 40%, transparent); }
.pb-block-chrome[data-border-top="solid"]       { border-top: 1px solid var(--accent, #C4A265); }
.pb-block-chrome[data-border-top="none"]        { border-top: none; }
.pb-block-chrome[data-border-bottom="hairline"] { border-bottom: 1px solid color-mix(in srgb, var(--accent, #C4A265) 40%, transparent); }
.pb-block-chrome[data-border-bottom="solid"]    { border-bottom: 1px solid var(--accent, #C4A265); }
.pb-block-chrome[data-border-bottom="none"]     { border-bottom: none; }
.pb-block-chrome[data-border-left="hairline"]   { border-left: 1px solid color-mix(in srgb, var(--accent, #C4A265) 40%, transparent); }
.pb-block-chrome[data-border-left="solid"]      { border-left: 1px solid var(--accent, #C4A265); }
.pb-block-chrome[data-border-left="none"]       { border-left: none; }
.pb-block-chrome[data-border-right="hairline"]  { border-right: 1px solid color-mix(in srgb, var(--accent, #C4A265) 40%, transparent); }
.pb-block-chrome[data-border-right="solid"]     { border-right: 1px solid var(--accent, #C4A265); }
.pb-block-chrome[data-border-right="none"]      { border-right: none; }

/* ---- Width / break-out (matches countdown's full-bleed trick) ---- */
.pb-block-chrome[data-width="container"] {
  margin-left: calc(-1 * var(--frame-padding-inline, 32px));
  margin-right: calc(-1 * var(--frame-padding-inline, 32px));
  padding-left: var(--frame-padding-inline, 32px);
  padding-right: var(--frame-padding-inline, 32px);
  box-sizing: border-box;
}
.pb-block-chrome[data-width="viewport"] {
  position: relative;
  width: 100vw;
  left: 50%;
  right: 50%;
  margin-left: -50vw;
  margin-right: -50vw;
  padding-left: var(--frame-padding-inline, 32px);
  padding-right: var(--frame-padding-inline, 32px);
  box-sizing: border-box;
}

/* ---- Vertical padding scale ----
   `Auto` (no data-pad-y attr) defaults to the `md` value — sensible
   breathing room without forcing operators to think about padding for
   every block. `none` is the explicit "I want zero padding here"
   escape hatch. Themes can dial the auto default via
   `--block-chrome-pad-y-auto`. */
.pb-block-chrome:not([data-pad-y]),
.pb-block-chrome[data-pad-y=""]      { padding-top: var(--block-chrome-pad-y-auto, 1.5rem); padding-bottom: var(--block-chrome-pad-y-auto, 1.5rem); }
.pb-block-chrome[data-pad-y="none"]  { padding-top: 0; padding-bottom: 0; }
.pb-block-chrome[data-pad-y="sm"]    { padding-top: 0.75rem; padding-bottom: 0.75rem; }
.pb-block-chrome[data-pad-y="md"]    { padding-top: 1.5rem;  padding-bottom: 1.5rem; }
.pb-block-chrome[data-pad-y="lg"]    { padding-top: 3rem;    padding-bottom: 3rem; }

/* ---- Bleed top / bottom ----
   Extends the chrome's BACKGROUND upward (or downward) into the
   paper's frame gap so the band appears to start at the cover edge
   with no cream gap and no gold ring visible. Implemented as
   `padding + negative margin` — the bg paints across the padding,
   while the negative margin pulls the content back to its natural
   position. This is more robust than a plain negative margin (which
   leaves the box-shadow rings of paper visible because chrome
   doesn't extend its bg far enough): the padding makes the bg
   actually fill the upward area.

   Two scopes:
     - First-child of paper with bleed-top: extend bg through the
       `frame-top-margin + frame-padding-block` (75 + 40 = 115px
       default). Covers the gold ring of paper's outer box-shadow
       and merges with the body bg above.
     - Non-first-child: just absorb the `frame-padding-block` so the
       band hugs the previous block.
   Same for bleed-bottom. */
.pb-themed-frame-paper > .pb-block-chrome:first-child[data-bleed-top="true"] {
  padding-top: calc(var(--frame-top-margin, 75px) + var(--frame-padding-block, 40px));
  margin-top: calc(-1 * (var(--frame-top-margin, 75px) + var(--frame-padding-block, 40px)));
  position: relative;
  z-index: 1;
}
.pb-themed-frame-paper > .pb-block-chrome:last-child[data-bleed-bottom="true"] {
  padding-bottom: calc(var(--frame-bottom-margin, var(--frame-top-margin, 75px)) + var(--frame-padding-block, 40px));
  margin-bottom: calc(-1 * (var(--frame-bottom-margin, var(--frame-top-margin, 75px)) + var(--frame-padding-block, 40px)));
  position: relative;
  z-index: 1;
}
.pb-themed .pb-block-chrome[data-bleed-top="true"]:not(.pb-themed-frame-paper > :first-child) {
  padding-top: var(--frame-padding-block, 40px);
  margin-top: calc(-1 * var(--frame-padding-block, 40px));
}
.pb-themed .pb-block-chrome[data-bleed-bottom="true"]:not(.pb-themed-frame-paper > :last-child) {
  padding-bottom: var(--frame-padding-block, 40px);
  margin-bottom: calc(-1 * var(--frame-padding-block, 40px));
}

/* ---- Inverted controls on dark backgrounds ----
   Cooperates with block-specific rules; here we only set ink/border defaults
   that block CSS reads via inheritance (e.g. add-to-calendar's button uses
   currentColor for its border + text). */
.pb-block-chrome[data-invert="true"] {
  color: var(--surface, #fff);
  --pb-on-dark: 1;
}

/* ---- Seamless stacking ----
   When two chromed blocks with bg are direct DOM siblings, suppress the
   duplicated hairline at the seam UNLESS the user has explicitly set the
   border via data-border-* on either side. Explicit choices always win. */
.pb-block-chrome[data-bg]:not([data-border-bottom]) + .pb-block-chrome[data-bg]:not([data-border-top]) {
  /* visual cue: nothing — relies on the next rule actually muting one of them */
}
.pb-block-chrome[data-bg] + .pb-block-chrome[data-bg]:not([data-border-top]) {
  border-top: none;
}
.pb-block-chrome[data-bg]:not([data-border-bottom]):has(+ .pb-block-chrome[data-bg]) {
  border-bottom: none;
}
/* Suppress the predecessor's bottom hairline (countdown legacy etc.) when
   the user explicitly picked "Sin línea" on the chrome that follows it. */
.pb-block-chrome[data-bg]:has(+ .pb-block-chrome[data-border-top="none"]) {
  border-bottom: none;
}
.pb-themed .pb-countdown:has(+ .pb-block-chrome[data-border-top="none"]) {
  border-bottom: none;
}

/* Inner block defers its native borders to the chrome wrapper whenever the
   chrome carries an explicit border-X override. The countdown is the
   notable case — it emits `--countdown-border-{top,bottom}` inline vars
   (legacy theming) that draw a gold hairline at the top/bottom of its
   pre-chrome rectangle. Now that the chrome system owns borders, the
   inner element should not double-paint. Empty data-border-* (no override
   at all) still leaves the legacy borders alone. */
.pb-block-chrome[data-border-top]    > .pb-countdown { border-top: none; }
.pb-block-chrome[data-border-bottom] > .pb-countdown { border-bottom: none; }
.pb-block-chrome[data-border-left]   > .pb-countdown { border-left: none; }
.pb-block-chrome[data-border-right]  > .pb-countdown { border-right: none; }

/* ===== Add-to-calendar block ===== */
.pb-themed .pb-add-to-calendar {
  display: flex;
  margin: 0 auto 1.25rem;
  padding: 0 1rem;
}
.pb-themed .pb-add-to-calendar[data-align="left"]   { justify-content: flex-start; }
.pb-themed .pb-add-to-calendar[data-align="right"]  { justify-content: flex-end; }
.pb-themed .pb-add-to-calendar[data-align="center"] { justify-content: center; }

.pb-themed .pb-add-to-calendar-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.7rem 1.25rem;
  border: 1px solid var(--accent, #C4A265);
  border-radius: 999px;
  color: var(--brand-dark, var(--brand, inherit));
  background: transparent;
  text-decoration: none;
  font-family: var(--font-body, Georgia, serif);
  font-size: 0.9rem;
  font-weight: 500;
  letter-spacing: 0.03em;
  transition: background 0.18s ease, color 0.18s ease;
}
.pb-themed .pb-add-to-calendar-btn:hover,
.pb-themed .pb-add-to-calendar-btn:focus {
  background: var(--accent, #C4A265);
  color: var(--surface, #fff);
}
.pb-themed .pb-add-to-calendar-icon { line-height: 0; }
.pb-themed .pb-add-to-calendar-text { display: inline-flex; flex-direction: column; line-height: 1.15; }
.pb-themed .pb-add-to-calendar-date {
  font-size: 0.72rem;
  opacity: 0.75;
  margin-top: 2px;
  letter-spacing: 0.05em;
}

/* Inverted mode: light pill on a dark background. Driven by the chrome
   wrapper's data-invert (universal box system), so the same rule fires
   for any block whose containing chrome is inverted. */
.pb-themed .pb-block-chrome[data-invert="true"] .pb-add-to-calendar-btn {
  border-color: var(--surface, #fff);
  color: var(--surface, #fff);
}
.pb-themed .pb-block-chrome[data-invert="true"] .pb-add-to-calendar-btn:hover,
.pb-themed .pb-block-chrome[data-invert="true"] .pb-add-to-calendar-btn:focus {
  background: var(--surface, #fff);
  color: var(--brand-dark, var(--brand, #4a1419));
}

/* ============================================================
   Cover block (with-text variant) — the unified portada.
   The legacy image-only cover renders inline styles directly;
   these rules only apply when the renderer emits .pb-cover-with-text.
   ============================================================ */

.pb-cover-with-text {
  display: flex;
  flex-direction: column;
  position: relative;
  text-align: center;
  /* min-height set inline by SSR from settings.height */
}
/* Reserve breathing room top + bottom so 'top' / 'bottom' valign feels
   anchored near the edge, not glued to it. Skipped on 100vh covers
   (those already fill the viewport — extra padding would push the next
   section into view). Middle valign is unaffected (margin auto centers). */
.pb-cover-with-text:not([data-height="100vh"]) {
  padding-block: clamp(2rem, 8vh, 6rem);
}

/* Cover lives inside the `.pb-themed-frame-paper` and renders in normal
   flow — it sits AFTER the fixed wactivity-header (whose height is
   reserved by `#main-content { padding-top }` in shell.css), and inside
   the paper's frame-top-margin + frame-padding-block. 100vh covers
   measure the visible viewport — that means subtracting both the fixed
   nav (--shell-nav-offset, 0 when no nav exists) AND the paper's own
   top reservation, so the cover fits in one screen instead of pushing
   the next section past the fold. */
.pb-themed-frame-paper > .pb-cover-with-text[data-height="100vh"],
.pb-themed-frame-paper > .pb-block-chrome > .pb-cover-with-text[data-height="100vh"] {
  min-height: calc(
    100vh
    - var(--shell-nav-offset, 0px)
    - var(--frame-top-margin, 75px)
    - var(--frame-padding-block, 40px)
  );
}
.pb-cover-with-text .pb-cover-bg {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  z-index: 0;
}
.pb-cover-with-text .pb-cover-bg-video video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.pb-cover-with-text .pb-cover-overlay {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 1;
}
.pb-cover-with-text[data-overlay="light"]  .pb-cover-overlay { background: rgba(255,255,255,0.45); }
.pb-cover-with-text[data-overlay="dark"]   .pb-cover-overlay { background: rgba(0,0,0,0.35); }
.pb-cover-with-text[data-overlay="heavy"]  .pb-cover-overlay { background: rgba(0,0,0,0.6); }
.pb-cover-with-text[data-overlay="fade-bottom"] .pb-cover-overlay {
  background: linear-gradient(to bottom, rgba(0,0,0,0) 30%, rgba(0,0,0,0.7) 100%);
}
.pb-cover-with-text[data-overlay="fade-top"] .pb-cover-overlay {
  background: linear-gradient(to top, rgba(0,0,0,0) 30%, rgba(0,0,0,0.7) 100%);
}

/* Text content ------------------------------------------------ */
.pb-cover-with-text .pb-cover-text {
  position: relative;
  z-index: 2;
  /* margin:0 auto centers horizontally only; vertical alignment is
     driven by justify-content on the flex column (data-text-valign). */
  margin: 0 auto;
  padding: 2rem 1.5rem;
  width: 100%;
  box-sizing: border-box;
}

/* Width tiers (max-width of the inner text block) */
.pb-cover-with-text[data-text-width="narrow"] .pb-cover-text { max-width: 560px; }
.pb-cover-with-text[data-text-width="normal"] .pb-cover-text { max-width: 800px; }
.pb-cover-with-text[data-text-width="wide"]   .pb-cover-text { max-width: 1100px; }

/* Vertical anchor inside the section (flex on parent) */
.pb-cover-with-text[data-text-valign="top"]    { justify-content: flex-start; }
.pb-cover-with-text[data-text-valign="middle"] { justify-content: center; }
.pb-cover-with-text[data-text-valign="bottom"] { justify-content: flex-end; }

/* Horizontal alignment of the text content */
.pb-cover-with-text[data-text-align="left"]   .pb-cover-text { text-align: left; margin-left: 0; }
.pb-cover-with-text[data-text-align="center"] .pb-cover-text { text-align: center; }
.pb-cover-with-text[data-text-align="right"]  .pb-cover-text { text-align: right; margin-right: 0; }

/* Cover width tiers inside the pb-themed paper frame. `container` mode
   escapes the paper's inline padding via negative margins so the image
   touches the inner gold border; the paper itself doesn't move.
   `viewport` carries an inline FULL_BLEED in the SSR (no CSS needed). */
.pb-themed .pb-cover[data-width="container"],
.pb-themed .pb-cover-with-text[data-width="container"] {
  margin-left: calc(-1 * var(--frame-padding-inline, 32px));
  margin-right: calc(-1 * var(--frame-padding-inline, 32px));
  border-radius: 0;
  box-shadow: none;
}

/* Cover-as-hero default: when the cover (or cover-with-text) is the
   first child of `.pb-page`, escape the wrapper's max-width and render
   full-bleed. This matches the operator's mental model — a cover at the
   top of a venue/space page is the hero, not a constrained image inside
   the content column. Use the `outsideContainer:true` flag from the
   editor when you want a footer cover; the renderer separates those
   blocks into `.pb-themed-hero` siblings of `.pb-page` already. */
.pb-themed .pb-page > .pb-cover:first-child,
.pb-themed .pb-page > .pb-cover-with-text:first-child {
  width: 100vw;
  max-width: 100vw;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
}

/* Outside-container hero (sibling of the paper frame). Contains blocks
   marked `settings.outsideContainer: true`. The default `.pb-themed-hero`
   sits ABOVE the paper; `.pb-themed-hero-footer` sits BELOW. No max-width
   here — blocks decide their own width via `box.width`. */
.pb-themed > .pb-themed-hero {
  max-width: 100%;
  margin: 0 auto;
}
.pb-themed > .pb-themed-hero-footer {
  /* Generous breathing room before the footer outside-container block so
     the cream/page bg of the paper continues visibly before the footer's
     own bg (often dark) takes over. Mirrors the "tail of the paper"
     feeling the user sees in restaurapro's .rp-menu min-height pattern. */
  margin-top: clamp(80px, 12vh, 180px);
}
.pb-themed > .pb-themed-hero .pb-cover-with-text[data-height="100vh"] {
  /* Outside the paper, 100vh measures from the hero's top — only need
     to subtract the fixed-nav reservation (paper's frame-top-margin /
     padding don't apply here because we're a sibling, not a child). */
  min-height: calc(100vh - var(--shell-nav-offset, 0px));
}

/* Image-only cover (no text on top) — emit the same overlay tiers when
   the user picks a velo for mood / dimming. The renderer wraps the
   bg layer in a `.pb-cover[data-has-bg="1"][data-overlay=…]` div with
   a `.pb-cover-overlay` sibling sitting absolutely above the image. */
.pb-cover[data-has-bg="1"] .pb-cover-overlay {
    position: absolute;
    inset: 0;
    pointer-events: none;
    z-index: 1;
}
.pb-cover[data-has-bg="1"][data-overlay="light"]  .pb-cover-overlay { background: rgba(255,255,255,0.45); }
.pb-cover[data-has-bg="1"][data-overlay="dark"]   .pb-cover-overlay { background: rgba(0,0,0,0.35); }
.pb-cover[data-has-bg="1"][data-overlay="heavy"]  .pb-cover-overlay { background: rgba(0,0,0,0.6); }
.pb-cover[data-has-bg="1"][data-overlay="fade-bottom"] .pb-cover-overlay {
    background: linear-gradient(to bottom, rgba(0,0,0,0) 30%, rgba(0,0,0,0.7) 100%);
}
.pb-cover[data-has-bg="1"][data-overlay="fade-top"] .pb-cover-overlay {
    background: linear-gradient(to top, rgba(0,0,0,0) 30%, rgba(0,0,0,0.7) 100%);
}

/* Auto-invert text colors on dark/heavy overlays so titles stay legible.
   `.pb-themed` parent applies brand-dark colors via cascade, so we anchor
   these on the `.pb-themed` selector to win specificity and apply per
   data-overlay tier. */
.pb-themed .pb-cover-with-text[data-overlay="dark"],
.pb-themed .pb-cover-with-text[data-overlay="heavy"],
.pb-themed .pb-cover-with-text[data-overlay="fade-bottom"],
.pb-themed .pb-cover-with-text[data-overlay="fade-top"],
.pb-cover-with-text[data-overlay="dark"],
.pb-cover-with-text[data-overlay="heavy"],
.pb-cover-with-text[data-overlay="fade-bottom"],
.pb-cover-with-text[data-overlay="fade-top"] {
  --cover-eyebrow-color: rgba(255,255,255,0.92);
  --cover-title-color: #ffffff;
  --cover-subtitle-color: rgba(255,255,255,0.95);
  --cover-location-color: rgba(255,255,255,0.95);
  --cover-location-bg: rgba(0,0,0,0.3);
  --cover-cta-color: #ffffff;
}
/* Ensure the inner elements actually pick up the inverted vars (some
   themes set colors directly on `.pb-themed h1` etc., so we re-assert
   the var resolution at the leaf). */
.pb-themed .pb-cover-with-text[data-overlay="dark"] .pb-cover-body,
.pb-themed .pb-cover-with-text[data-overlay="heavy"] .pb-cover-body,
.pb-themed .pb-cover-with-text[data-overlay="fade-bottom"] .pb-cover-body,
.pb-themed .pb-cover-with-text[data-overlay="fade-top"] .pb-cover-body,
.pb-themed .pb-cover-with-text[data-overlay="dark"] .pb-cover-body *,
.pb-themed .pb-cover-with-text[data-overlay="heavy"] .pb-cover-body *,
.pb-themed .pb-cover-with-text[data-overlay="fade-bottom"] .pb-cover-body *,
.pb-themed .pb-cover-with-text[data-overlay="fade-top"] .pb-cover-body * {
  color: var(--cover-title-color);
}
.pb-themed .pb-cover-with-text[data-overlay="dark"] .pb-cover-eyebrow,
.pb-themed .pb-cover-with-text[data-overlay="heavy"] .pb-cover-eyebrow,
.pb-themed .pb-cover-with-text[data-overlay="fade-bottom"] .pb-cover-eyebrow,
.pb-themed .pb-cover-with-text[data-overlay="fade-top"] .pb-cover-eyebrow {
  color: var(--cover-eyebrow-color);
}
.pb-themed .pb-cover-with-text[data-overlay="dark"] .pb-cover-description,
.pb-themed .pb-cover-with-text[data-overlay="heavy"] .pb-cover-description,
.pb-themed .pb-cover-with-text[data-overlay="fade-bottom"] .pb-cover-description,
.pb-themed .pb-cover-with-text[data-overlay="fade-top"] .pb-cover-description {
  color: var(--cover-subtitle-color);
}

/* Eyebrow — small uppercase line above titles */
.pb-cover-with-text .pb-cover-eyebrow {
  font-size: var(--cover-eyebrow-size, 0.75rem);
  letter-spacing: var(--cover-eyebrow-tracking, 0.35em);
  text-transform: uppercase;
  color: var(--cover-eyebrow-color, var(--brand, inherit));
  font-weight: 500;
  margin-bottom: var(--cover-eyebrow-margin-bottom, 1.5rem);
}

/* Body — rich HTML emitted by the editor's RichEditor. Inherits the
   display font + size by default so a single line "Marco" looks like a
   hero title; users can override per-element with inline styles or via
   the rich-editor's bold/italic. Multiple lines (e.g. "Marco<br>&<br>
   Sonia") stack naturally because the body div is block-flow. */
.pb-cover-with-text .pb-cover-body {
  font-family: var(--cover-title-font, var(--font-display, var(--font-heading, Georgia, serif)));
  font-weight: 400;
  font-size: var(--cover-title-size, clamp(2.6rem, 8vw, 6rem));
  line-height: var(--cover-title-line-height, 1.1);
  color: var(--cover-title-color, var(--brand-dark, var(--brand, inherit)));
  margin: 0 0 1rem;
}
/* Reset rich-editor's inner block elements so they don't stack with
   default browser margins on top of the body's margin. */
.pb-cover-with-text .pb-cover-body p,
.pb-cover-with-text .pb-cover-body h1,
.pb-cover-with-text .pb-cover-body h2,
.pb-cover-with-text .pb-cover-body h3 {
  margin: 0;
  font: inherit;
  color: inherit;
}
.pb-cover-with-text .pb-cover-body a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 4px;
}

/* Description — small line below body (date / tagline / location) */
.pb-cover-with-text .pb-cover-description {
  font-size: var(--cover-subtitle-size, 0.95rem);
  letter-spacing: var(--cover-subtitle-tracking, 0.2em);
  text-transform: uppercase;
  color: var(--cover-subtitle-color, var(--ink, inherit));
  margin-top: 0.75rem;
}

/* CTA button */
.pb-cover-with-text .pb-cover-cta {
  display: inline-block;
  margin-top: 1.75rem;
  padding: 0.85em 1.7em;
  font: inherit;
  font-size: 0.85rem;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  text-decoration: none;
  border-radius: 999px;
  cursor: pointer;
  transition: transform 0.15s ease, background 0.15s ease, color 0.15s ease;
}
.pb-cover-with-text .pb-cover-cta-primary {
  background: var(--cover-cta-bg, var(--brand, #4a1419));
  color: var(--cover-cta-color, #fff);
  border: 1px solid var(--cover-cta-bg, var(--brand, #4a1419));
}
.pb-cover-with-text .pb-cover-cta-ghost {
  background: transparent;
  color: var(--cover-cta-color, currentColor);
  border: 1px solid currentColor;
}
.pb-cover-with-text .pb-cover-cta-link {
  background: transparent;
  color: var(--cover-cta-color, currentColor);
  border: none;
  padding: 0.5em 0;
  text-decoration: underline;
  text-underline-offset: 6px;
}
.pb-cover-with-text .pb-cover-cta:hover { transform: translateY(-1px); }

/* Mobile */
@media (max-width: 768px) {
  .pb-cover-with-text .pb-cover-text { padding: 1.5rem 1rem; }
}
