:root {
  --primary: #2563eb;
  --primary-ink: #ffffff;
  --ink: #16202c;
  --muted: #5b6b7b;
  --bg: #ffffff;
  --surface: #f7f8fa;
  --border: #e6eaf0;
  --radius: 12px;
  --container: 1080px;
}
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  font-family: var(--font-body, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif);
  font-size: var(--base-size, 16px);
  color: var(--ink);
  background: var(--bg);
  line-height: 1.6;
}
h1, h2, h3 { font-family: var(--font-heading, inherit); }
/* Form controls don't inherit fonts by default — keep the site font everywhere. */
button, input, select, textarea { font-family: inherit; }
a { color: var(--primary); text-decoration: none; }
img { max-width: 100%; height: auto; display: block; }
.container { max-width: var(--container); margin: 0 auto; padding: 0 24px; }

.site-header {
  /* Width/style are vars so the Template screen can turn the line off (0), make
     it thicker, or switch it to dashed/dotted/double. */
  border-bottom: var(--header-border-w, 1px) var(--header-border-style, solid) var(--header-border, var(--border));
  background: var(--header-bg, rgba(255,255,255,.85));
  backdrop-filter: blur(8px);
  z-index: 10;
}
.site-header[data-sticky="true"] { position: sticky; top: 0; }
.site-header--w-full .container, .site-footer--w-full .container { max-width: none; }
.site-header .inner { display: flex; align-items: center; gap: 20px; height: var(--header-height, 64px); }
.site-header .brand { font-weight: 700; font-size: 18px; letter-spacing: -.01em; color: var(--header-brand, var(--ink)); display: inline-flex; align-items: center; }
.site-header .brand-logo { height: var(--logo-h, 32px); width: auto; display: block; }
.site-nav { display: flex; flex-wrap: wrap; gap: 22px; }
.site-nav a { color: var(--nav-link, var(--muted)); font-size: 15px; }
.site-nav a:hover { color: var(--nav-hover, var(--ink)); }
/* Unscoped so the FOOTER menu can mark the current page too. Deliberately
   before the header's own rule, which is more specific and still wins. */
.site-nav a[aria-current="page"] { color: var(--nav-active, var(--nav-hover, var(--ink))); }
/* Header menu items: every part is a var, so an untouched header keeps the
   plain-text look and one setting is enough to turn the items into boxes.
   Scoped to the header — the columns footer reuses .site-nav. */
.site-header .site-nav { gap: var(--nav-gap, 22px); }
.site-header .site-nav a {
  display: inline-flex; align-items: center;
  font-size: var(--nav-fs, 15px);
  font-weight: var(--nav-fw, inherit);
  text-transform: var(--nav-tt, none);
  letter-spacing: var(--nav-ls, normal);
  padding: var(--nav-pad-y, 0) var(--nav-pad-x, 0);
  border-radius: var(--nav-radius, 0);
  background: var(--nav-bg, transparent);
  border: var(--nav-bw, 0) var(--nav-bs, solid) var(--nav-bc, transparent);
  transition: background .18s ease, border-color .18s ease, color .18s ease;
}
.site-header .site-nav a:hover {
  color: var(--nav-hover, var(--ink));
  background: var(--nav-bg-hover, var(--nav-bg, transparent));
  border-color: var(--nav-bc-hover, var(--nav-bc, transparent));
}
.site-header .site-nav a[aria-current="page"] {
  color: var(--nav-active, var(--nav-hover, var(--ink)));
  background: var(--nav-bg-active, var(--nav-bg, transparent));
  border-color: var(--nav-bc-active, var(--nav-bc, transparent));
}
.nav-ic { display: inline-flex; vertical-align: -0.15em; margin-right: 7px; }
.nav-ic svg { width: 1em; height: 1em; }
/* The menu icon can carry its own three states. Unset it inherits the link's
   colour — exactly what it did before there was anything to set. */
.site-header .site-nav a .nav-ic { color: var(--nav-ic, inherit); transition: color .18s ease; }
.site-header .site-nav a:hover .nav-ic { color: var(--nav-ic-hover, var(--nav-ic, inherit)); }
.site-header .site-nav a[aria-current="page"] .nav-ic { color: var(--nav-ic-active, var(--nav-ic-hover, var(--nav-ic, inherit))); }
.header-ctas { display: inline-flex; align-items: center; gap: 10px; }
.header-cta {
  display: inline-block; padding: 8px 16px; font-weight: 600; font-size: 14px;
  /* Follows the theme's button radius, like .btn does — 8px only when the
     theme has not set one. */
  border-radius: var(--theme-btn-radius, 8px);
  /* Per-button override → the theme's button colour → the theme's primary.
     Without the middle step, recolouring the theme's Primary button moved the
     block buttons (.btn) but left these on the bare primary colour. */
  --btn-fill: var(--btn-bg, var(--theme-btn-bg, var(--primary)));
  --btn-ink: var(--btn-text, var(--theme-btn-text, var(--primary-ink)));
  background: var(--btn-fill); color: var(--btn-ink);
  /* Do not transition background: a gradient fill is not interpolatable and
     flickers mid-transition; swap it instantly, fade only colour and shadow. */
  transition: color .15s ease, box-shadow .15s ease;
}
/* No hover colour set → keep the resting fill/ink (no colour flip). */
.header-cta:hover { background: var(--btn-hover-bg, var(--theme-btn-hbg, var(--btn-fill))); color: var(--btn-hover-text, var(--theme-btn-htext, var(--btn-ink))); }
.header-cta.header-cta--outline { --btn-fill: transparent; --btn-ink: var(--btn-text, var(--btn-line, var(--primary))); box-shadow: inset 0 0 0 1.5px var(--btn-line, var(--primary)); }
.header-cta.header-cta--outline:hover { background: var(--btn-hover-bg, var(--btn-line, var(--primary))); color: var(--btn-hover-text, #fff); }
.header-cta.header-cta--secondary { --btn-fill: var(--btn-bg, rgba(0,0,0,.06)); --btn-ink: var(--btn-text, var(--ink)); }
/* Optional icon / stacked layout / full-height / fixed-width header buttons */
.header-cta { display: inline-flex; align-items: center; justify-content: center; gap: 7px; text-align: center; }
.hbtn-ic { display: inline-flex; }
.hbtn-ic svg { width: 1.1em; height: 1.1em; }
.header-cta--icon-top { flex-direction: column; gap: 3px; }
.header-cta--icon-top .hbtn-ic svg { width: 1.4em; height: 1.4em; }
.header-cta--v-top { align-self: flex-start; }
.header-cta--v-bottom { align-self: flex-end; }
.center-top { align-items: stretch; }
.center-top .brand { align-self: center; }
.center-slot { align-items: center; }
.header-ctas { align-self: stretch; align-items: center; }

/* Mobile nav (≤768px) */
.nav-toggle { display: none; background: none; border: 0; padding: 8px; margin-left: auto; cursor: pointer; align-items: center; gap: 7px; }
/* The gap follows the bar's thickness (2px bars, 4px apart by default), and
   the cross the bars fold into follows the gap — so one number resizes the
   whole thing and the open state still meets in the middle. */
.nav-toggle-bars { display: grid; gap: calc(var(--burger-h, 2px) * 2); }
.nav-toggle-bars span { display: block; width: var(--burger-w, 20px); height: var(--burger-h, 2px); border-radius: 2px; background: var(--mnav-icon, var(--nav-link, var(--ink))); transition: transform .25s ease, opacity .2s ease; }
.nav-toggle.open .nav-toggle-bars span:nth-child(1) { transform: translateY(calc(var(--burger-h, 2px) * 3)) rotate(45deg); }
.nav-toggle.open .nav-toggle-bars span:nth-child(2) { opacity: 0; }
.nav-toggle.open .nav-toggle-bars span:nth-child(3) { transform: translateY(calc(var(--burger-h, 2px) * -3)) rotate(-45deg); }
.nav-toggle-label { font-size: 13px; font-weight: 600; color: var(--mnav-icon, var(--nav-link, var(--ink))); }
.mobile-nav, .mobile-nav-backdrop, .mobile-nav-close { display: none; }
body.nav-lock { overflow: hidden; }

/* Header variants */
.site-header--logo-left-menu-right .inner { justify-content: space-between; }
.site-header--logo-left-menu-center-cta .site-nav { margin: 0 auto; }
.site-header--logo-center .inner { flex-direction: column; justify-content: center; gap: 12px; height: auto; padding: 16px 0; }
.site-header--logo-center .site-nav { justify-content: center; }
.center-top { display: flex; align-items: center; width: 100%; }
.center-top .brand { flex: 0 0 auto; }
.center-slot { flex: 1 1 0; display: flex; align-items: center; }
.center-slot--left { justify-content: flex-start; }
.center-slot--right { justify-content: flex-end; }
/* Menu split either side of a centered logo. The minmax(0,1fr) grid is what pins
   the logo to the page's centre line: a flex row would let the heavier half
   shove it off centre, and the halves are rarely even — the right one also
   carries the buttons. The 0 floor keeps the two tracks equal even when a side
   runs out of room, so the logo never drifts; the side wraps instead, and the
   bar grows to hold it rather than clipping what spilled. */
.site-header--logo-center-menu-split .inner {
  display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  height: auto; min-height: var(--header-height, 64px);
}
.site-header--logo-center-menu-split .brand { justify-self: center; }
/* A tighter gap than the bar's own: it is all that separates the menu from the
   buttons beside it, and those two are what run out of room first. */
.split-side { display: flex; align-items: center; gap: 12px; min-width: 0; }
/* Both halves align inwards, so the menu reads as one run around the logo... */
.split-side--left { justify-content: flex-end; }
.split-side--right { justify-content: flex-start; }
/* ...while the buttons leave it and sit out at the bar's right edge. */
.split-side--right .header-ctas { margin-left: auto; }

/* Page loading indicator */
.page-loader {
  position: fixed; inset: 0; z-index: 999; display: flex; flex-direction: column; gap: 22px;
  align-items: center; justify-content: center; transition: opacity .4s ease;
}
/* The fill lives in ::before so its opacity never fades the indicator itself. */
.page-loader::before {
  content: ""; position: absolute; inset: 0;
  background: var(--loader-bg, var(--bg)); opacity: var(--loader-bg-opacity, 1);
}
.page-loader > * { position: relative; z-index: 1; }
.page-loader.done { opacity: 0; pointer-events: none; }
/* Companion indicators for the logo/icon variants */
.loader-media { position: relative; width: fit-content; display: grid; place-items: center; }
.loader-media--ring { aspect-ratio: 1; padding: 18px; }
.loader-ring {
  position: absolute; inset: 0; border-radius: 999px;
  border: 3px solid color-mix(in srgb, var(--loader-accent, var(--primary)) 20%, transparent);
  border-top-color: var(--loader-accent, var(--primary));
  animation: loader-spin .9s linear infinite;
}
.loader-spinner--sm { width: 30px; height: 30px; border-width: 3px; }
.loader-dots--sm span { width: 9px; height: 9px; }
.loader-minibar { position: relative; width: 150px; height: 4px; border-radius: 999px; overflow: hidden; background: color-mix(in srgb, var(--loader-accent, var(--primary)) 18%, transparent); }
.loader-minibar::before { content: ""; position: absolute; left: -40%; width: 40%; height: 100%; border-radius: 999px; background: var(--loader-accent, var(--primary)); animation: loader-mini 1.1s ease-in-out infinite; }
@keyframes loader-mini { to { left: 100%; } }
.loader-spinner {
  width: 46px; height: 46px; border-radius: 999px;
  border: 4px solid color-mix(in srgb, var(--loader-accent, var(--primary)) 20%, transparent);
  border-top-color: var(--loader-accent, var(--primary));
  animation: loader-spin .8s linear infinite;
}
@keyframes loader-spin { to { transform: rotate(360deg); } }
.loader-dots { display: flex; gap: 10px; }
.loader-dots span { width: 12px; height: 12px; border-radius: 999px; background: var(--loader-accent, var(--primary)); animation: loader-bounce 1s ease-in-out infinite; }
.loader-dots span:nth-child(2) { animation-delay: .15s; }
.loader-dots span:nth-child(3) { animation-delay: .3s; }
@keyframes loader-bounce { 0%,100% { transform: translateY(0); opacity: .45; } 50% { transform: translateY(-10px); opacity: 1; } }
.loader-logo { height: 56px; width: auto; animation: loader-pulse 1.2s ease-in-out infinite; }
.loader-icon { height: 64px; width: 64px; object-fit: contain; border-radius: 14px; animation: loader-pulse 1.2s ease-in-out infinite; }
.loader-brand { font-size: 26px; font-weight: 800; color: var(--loader-accent, var(--primary)); animation: loader-pulse 1.2s ease-in-out infinite; }
@keyframes loader-pulse { 0%,100% { opacity: .45; transform: scale(.96); } 50% { opacity: 1; transform: scale(1); } }
/* Bar variant: slim indeterminate bar at the very top; page stays visible. */
.page-loader-bar { position: fixed; top: 0; left: 0; right: 0; height: 3px; z-index: 999; overflow: hidden; transition: opacity .3s ease; }
.page-loader-bar.done { opacity: 0; pointer-events: none; }
.page-loader-bar .bar-inner { height: 100%; width: 35%; background: var(--loader-accent, var(--primary)); border-radius: 3px; animation: loader-bar 1.1s ease-in-out infinite; }
@keyframes loader-bar { 0% { margin-left: -35%; } 100% { margin-left: 100%; } }

/* Floating contact buttons + back-to-top */
.float-stack { position: fixed; right: 18px; bottom: 18px; z-index: 60; display: flex; flex-direction: column; gap: 10px; }
.float-stack--left { right: auto; left: 18px; }
/* ---- Sidebar rail ---- */
.site-sidebar { position: fixed; top: var(--sb-top, 64px); bottom: 0; left: 0; width: var(--sb-w, 96px); z-index: 8; overflow-y: auto; background: var(--sb-bg, var(--surface)); border-right: 1px solid var(--sb-border, var(--border)); padding: 12px 8px; display: flex; flex-direction: column; }
.sb-btns { display: flex; flex-direction: column; gap: 8px; margin-top: 14px; }
.sb-btns--bottom { margin-top: auto; position: sticky; bottom: -12px; padding: 10px 0 12px; background: var(--sb-bg, var(--surface)); border-top: 1px solid var(--sb-border, var(--border)); }
.sb-btn { width: 100%; padding: 9px 6px; border-radius: 9px; font-size: 12.5px; display: inline-flex; align-items: center; justify-content: center; gap: 6px; }
.site-sidebar--right { left: auto; right: 0; border-right: 0; border-left: 1px solid var(--sb-border, var(--border)); }
.sb-links { display: flex; flex-direction: column; gap: 4px; }
.sb-link { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 12px 4px; border-radius: 10px; color: var(--sb-text, var(--nav-link, var(--muted))); font-size: 12px; font-weight: 600; text-align: center; text-decoration: none; }
/* Three states, each its own text / icon / panel. Every one falls back to the
   state before it, so setting only "default" still looks deliberate and a
   sidebar nobody has coloured behaves exactly as it always did. */
.sb-link { background: var(--sb-item-bg, transparent); transition: background .18s ease, color .18s ease; }
.sb-link:hover { color: var(--sb-hover, var(--ink)); background: var(--sb-item-bg-hover, rgba(127,127,127,.12)); }
.sb-link[aria-current="page"] { color: var(--sb-active, var(--sb-hover, var(--ink))); background: var(--sb-item-bg-active, var(--sb-item-bg-hover, rgba(127,127,127,.12))); }
.sb-ic { display: inline-flex; color: var(--sb-icon, var(--primary)); transition: color .18s ease; }
.sb-link:hover .sb-ic { color: var(--sb-icon-hover, var(--sb-icon, var(--primary))); }
.sb-link[aria-current="page"] .sb-ic { color: var(--sb-icon-active, var(--sb-icon-hover, var(--sb-icon, var(--primary)))); }
.sb-ic svg { width: 22px; height: 22px; }
body.has-sb--left { padding-left: var(--sb-w, 96px); }
body.has-sb--right { padding-right: var(--sb-w, 96px); }
/* Header + announcement bar span the full viewport — the rail only claims the
 * area below the header, so they break out of the body's side padding. */
body.has-sb--left .site-header, body.has-sb--left .announce-bar { margin-left: calc(var(--sb-w, 96px) * -1); }
body.has-sb--right .site-header, body.has-sb--right .announce-bar { margin-right: calc(var(--sb-w, 96px) * -1); }
.float-btn { display: flex; align-items: center; justify-content: center; width: 46px; height: 46px; border-radius: 999px; color: #fff; border: 0; cursor: pointer; box-shadow: 0 10px 24px rgba(0,0,0,.28); transition: transform .15s ease; }
.float-btn:hover { transform: translateY(-2px); }
.float-btn svg { width: 22px; height: 22px; }
.back-top { background: var(--surface); color: var(--ink); border: 1px solid var(--border); opacity: 0; pointer-events: none; transition: opacity .2s ease, transform .15s ease; }
.back-top.show { opacity: 1; pointer-events: auto; }

/* Announcement bar (above the header) */
.announce-bar { background: var(--primary); color: var(--primary-ink); font-size: 13px; }
.announce-inner { display: flex; align-items: center; justify-content: center; gap: 10px; padding-top: 7px; padding-bottom: 7px; flex-wrap: wrap; text-align: center; }
.announce-link { color: inherit; font-weight: 700; text-decoration: underline; text-underline-offset: 2px; }

.site-footer { border-top: 1px solid var(--footer-border, var(--border)); color: var(--footer-color, var(--muted)); background: var(--footer-bg, transparent); font-size: 14px; }
.site-footer .inner { padding: var(--footer-pad, 28px) 0; display: flex; flex-direction: column; gap: 12px; align-items: center; }
.site-footer .footer-copy { color: var(--footer-color, var(--muted)); }

/* Rich footer (brand + columns + payments + bottom bar) */
.site-footer--rich { padding: var(--footer-pad, 48px) 0 0; }
/* auto-fit can't be combined with an fr track (invalid CSS, the whole rule is
   dropped) — the renderer passes the real column count instead. */
.footer-grid { display: grid; grid-template-columns: 1.4fr repeat(var(--footer-cols, 3), minmax(0, 1fr)); gap: 36px; padding-bottom: 32px; }
.footer-grid--no-cols { grid-template-columns: 1fr; }
.footer-logo { height: 40px; width: auto; }
.footer-name { font-weight: 700; font-size: 18px; color: var(--ink); }
.footer-desc { margin: 12px 0 0; font-size: 13px; line-height: 1.6; max-width: 320px; }
.footer-socials { display: flex; gap: 10px; margin-top: 16px; }
.footer-social { display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; border-radius: 999px; border: 1px solid var(--footer-border, var(--border)); color: var(--footer-social, var(--footer-color, var(--muted))); transition: color .15s ease, border-color .15s ease; }
.footer-social:hover { color: var(--footer-social-hover, var(--primary)); border-color: var(--footer-social-hover, var(--primary)); }
.footer-social svg { width: 15px; height: 15px; }
.footer-col-title {
  display: flex; align-items: center; justify-content: space-between; gap: 8px; width: 100%;
  background: none; border: 0; padding: 0; text-align: left; cursor: default;
  font-weight: 700; font-size: 14px; color: var(--footer-col-title, var(--footer-heading, var(--ink))); margin-bottom: 12px;
}
.footer-col-title .fc-chev { width: 16px; height: 16px; display: none; transition: transform .25s ease; }
.footer-col-links { display: grid; gap: 8px; }
.footer-col-links a { color: var(--footer-col-link, var(--nav-link, var(--muted))); font-size: 13px; }
.footer-col-links a:hover { color: var(--footer-col-hover, var(--nav-hover, var(--ink))); }
.footer-col-links a[aria-current="page"] { color: var(--footer-col-active, var(--footer-col-hover, var(--nav-hover, var(--ink)))); }
.footer-payments { border-top: 1px solid var(--footer-border, var(--border)); padding: 20px 0; display: flex; flex-direction: column; gap: 12px; }
.footer-payments-title { font-size: 12px; }
.footer-payments-row { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; }
.footer-payment { height: 26px; width: auto; border-radius: 999px; }
.footer-responsible { border-top: 1px solid var(--footer-border, var(--border)); padding: 20px 0; display: flex; flex-direction: column; gap: 12px; }
.footer-responsible-title { font-size: 12px; }
.footer-responsible-row { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; }
.footer-responsible-logo { height: 26px; width: auto; }
/* The bottom-bar note, with its optional icon sitting on the text baseline. */
.footer-note { display: inline-flex; align-items: center; gap: 6px; }
.footer-note-ic { display: inline-flex; flex: none; }
.footer-note-ic svg { width: 18px; height: 18px; }
/* Icon on the right: reverse the row rather than move it in the markup, so the
   text still comes first for a screen reader. */
.footer-note--ic-right { flex-direction: row-reverse; }

/* --- The two footer logo rows: alignment, size and treatment, chosen per site
   in Template → Footer. Both rows share these so they behave identically. --- */
.frow--left { justify-content: flex-start; }
.frow--center { justify-content: center; }
.frow--right { justify-content: flex-end; }
.ftitle--left { text-align: left; }
.ftitle--center { text-align: center; }
.ftitle--right { text-align: right; }
.fimg--sm { height: 20px; }
.fimg--md { height: 26px; }
.fimg--lg { height: 34px; }
/* content-box keeps the logo itself at the chosen height while the tile grows. */
.fimg--card {
  box-sizing: content-box; padding: 5px 9px; border-radius: 10px;
  background: var(--footer-logo-tile, rgba(255, 255, 255, .07));
  border: 1px solid var(--footer-border, var(--border));
}
.fimg--mono { filter: grayscale(1); opacity: .68; transition: filter .2s ease, opacity .2s ease; }
.fimg--mono:hover { filter: none; opacity: 1; }
.footer-bottom { border-top: 1px solid var(--footer-border, var(--border)); padding: 16px 0; display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; font-size: 12px; }
@media (max-width: 768px) {

  /* --- Header: desktop nav hides; hamburger shows --- */
  .site-nav, .site-header .header-ctas { display: none; }
  .nav-toggle { display: flex; }
  .site-header--logo-center .inner { flex-direction: row; justify-content: flex-start; gap: 12px; height: var(--header-height, 60px); padding: 0; }
  /* The split header folds back to a plain bar: display:contents dissolves the
     two wrappers so the brand, the (kept) buttons and the toggle lay themselves
     out exactly like every other variant's. */
  .site-header--logo-center-menu-split .inner { display: flex; gap: 12px; }
  .site-header--logo-center-menu-split .split-side { display: contents; }
  .site-header--logo-center-menu-split .header-ctas { margin-left: 0; }

  .mobile-nav { display: block; }
  .mobile-nav-links { display: grid; }
  .mobile-nav-links a { padding: 13px 24px; font-size: var(--mnav-fs, 15px); font-weight: var(--mnav-fw); text-transform: var(--mnav-tt, none); color: var(--mnav-text, var(--nav-link, var(--ink))); background: var(--mnav-item-bg, transparent); border-bottom: 1px solid var(--mnav-border, var(--header-border, var(--border))); }
  .mobile-nav-links a:hover, .mobile-nav-links a:active { color: var(--mnav-text-hover, var(--mnav-text, var(--nav-hover, var(--ink)))); background: var(--mnav-item-bg-hover, var(--mnav-item-bg, transparent)); }
  /* The page being viewed (Template → Mobile menu → Menu style → Current page).
     Unset, it looks like any other link — as it always did. */
  .mobile-nav-links a[aria-current="page"] { color: var(--mnav-text-active, var(--mnav-text, var(--nav-link, var(--ink)))); background: var(--mnav-item-bg-active, var(--mnav-item-bg, transparent)); }
  .mobile-nav-links a .nav-ic { color: var(--mnav-ic, inherit); }
  .mobile-nav-links a:hover .nav-ic { color: var(--mnav-ic-hover, var(--mnav-ic, inherit)); }
  .mobile-nav-links a[aria-current="page"] .nav-ic { color: var(--mnav-ic-active, var(--mnav-ic, inherit)); }
  /* The panel's side inset — the boxed links and the buttons beneath them read
     the same one, so they line up however the menu is styled. */
  .mobile-nav { --mnav-pad-x: 24px; }
  .mobile-nav-ctas { display: grid; gap: 10px; padding: 16px var(--mnav-pad-x) 20px; }
  .mobile-nav-ctas .header-cta { text-align: center; }

  /* Slide-down: expands beneath the header */
  .mobile-nav--dropdown { max-height: 0; overflow: hidden; transition: max-height .3s ease; background: var(--mnav-bg, var(--header-bg, var(--bg))); backdrop-filter: blur(8px); }
  .mobile-nav--dropdown.open { max-height: 80vh; overflow-y: auto; }

  /* Drawer: slides in from the right over a backdrop */
  .mobile-nav--drawer { position: fixed; top: 0; right: 0; bottom: 0; z-index: 120; width: min(78vw, 320px); background: var(--mnav-bg, var(--bg)); transform: translateX(100%); transition: transform .28s ease; overflow-y: auto; padding-top: 52px; box-shadow: -18px 0 50px rgba(0,0,0,.25); }
  .mobile-nav--drawer.open { transform: none; }

  /* Fullscreen overlay */
  .mobile-nav--fullscreen { position: fixed; inset: 0; z-index: 120; background: var(--mnav-bg, var(--bg)); opacity: 0; pointer-events: none; transition: opacity .25s ease; display: flex; flex-direction: column; justify-content: center; }
  .mobile-nav--fullscreen.open { opacity: 1; pointer-events: auto; }
  .mobile-nav--fullscreen .mobile-nav-links a { border: 0; text-align: center; font-size: var(--mnav-fs, 20px); font-weight: var(--mnav-fw, 600); padding: 14px 24px; }
  .mobile-nav--fullscreen { --mnav-pad-x: 40px; }
  .mobile-nav--fullscreen .mobile-nav-ctas { padding: 22px var(--mnav-pad-x); }

  /* Layout options (Template → Mobile menu): two columns, the icon above the
     label, and alignment — which, left unset, stays the style's own. */
  .mobile-nav--cols-2 .mobile-nav-links { grid-template-columns: 1fr 1fr; }
  .mobile-nav--cols-2 .mobile-nav-links a { padding-left: 16px; padding-right: 16px; }
  .mobile-nav--cols-2:not(.mobile-nav--fullscreen):not(.mobile-nav--boxes) .mobile-nav-links a:nth-child(odd) { border-right: 1px solid var(--mnav-border, var(--header-border, var(--border))); }
  .mobile-nav--icon-top .mobile-nav-links a { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; }
  .mobile-nav--icon-top .mobile-nav-links .nav-ic { margin-right: 0; font-size: 1.4em; }
  .mobile-nav--align-left .mobile-nav-links a { text-align: left; }
  .mobile-nav--align-center .mobile-nav-links a { text-align: center; }
  .mobile-nav--icon-top.mobile-nav--align-center .mobile-nav-links a,
  .mobile-nav--fullscreen.mobile-nav--icon-top:not(.mobile-nav--align-left) .mobile-nav-links a { align-items: center; }

  /* Boxes (Menu style → Shape): each link its own box — a gap between, its own
     corners and border per state — instead of rows split by lines. */
  .mobile-nav--boxes .mobile-nav-links { gap: var(--mnav-gap, 8px); padding: 12px var(--mnav-pad-x); }
  .mobile-nav--boxes .mobile-nav-links a { border: var(--mnav-bw, 0px) var(--mnav-bs, solid) var(--mnav-bc, transparent); border-radius: var(--mnav-radius, 10px); padding: 12px 16px; }
  .mobile-nav--boxes .mobile-nav-links a:hover { border-color: var(--mnav-bc-hover, var(--mnav-bc, transparent)); }
  .mobile-nav--boxes .mobile-nav-links a[aria-current="page"] { border-color: var(--mnav-bc-active, var(--mnav-bc, transparent)); }

  .mobile-nav-backdrop { display: block; position: fixed; inset: 0; z-index: 110; background: rgba(0,0,0,.5); opacity: 0; pointer-events: none; transition: opacity .25s ease; }
  .mobile-nav-backdrop.show { opacity: 1; pointer-events: auto; }
  .mobile-nav-close { display: flex; position: absolute; top: 10px; right: 12px; z-index: 1; align-items: center; justify-content: center; width: var(--mnav-close, 36px); height: var(--mnav-close, 36px); border: 0; border-radius: 999px; background: transparent; color: var(--mnav-text, var(--nav-link, var(--ink))); font-size: calc(var(--mnav-close, 36px) / 2); cursor: pointer; }

  /* Site logo repeated at the top of an overlay menu (drawer/fullscreen) */
  .mobile-nav-brand { display: flex; align-items: center; gap: 8px; min-height: 52px; padding: 8px 56px 8px 24px; font-size: 17px; font-weight: 700; color: var(--mnav-text, var(--nav-link, var(--ink))); border-bottom: 1px solid var(--mnav-border, var(--header-border, var(--border))); }
  .mobile-nav-brand img { height: var(--logo-h, 32px); width: auto; max-width: 100%; display: block; }
  .mobile-nav--drawer.mobile-nav--brand { padding-top: 0; }
  .mobile-nav--fullscreen .mobile-nav-brand { position: absolute; top: 0; left: 0; right: 0; justify-content: center; padding: 8px 56px; }

  /* The footer's text repeated at the bottom of an overlay menu */
  .mobile-nav-note { margin: 0; padding: 14px 24px 20px; font-size: 12px; line-height: 1.5; text-align: center; color: var(--mnav-text, var(--nav-link, var(--ink))); opacity: .7; }
  .mobile-nav--drawer .mobile-nav-note { border-top: 1px solid var(--mnav-border, var(--header-border, var(--border))); margin-top: 8px; }
  .mobile-nav--fullscreen .mobile-nav-note { position: absolute; left: 0; right: 0; bottom: 0; }


  /* --- Footer mobile layouts --- */
  .footer-grid { grid-template-columns: 1fr 1fr; gap: 24px; }
  .footer-brand { grid-column: 1 / -1; }
  .footer-desc { max-width: none; }

  .site-footer--m-stacked .footer-grid { grid-template-columns: 1fr; }

  .site-footer--m-compact .footer-col { display: none; }
  .site-footer--m-compact .footer-grid { grid-template-columns: 1fr; padding-bottom: 8px; }

  .site-footer--m-accordion .footer-grid { grid-template-columns: 1fr; gap: 0; padding-bottom: 20px; }
  .site-footer--m-accordion .footer-col { border-top: 1px solid var(--footer-border, var(--border)); }
  .site-footer--m-accordion .footer-col-title { margin: 0; padding: 14px 0; cursor: pointer; }
  .site-footer--m-accordion .footer-col-title .fc-chev { display: block; }
  .site-footer--m-accordion .footer-col.open .footer-col-title .fc-chev { transform: rotate(180deg); }
  .site-footer--m-accordion .footer-col-links { max-height: 0; overflow: hidden; transition: max-height .3s ease; }
  .site-footer--m-accordion .footer-col.open .footer-col-links { max-height: 420px; padding-bottom: 14px; }
  .site-footer--m-accordion .footer-brand { padding-bottom: 20px; }

  .footer-bottom { justify-content: center; text-align: center; }
}

@media (max-width: 768px) {
  .container { padding: 0 12px; }
}
/* Footer variants */
.site-footer--columns .inner { align-items: flex-start; }
.site-footer--columns .site-nav { display: block; columns: 3; column-gap: 40px; width: 100%; }
.site-footer--columns .site-nav a { display: block; margin-bottom: 8px; }
.site-footer--minimal .inner { padding: 18px 0; }

.btn {
  display: inline-block; padding: 12px 22px; border-radius: var(--theme-btn-radius, 10px);
  background: var(--theme-btn-bg, var(--primary)); color: var(--theme-btn-text, var(--primary-ink)); font-weight: 600;
}
.btn .btn-ic { display: inline-flex; align-items: center; margin-right: 8px; vertical-align: -0.18em; }
.btn .btn-ic svg { width: 1.1em; height: 1.1em; }
.btn:hover {
  filter: brightness(.97);
  background: var(--theme-btn-hbg, var(--theme-btn-bg, var(--primary)));
  color: var(--theme-btn-htext, var(--theme-btn-text, var(--primary-ink)));
}
.btn--secondary { background: rgba(0,0,0,.06); color: var(--ink); }
.btn--outline { background: transparent; color: var(--primary); box-shadow: inset 0 0 0 1.5px var(--primary); }
.cta-buttons { display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; }
.cta-buttons .btn { transition: color .15s ease, box-shadow .15s ease; }
/* Per-button hover (only when a hover colour is set); others keep the default. */
.cta-buttons .btn[data-hover]:hover { background: var(--cbtn-hbg, var(--primary)); color: var(--cbtn-htext, var(--primary-ink)); filter: none; }

/* Single image */
.block--single-image figure { margin: 0; }
.block--single-image .single-image { width: 100%; border-radius: var(--img-radius, 12px); }
/* Image corner radius set apart for phones (Style → Image). The desktop value
   rides as an inline custom property on the wrapper, and inline beats any rule
   — so the phone's value goes on the images themselves, not on the variable. */
@media (max-width: 768px) {
  .block-design[data-img-m] .single-image,
  .block-design[data-img-m] .video-frame,
  .block-design[data-img-m] .slide-img,
  .block-design[data-img-m] .rank-card--none,
  .block-design[data-img-m] .block--hero img,
  .block-design[data-img-m] .split__media img,
  .block-design[data-img-m] .gallery-item img,
  .block-design[data-img-m] .gallery-scrim {
    border-radius: var(--img-radius-m);
  }
}
.block--single-image figcaption { text-align: center; color: var(--muted); font-size: 14px; margin-top: 8px; }

/* Video (Single video / Video + text). The frame owns the shape so a file, an
   embed and the cover image are interchangeable inside it — the player is
   absolutely positioned, and the ratio holds the space before it loads, so
   nothing on the page moves when it does. */
.video-frame {
  position: relative; width: 100%; overflow: hidden;
  aspect-ratio: var(--video-ratio, 16 / 9);
  border-radius: var(--img-radius, 12px);
  background: #000;
}
.video-frame > video, .video-frame > iframe, .video-frame > .video-facade {
  position: absolute; inset: 0; width: 100%; height: 100%; border: 0; display: block;
}
/* contain, not cover: the frame ratio is the operator's choice and the
   video's is the file's — cropping the picture to fit is never the right
   answer, letterboxing it is. Identical when the two agree. */
.video-frame > video { object-fit: contain; background: #000; }
.block--single-video figure { margin: 0; }
.block--single-video figcaption { text-align: center; color: var(--muted); font-size: 14px; margin-top: 8px; }
/* Cover image standing in for an embed until it is clicked. */
.video-facade {
  padding: 0; cursor: pointer; background-color: #000;
  background-size: cover; background-position: 50% 50%; background-repeat: no-repeat;
}
/* It is an <a>, so the theme's link colour would otherwise underline it. */
.video-facade, .video-facade:hover { text-decoration: none; }
.video-facade::after {
  content: ""; position: absolute; inset: 0;
  background: rgba(0,0,0,.28); transition: background .2s ease;
}
.video-facade:hover::after { background: rgba(0,0,0,.14); }
.video-play {
  position: absolute; top: 50%; left: 50%; z-index: 1;
  width: 68px; height: 48px; margin: -24px 0 0 -34px;
  border-radius: 12px; background: rgba(0,0,0,.65);
  transition: background .2s ease, transform .2s ease;
}
/* The triangle is drawn from borders — no asset, no icon dependency. */
.video-play::before {
  content: ""; position: absolute; top: 50%; left: 50%;
  margin: -9px 0 0 -6px; border-style: solid;
  border-width: 9px 0 9px 15px; border-color: transparent transparent transparent #fff;
}
.video-facade:hover .video-play { background: var(--primary); transform: scale(1.06); }
.block--videotext .split__media { min-width: 0; }

/* Block design (generic per-block Style: width, background image, padding) */
.block-design[data-width="full"] .container { max-width: none; }

/* --- Section shape (Style → Section shape) ---------------------------------
   The edge is eaten out of the block by a piece painted in the page's own
   colour, so the top and bottom answer on their own and any two blocks can
   meet along a slant, a curve or a notch. Nothing is drawn unless asked for. */
.block-design[data-sep-top], .block-design[data-sep-bottom] { position: relative; overflow: hidden; }
.block-design[data-sep-top]::before,
.block-design[data-sep-bottom]::after {
  content: ""; position: absolute; left: -1px; right: -1px; height: var(--sep-h, 48px);
  background: var(--bg); pointer-events: none; z-index: 1;
}
.block-design[data-sep-top]::before { top: 0; }
.block-design[data-sep-bottom]::after { bottom: 0; }
/* Slant — a straight cut, mirrored on the other edge so a stack reads as one line. */
.block-design[data-sep-top="slant"]::before { clip-path: polygon(0 0, 100% 0, 100% 0, 0 100%); }
.block-design[data-sep-bottom="slant"]::after { clip-path: polygon(0 100%, 100% 100%, 100% 100%, 0 0); }
.block-design[data-sep-top="slant-rev"]::before { clip-path: polygon(0 0, 100% 0, 100% 100%, 0 0); }
.block-design[data-sep-bottom="slant-rev"]::after { clip-path: polygon(0 100%, 100% 100%, 100% 0, 0 100%); }
/* Curve — the block's edge bows away from the section before it. */
.block-design[data-sep-top="curve"]::before { border-radius: 0 0 50% 50% / 0 0 100% 100%; }
.block-design[data-sep-bottom="curve"]::after { border-radius: 50% 50% 0 0 / 100% 100% 0 0; }
/* Arch — the opposite bow: the block rises into the section before it. */
.block-design[data-sep-top="arch"]::before { clip-path: ellipse(75% 100% at 50% 0); }
.block-design[data-sep-bottom="arch"]::after { clip-path: ellipse(75% 100% at 50% 100%); }
/* Notch — a wedge cut out of the middle of the edge. */
.block-design[data-sep-top="notch"]::before { clip-path: polygon(0 0, 42% 0, 50% 100%, 58% 0, 100% 0); }
.block-design[data-sep-bottom="notch"]::after { clip-path: polygon(0 100%, 42% 100%, 50% 0, 58% 100%, 100% 100%); }
/* Chevron — the whole edge points into the block. */
.block-design[data-sep-top="chevron"]::before { clip-path: polygon(0 0, 100% 0, 100% 0, 50% 100%, 0 0); }
.block-design[data-sep-bottom="chevron"]::after { clip-path: polygon(0 100%, 50% 0, 100% 100%, 100% 100%, 0 100%); }
/* The shape sits over the block's own padding, so give the content room. */
.block-design[data-sep-top] > .block { padding-top: calc(var(--pt, 48px) + var(--sep-h, 48px) * .6); }
.block-design[data-sep-bottom] > .block { padding-bottom: calc(var(--pb, 48px) + var(--sep-h, 48px) * .6); }

/* --- Section header (Style → Heading) --------------------------------------
   A small line above the heading, which way the pair lines up, and a mark
   under the heading — the three things that make one site's sections read
   differently from another's, without touching a single block's markup. */
.block-design[data-eyebrow] > .block > .container::before {
  content: var(--eyebrow, ""); display: block; margin-bottom: 10px;
  font-size: 12px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
  color: var(--primary);
}
/* Blocks that centre their own heading take the eyebrow with them; an explicit
   alignment below still wins. */
.block-design[data-eyebrow] > :is(.block--hero, .block--features, .block--faq, .block--gallery, .block--steps, .block--cards, .block--logo-strip, .block--images-slide, .block--txfeed, .block--ranking) > .container::before { text-align: center; }
.block-design[data-head-align="left"] > .block > .container::before { text-align: left; }
.block-design[data-head-align="center"] > .block > .container::before { text-align: center; }
.block-design[data-head-align="right"] > .block > .container::before { text-align: right; }
/* Alignment reaches the heading pair of every block, whatever it calls them. */
.block-design[data-head-align] :is(h1, h2, .cards-heading, .steps-heading, .rank-bar-title),
.block-design[data-head-align] :is(.block-sub, .cards-sub, .steps-sub, .gallery-sub) {
  text-align: var(--head-align);
}
.block-design[data-head-align="left"] { --head-align: left; }
.block-design[data-head-align="center"] { --head-align: center; }
.block-design[data-head-align="right"] { --head-align: right; }
.block-design[data-head-align="center"] :is(.block-sub, .cards-sub, .steps-sub, .gallery-sub) { margin-left: auto; margin-right: auto; }
.block-design[data-head-align="left"] :is(.block-sub, .cards-sub, .steps-sub, .gallery-sub) { margin-left: 0; margin-right: auto; }
.block-design[data-head-align="right"] :is(.block-sub, .cards-sub, .steps-sub, .gallery-sub) { margin-left: auto; margin-right: 0; }
/* The mark under the heading. */
.block-design[data-head-accent] :is(h1, h2, .cards-heading, .steps-heading)::after {
  content: ""; display: block; margin-top: 12px; border-radius: 999px;
  background: var(--primary);
}
.block-design[data-head-accent="line"] :is(h1, h2, .cards-heading, .steps-heading)::after { width: 48px; height: 2px; }
.block-design[data-head-accent="bar"] :is(h1, h2, .cards-heading, .steps-heading)::after { width: 64px; height: 5px; }
.block-design[data-head-accent="dot"] :is(h1, h2, .cards-heading, .steps-heading)::after { width: 8px; height: 8px; }
.block-design[data-head-accent="wide"] :is(h1, h2, .cards-heading, .steps-heading)::after {
  width: 120px; height: 3px;
  background: linear-gradient(90deg, var(--primary), transparent);
}
/* A centred or right-aligned heading carries its mark with it. */
.block-design[data-head-align="center"] :is(h1, h2, .cards-heading, .steps-heading)::after { margin-left: auto; margin-right: auto; }
.block-design[data-head-align="right"] :is(h1, h2, .cards-heading, .steps-heading)::after { margin-left: auto; }
/* Blocks that centre their own heading keep the mark centred with it. */
.block--hero :is(h1, h2)::after, .block--features h2::after, .block--faq h2::after,
.block--gallery h2::after, .block--steps .steps-heading::after, .cards-head .cards-heading::after {
  margin-left: auto; margin-right: auto;
}
.block-design[data-head-align="left"] :is(.block--hero, .block--features, .block--faq, .block--gallery) :is(h1, h2)::after,
.block-design[data-head-align="left"] .cards-head .cards-heading::after,
.block-design[data-head-align="left"] .steps-heading::after { margin-left: 0; margin-right: auto; }
/* Per-side padding overrides the block's baked-in padding (vertical on .block,
   horizontal gutter on .container). Only the sides the user set are emitted. */
.block-design[data-pt] > .block { padding-top: var(--pt); }
.block-design[data-pb] > .block { padding-bottom: var(--pb); }
.block-design[data-pl] .container { padding-left: var(--pl); }
.block-design[data-pr] .container { padding-right: var(--pr); }
@media (max-width: 768px) {
  .block-design[data-pt-m] > .block { padding-top: var(--pt-m); }
  .block-design[data-pb-m] > .block { padding-bottom: var(--pb-m); }
  .block-design[data-pl-m] .container { padding-left: var(--pl-m); }
  .block-design[data-pr-m] .container { padding-right: var(--pr-m); }
}
/* Background image lives in a ::before overlay so its opacity never fades the
   block's content. --block-bg-opacity defaults to 1 (fully opaque). */
/* Per-block screen visibility (Setting tab). Bands meet at the stylesheet's own
   mobile breakpoint, so "mobile" here means the same 768px as everywhere else. */
@media (max-width: 768px) { .block-design[data-hide-m] { display: none; } }
@media (min-width: 769px) and (max-width: 1024px) { .block-design[data-hide-t] { display: none; } }
@media (min-width: 1025px) { .block-design[data-hide-d] { display: none; } }

.block-design[data-bg="full"] { position: relative; }
.block-design[data-bg="full"] > * { position: relative; z-index: 1; }
.block-design[data-bg="full"]::before {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background-image: var(--block-bg); background-size: cover; background-position: center;
  opacity: var(--block-bg-opacity, 1);
}
.block-design[data-bg="contained"] .container { position: relative; }
.block-design[data-bg="contained"] .container > * { position: relative; z-index: 1; }
.block-design[data-bg="contained"] .container::before {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none; border-radius: 16px;
  background-image: var(--block-bg); background-size: cover; background-position: center;
  opacity: var(--block-bg-opacity, 1);
}

/* Page header (breadcrumb + title + description) */
.block--page-header { padding: 52px 0; }
.block--page-header.ph--center { text-align: center; }
.ph-crumbs { font-size: 13px; color: var(--muted); margin-bottom: 14px; }
.ph-crumbs a { color: inherit; transition: color .15s ease; }
.ph-crumbs a:hover { color: var(--primary); }
.ph-current { color: var(--ink); font-weight: 600; }
.ph-sep { margin: 0 9px; opacity: .55; }
.ph-title { font-size: clamp(28px, 4.5vw, 44px); line-height: 1.15; margin: 0; letter-spacing: -.02em; }
.ph-desc { margin: 12px 0 0; font-size: 17px; color: var(--muted); max-width: 760px; }
.ph--center .ph-desc { margin-left: auto; margin-right: auto; }

/* Section eyebrow pill (reusable) */
.section-eyebrow {
  display: inline-block; padding: 4px 14px; border-radius: 999px; font-size: 12px; font-weight: 600;
  background: color-mix(in srgb, var(--primary) 12%, transparent); color: var(--primary);
}

/* Cards */
/* Shared by the Cards and Articles blocks */
.cards-head { text-align: center; margin-bottom: 32px; }
.cards-heading { font-size: clamp(24px, 4vw, 36px); margin: 10px 0 8px; }
.cards-sub { color: var(--muted); max-width: 640px; margin: 0 auto; }
.cards-grid { display: grid; grid-template-columns: repeat(var(--cols,3), 1fr); gap: 20px; }
.ucard { display: flex; flex-direction: column; position: relative; border: 1px solid var(--border); border-radius: 12px; overflow: hidden; background: #fff; }
a.ucard { text-decoration: none; color: inherit; transition: transform .18s ease, border-color .18s ease; }
a.ucard:hover { transform: translateY(-3px); border-color: var(--primary); }
/* Hover animation "None" — the card still marks itself as hovered, it just
   does not move. */
.cards-hover-none a.ucard:hover { transform: none; }
.ucard-badge {
  position: absolute; top: 10px; right: 10px; z-index: 1; padding: 2px 9px; border-radius: 999px;
  font-size: 11px; font-weight: 700; background: var(--primary); color: var(--primary-ink);
}
.ucard-img { width: 100%; aspect-ratio: var(--ucard-ratio, 16/10); object-fit: cover; display: block; }
/* --- Words over the picture (Style → Card) ---------------------------------
   The body leaves the flow and sits on the image behind a scrim, which turns
   a grid of cards into a wall of posters. */
.cards--over .ucard { position: relative; }
.cards--over .ucard-body {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 1;
  background: linear-gradient(to top, rgba(0, 0, 0, .78), rgba(0, 0, 0, .45) 55%, transparent);
  color: #fff; padding: 18px 16px 14px;
}
.cards--over .ucard-body :is(h3, p) { color: #fff; }
.cards--over .ucard-body p { opacity: .9; }
/* A card whose media sits beside the text has nothing to lie over. */
.cards--over .ucard--left .ucard-body, .cards--over .ucard--right .ucard-body { position: static; background: none; color: inherit; }
.cards--over .ucard--left .ucard-body :is(h3, p), .cards--over .ucard--right .ucard-body :is(h3, p) { color: inherit; }
.ucard-icon { padding: 20px 16px 0; color: var(--primary); }
.ucard-icon svg { width: 40px; height: 40px; display: inline-block; }
.ucard-body { padding: 16px; }
.ucard-body h3 { margin: 0 0 6px; font-size: 17px; }
.ucard-body p { margin: 0; color: var(--muted); font-size: 14px; }
/* Media position (left / right put media beside the text) */
.ucard--left, .ucard--right { flex-direction: row; align-items: flex-start; }
.ucard--right { flex-direction: row-reverse; }
.ucard--left .ucard-img, .ucard--right .ucard-img { width: 88px; height: 88px; aspect-ratio: 1; flex: 0 0 auto; margin: 14px; border-radius: 10px; }
/* "Full image" fit — no crop; the image keeps its natural ratio and the card grows. */
.ucard-img.ucard-img--full { aspect-ratio: auto; height: auto; }
/* A shape asked for by name wins over "no crop" — that is what asking means. */
.cards--ratio .ucard-img, .cards--ratio .ucard-img.ucard-img--full {
  aspect-ratio: var(--ucard-ratio, 16/10); height: auto; object-fit: cover;
}
.ucard--left .ucard-img.ucard-img--full, .ucard--right .ucard-img.ucard-img--full { height: auto; aspect-ratio: auto; }
.ucard--left .ucard-icon, .ucard--right .ucard-icon { padding: 18px 0 0 18px; }
.ucard--right .ucard-icon { padding: 18px 18px 0 0; }
.ucard--left .ucard-body, .ucard--right .ucard-body { flex: 1 1 auto; }
/* Text alignment */
.block--cards[data-align="center"] .ucard-body, .block--cards[data-align="center"] .ucard-icon { text-align: center; }
.block--cards[data-align="right"] .ucard-body, .block--cards[data-align="right"] .ucard-icon { text-align: right; }
/* Shadow / glow presets */
.ucard--shadow-soft { box-shadow: 0 2px 8px rgba(0,0,0,.06); }
.ucard--shadow-medium { box-shadow: 0 8px 20px -6px rgba(0,0,0,.15); }
.ucard--shadow-strong { box-shadow: 0 16px 40px -8px rgba(0,0,0,.28); }
/* Cards marquee: the same cards scrolling forever. Each card takes the same
   share of the container a grid column would, so switching layout keeps the
   sizing; the track holds two identical sets and shifts by half its width. */
.cards-marquee { overflow: hidden; }
.cards-track { display: flex; width: max-content; animation: cards-marquee linear infinite; }
.cards-set { display: flex; gap: 20px; padding-right: 20px; flex: 0 0 auto; }
/* One card = the share a grid column would get: the container's width (capped
   by the viewport minus its gutters), less the gaps, divided by the columns. */
.cards-set > * { flex: 0 0 auto; width: calc((min(var(--container, 1080px), 100vw - 48px) - (var(--cols,3) - 1) * 20px) / var(--cols,3)); }
.cards-marquee--pause .cards-track:hover { animation-play-state: paused; }
/* A visitor who asked for less motion gets a static row rather than a loop. */
@media (prefers-reduced-motion: reduce){ .cards-track { animation: none; } }
@keyframes cards-marquee { to { transform: translateX(-50%); } }

@media (max-width: 768px){ .cards-grid { grid-template-columns: repeat(var(--cols-m, 2), 1fr); gap: 14px; } }
@media (max-width: 768px){ .cards-set { gap: 14px; padding-right: 14px; } .cards-set > * { width: calc((100vw - 48px - (var(--cols-m, 2) - 1) * 14px) / var(--cols-m, 2)); } }
@media (max-width: 480px){ .cards-grid { grid-template-columns: repeat(var(--cols-m, 1), 1fr); } }

/* Step list */
.block--steps .steps-heading { text-align: center; font-size: clamp(24px, 4vw, 40px); margin: 0 0 10px; }
.block--steps .steps-sub { text-align: center; color: var(--muted); margin: 0 auto 32px; max-width: 640px; }
.block--steps .steps { display: flex; gap: var(--step-gap, 14px); align-items: stretch; }
/* Steps per row (Content → Per screen). Unset = the original single row. The
   connector is dropped once the row wraps — it would point at nothing. */
.block--steps .steps[data-cols] { flex-wrap: wrap; }
.block--steps .steps[data-cols] > .step {
  flex: 0 0 calc((100% - (var(--step-cols, 1) - 1) * var(--step-gap, 14px)) / var(--step-cols, 1));
}
.block--steps .steps[data-nolines] > .step::after { display: none; }
.block--steps .step {
  flex: 1 1 0; min-width: 0; position: relative; text-align: center; padding: 28px 18px;
  border: 1px solid var(--step-border, var(--border)); border-radius: 16px;
  background: var(--step-card-bg, var(--surface)); transition: border-color .3s ease, box-shadow .3s ease;
}
/* Connector: a line from this circle's centre to the next one's, behind the circles. */
.block--steps .step:not(:last-child)::after {
  content: ""; position: absolute; top: 47px; left: 50%; width: calc(100% + var(--step-gap, 14px));
  height: 2px; background: var(--step-connector, var(--border)); z-index: 0; transition: background .3s ease;
}
.block--steps .step-num {
  position: relative; z-index: 1; width: 40px; height: 40px; margin: 0 auto 14px; border-radius: 999px;
  display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 15px;
  background: var(--step-circle, var(--surface)); color: var(--step-circle-text, var(--muted));
  border: 1px solid var(--step-border, var(--border)); transition: background .3s ease, color .3s ease, box-shadow .3s ease;
}
.block--steps .step-title { color: var(--step-title, var(--ink)); font-weight: 700; font-size: 17px; margin-bottom: 6px; }
.block--steps .step-text { color: var(--step-text, var(--muted)); font-size: 14px; line-height: 1.5; }
/* Active + done (progress) states */
.block--steps .step.active {
  background: var(--step-active-card-bg, var(--step-card-bg, var(--surface)));
  border-color: var(--step-active-card-border, var(--step-active, var(--primary)));
  box-shadow: 0 0 0 1px var(--step-active-card-border, var(--step-active, var(--primary))), 0 16px 40px -18px var(--step-active, var(--primary));
}
.block--steps .step.active .step-num, .block--steps .step.done .step-num {
  background: var(--step-active, var(--primary)); color: var(--step-active-text, #fff); border-color: transparent;
}
.block--steps .step.active .step-num { box-shadow: 0 0 18px -2px var(--step-active, var(--primary)); }
.block--steps .step.done::after { background: var(--step-active, var(--primary)); }
/* Pulse animation (CSS only, on the active circle) */
.block--steps .steps--anim-pulse .step.active .step-num { animation: step-pulse 1.4s ease-in-out infinite; }
@keyframes step-pulse { 0%,100% { transform: scale(1); } 50% { transform: scale(1.1); } }
/* CTA */
.block--steps .steps-cta-wrap { text-align: center; margin-top: 32px; }
.block--steps .steps-cta { display: inline-block; padding: 14px 30px; border-radius: 999px; font-weight: 700; background: var(--step-cta-bg, var(--primary)); color: var(--step-cta-text, var(--primary-ink)); transition: color .15s ease, box-shadow .15s ease; }
.block--steps .steps-cta:hover { background: var(--step-cta-hover-bg, var(--step-cta-bg, var(--primary))); color: var(--step-cta-hover-text, var(--step-cta-text, var(--primary-ink))); }
/* Style variants mirror .btn--secondary/.btn--outline; Style-tab colour vars still win. */
.block--steps .steps-cta--secondary { background: var(--step-cta-bg, rgba(0,0,0,.06)); color: var(--step-cta-text, var(--ink)); }
.block--steps .steps-cta--outline { background: var(--step-cta-bg, transparent); color: var(--step-cta-text, var(--primary)); box-shadow: inset 0 0 0 1.5px var(--step-cta-text, var(--primary)); }
.steps-cta .btn-ic { display: inline-flex; align-items: center; margin-right: 8px; vertical-align: -0.18em; }
.steps-cta .btn-ic svg { width: 1.1em; height: 1.1em; }
/* --- Steps as a timeline (Content → Per screen → Layout) -------------------
   The same steps read down the page, with the line beside them rather than
   through them. Nothing here applies unless the layout asks for it. */
.block--steps .steps--timeline, .block--steps .steps--timeline-alt {
  flex-direction: column; gap: 0; align-items: stretch;
}
.steps--timeline > .step, .steps--timeline-alt > .step {
  flex: 0 0 auto; text-align: left; padding: 0 0 28px 56px; border: 0; background: transparent;
  border-radius: 0; box-shadow: none; position: relative;
}
.steps--timeline > .step:last-child, .steps--timeline-alt > .step:last-child { padding-bottom: 0; }
/* The line runs from each circle down to the next one. */
.steps--timeline > .step:not(:last-child)::after,
.steps--timeline-alt > .step:not(:last-child)::after {
  content: ""; position: absolute; left: 19px; top: 40px; bottom: 0; width: 2px; height: auto;
  background: var(--step-connector, var(--border)); display: block;
}
.steps--timeline > .step.done::after, .steps--timeline-alt > .step.done::after { background: var(--step-active, var(--primary)); }
.steps--timeline > .step .step-num, .steps--timeline-alt > .step .step-num {
  position: absolute; left: 0; top: 0; margin: 0;
}
.steps--timeline > .step.active, .steps--timeline-alt > .step.active {
  background: transparent; box-shadow: none; border-color: transparent;
}
/* The alternating timeline steps out to both sides on a wide screen. */
@media (min-width: 900px) {
  .steps--timeline-alt { max-width: 860px; margin: 0 auto; }
  .steps--timeline-alt > .step { width: 50%; padding-left: 0; padding-right: 48px; text-align: right; }
  .steps--timeline-alt > .step:nth-child(even) { margin-left: 50%; padding-left: 48px; padding-right: 0; text-align: left; }
  .steps--timeline-alt > .step .step-num { left: auto; right: -20px; }
  .steps--timeline-alt > .step:nth-child(even) .step-num { left: -20px; right: auto; }
  .steps--timeline-alt > .step:not(:last-child)::after { left: auto; right: -1px; }
  .steps--timeline-alt > .step:nth-child(even):not(:last-child)::after { left: -1px; right: auto; }
}

@media (max-width: 720px) {
  .block--steps .steps { flex-direction: column; }
  .block--steps .step:not(:last-child)::after { display: none; }
  /* A desktop row count means nothing once the list stacks — and left alone it
     would set each card's HEIGHT in a column flow. */
  .block--steps .steps[data-cols] > .step { flex: 1 1 auto; }
  /* Two-up on a phone, when the block asks for it. */
  .block--steps .steps[data-cols-m] { flex-direction: row; flex-wrap: wrap; }
  .block--steps .steps[data-cols-m] > .step {
    flex: 0 0 calc((100% - (var(--step-cols-m, 1) - 1) * var(--step-gap-m, var(--step-gap, 14px))) / var(--step-cols-m, 1));
  }
}
/* Gap and button corners apart on a phone. The block's own vars ride inline on
   the section, where a rule could not beat them — so the phone's values are
   applied to the properties here instead. */
@media (max-width: 768px) {
  .block--steps .steps { gap: var(--step-gap-m, var(--step-gap, 14px)); }
}

/* Button motion (Style → Button → Animation). Written for any button, not just
   the Step list's: hover moves for a pointer, and two idle ones that run on
   their own for a call to action that wants to be noticed. */
.btn-anim--lift { transition: transform .18s ease, box-shadow .18s ease; }
.btn-anim--lift:hover { transform: translateY(-3px); box-shadow: 0 14px 26px -14px rgba(0,0,0,.6); }
.btn-anim--grow { transition: transform .18s ease; }
.btn-anim--grow:hover { transform: scale(1.06); }
.btn-anim--glow { transition: box-shadow .25s ease; }
.btn-anim--glow:hover { box-shadow: 0 0 0 3px color-mix(in srgb, currentColor 22%, transparent), 0 0 24px -4px currentColor; }
.btn-anim--shine { position: relative; overflow: hidden; }
.btn-anim--shine::before {
  content: ""; position: absolute; top: 0; bottom: 0; left: -70%; width: 45%;
  background: linear-gradient(100deg, transparent, rgba(255,255,255,.45), transparent);
  transform: skewX(-18deg); pointer-events: none;
}
.btn-anim--shine:hover::before { animation: btn-shine .85s ease; }
@keyframes btn-shine { from { left: -70%; } to { left: 130%; } }
.btn-anim--pulse { animation: btn-pulse 1.8s ease-in-out infinite; }
@keyframes btn-pulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.045); } }
.btn-anim--float { animation: btn-float 3s ease-in-out infinite; }
@keyframes btn-float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-4px); } }
@media (prefers-reduced-motion: reduce) {
  .btn-anim--pulse, .btn-anim--float { animation: none; }
  .btn-anim--lift:hover, .btn-anim--grow:hover { transform: none; }
}

/* Logo strip */
.block--logo-strip { padding: 36px 0; }
.block--logo-strip h2 { font-size: 28px; text-align: center; margin: 0 0 10px; letter-spacing: -.01em; }
.block--logo-strip .block-sub { margin-bottom: 26px; }
.logo-strip { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 36px; }
.logo-strip-img { width: auto; display: inline-block; }
.logo-strip--gray .logo-strip-img { filter: grayscale(1); opacity: .65; transition: filter .2s ease, opacity .2s ease; }
.logo-strip--gray .logo-strip-img:hover { filter: none; opacity: 1; }
.logo-strip--marquee { flex-wrap: nowrap; justify-content: flex-start; overflow: hidden; }
.logo-strip--marquee .logo-track { display: flex; width: max-content; min-width: 200%; flex: 0 0 auto; animation: logo-marquee linear infinite; }
.logo-strip--marquee .logo-set { display: flex; align-items: center; gap: 36px; padding-right: 36px; flex: 1 0 auto; }
.logo-strip--marquee .logo-set > * { flex: 0 0 auto; }
.logo-strip--pause .logo-track:hover { animation-play-state: paused; }
@keyframes logo-marquee { to { transform: translateX(-50%); } }

/* Article page + articles block */
.block--article { padding: 44px 0 80px; }
.block--article .article-back { display: inline-block; font-size: 13px; font-weight: 600; color: var(--muted); margin-bottom: 22px; transition: color .15s ease; }
.block--article .article-back:hover { color: var(--primary); }
.block--article .article-title { font-size: clamp(30px, 4.5vw, 46px); line-height: 1.15; margin: 0 0 14px; letter-spacing: -.02em; }
.block--article .article-meta { color: var(--muted); font-size: 14px; padding-bottom: 22px; margin-bottom: 30px; border-bottom: 1px solid var(--border); }
.block--article .article-cover { width: 100%; border-radius: var(--radius); border: 1px solid var(--border); margin-bottom: 36px; }
.article-content p { font-size: 17px; line-height: 1.85; margin: 0 0 20px; }
.article-content h2 { font-size: 27px; margin: 40px 0 14px; letter-spacing: -.01em; }
.article-content h3 { font-size: 21px; margin: 30px 0 12px; }
.article-content ul { margin: 0 0 20px; padding-left: 24px; }
.article-content li { margin-bottom: 9px; font-size: 17px; line-height: 1.75; }
.article-content .article-img { width: 100%; border-radius: var(--radius); border: 1px solid var(--border); margin: 10px 0 22px; }
.article-content img { max-width: 100%; border-radius: var(--radius); margin: 10px 0 22px; }
.article-content blockquote { margin: 0 0 20px; padding: 6px 0 6px 18px; border-left: 3px solid var(--primary); color: var(--muted); font-size: 17px; }
.article-content a { text-decoration: underline; }
.article-content ol { margin: 0 0 20px; padding-left: 24px; }
.block--articles .article-date { font-size: 12px; color: var(--muted); margin-bottom: 6px; }
.block--articles .article-more { display: inline-block; margin-top: 10px; font-size: 13px; font-weight: 600; color: var(--primary); }
/* "View all" bar: heading left, link top-right */
.articles-bar { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; margin-bottom: 28px; }
.articles-bar .cards-head { margin-bottom: 0; }
.cards-head--left { text-align: left; }
.cards-head--left .cards-sub { margin: 0; }
.articles-viewall { font-size: 14px; font-weight: 600; color: var(--primary); white-space: nowrap; padding-bottom: 4px; }
.articles-viewall:hover { text-decoration: underline; }
/* Load more */
.art-hidden { display: none; }
.articles-more-wrap { text-align: center; margin-top: 26px; }
.articles-more {
  padding: 10px 28px; border-radius: 999px; border: 1px solid var(--border);
  background: var(--artm-bg, var(--surface)); color: var(--artm-text, var(--ink));
  font-weight: 600; font-size: 14px; cursor: pointer;
  transition: color .15s ease, border-color .15s ease;
}
.articles-more:hover {
  border-color: var(--primary);
  background: var(--artm-hbg, var(--artm-bg, var(--surface)));
  color: var(--artm-htext, var(--artm-text, var(--primary)));
}

/* Slider (Cards slider + Images slide) */
.slider { position: relative; }
.slider-viewport { overflow: hidden; }
.slider-track { display: flex; align-items: center; transition: transform .4s ease; margin: 0 -8px; }
/* Peek (Image slider / Cards slider → Peek at the edges): each slide narrows by
   the same percent on both sides, so a sliver of the previous/next slide shows
   at the viewport's edges. 0% (unset) reduces to the original 100%/perview —
   the client script applies the matching offset (see SLIDER_JS in
   render-page.tsx), so the two must be read together if either changes. */
/* The peek in force. Named apart from --slider-peek so the narrow band can
   override it without a var referring to itself. */
.slider { --slider-peek-now: var(--slider-peek, 0%); }
.slider-slide { flex: 0 0 calc((100% - 2 * var(--slider-peek-now, 0%)) / var(--perview,1)); box-sizing: border-box; padding: 0 8px; }
/* Natural aspect ratio — the full image, never cropped. */
.slider-slide .slide-img { width: 100%; height: auto; border-radius: var(--img-radius, 10px); display: block; }
.slider-arrow { position: absolute; top: 50%; transform: translateY(-50%); width: 36px; height: 36px; border-radius: 999px; border: 1px solid var(--border); background: var(--slider-arrow-bg, #fff); color: var(--slider-arrow-color, var(--ink)); font-size: 20px; line-height: 1; cursor: pointer; z-index: 2; }
/* One value, both sides (Style tab → Arrows → Edge offset). Negative sits
   outside the frame — -6px is the original position. */
.slider-prev { left: var(--slider-arrow-offset, -6px); } .slider-next { right: var(--slider-arrow-offset, -6px); }
/* One value serves both positions (Style tab → Dots → Offset): the gap below
   the slider when Outside (the original spacing), or the distance up from the
   bottom edge when Inside. */
.slider-dots { display: flex; gap: 6px; justify-content: center; margin-top: var(--slider-dots-offset, 12px); }
/* Arrows and dots per screen (Style → Slider): both screens' answers are in
   the page; each screen hides the one that is not its own. */
@media (max-width: 768px) {
  .slider--no-arrows-m .slider-arrow, .slider--no-arrows-m .rank-bar-nav, .slider--no-dots-m .slider-dots { display: none; }
}
@media (min-width: 769px) {
  .slider--no-arrows-d .slider-arrow, .slider--no-arrows-d .rank-bar-nav, .slider--no-dots-d .slider-dots { display: none; }
}
/* Base diameter (Style tab → Dots → Size: S/M/L/XL). The line/bar variants
   below are expressed relative to it, so a size choice scales whichever dot
   style is picked rather than only the round default. */
.slider-dot { width: var(--slider-dot-size, 8px); height: var(--slider-dot-size, 8px); border-radius: 999px; border: 0; background: var(--slider-dot-color, var(--border)); cursor: pointer; padding: 0; }
.slider-dot[aria-current="true"] { background: var(--slider-dot-active, var(--primary)); }

/* Arrow style variants (Style tab → Arrows → Arrow style). Compound selector
   (.slider-arrow.slider-arrow--X) so a theme's own .slider-arrow override
   (appended after this stylesheet) can never outrank them by source order. */
.slider-arrow.slider-arrow--square { border-radius: 8px; }
.slider-arrow.slider-arrow--minimal { background: transparent; border-color: transparent; }
.slider-arrow.slider-arrow--solid { background: var(--slider-arrow-bg, var(--primary)); color: var(--slider-arrow-color, #fff); border-color: transparent; }
.slider-arrow.slider-arrow--outline { background: transparent; border-width: 2px; border-color: var(--slider-arrow-color, var(--border)); color: var(--slider-arrow-color, var(--ink)); }

/* Dot style variants (Style tab → Dots → Dots style). Same compound-selector
   reasoning: descendant + modifier class already outranks the theme's plain
   .slider-dot rule, regardless of order. */
.slider-dots.slider-dots--line .slider-dot { transition: width .2s ease; }
.slider-dots.slider-dots--line .slider-dot[aria-current="true"] { width: calc(var(--slider-dot-size, 8px) * 2.75); border-radius: 999px; }
.slider-dots.slider-dots--bar .slider-dot { width: calc(var(--slider-dot-size, 8px) * 2.25); height: calc(var(--slider-dot-size, 8px) * 0.5); border-radius: 2px; }
.slider-dots.slider-dots--hollow .slider-dot { background: transparent; border: 2px solid var(--slider-dot-color, var(--border)); }
.slider-dots.slider-dots--hollow .slider-dot[aria-current="true"] { background: var(--slider-dot-active, var(--primary)); border-color: var(--slider-dot-active, var(--primary)); }

/* Dot position (Style tab → Dots → Position): Outside (default) leaves them
   below the slider, taking their own space; Inside overlaps them on the image
   itself, so .slider needs no extra height for the row. Compound selector for
   the same reason as the other slider modifiers above. */
.slider-dots.slider-dots--inside { position: absolute; left: 0; right: 0; bottom: var(--slider-dots-offset, 12px); margin-top: 0; z-index: 2; }

/* --- Ranking: numbered logo chart (Top 10 …) ------------------------------
   The rank sits behind its card as one big numeral; the card is pushed right so
   the digits stay readable. Both the numeral and the bar take their colour from
   the theme, so the same block looks native on a gold site and a blue one. */
.block--ranking { padding: 36px 0; }
.block--ranking > .container > h2 { font-size: clamp(20px, 3vw, 30px); margin: 0 0 18px; letter-spacing: -.01em; }
/* Heading bar: badge + title + the slider's prev/next, all on one pill. */
.rank-bar {
  display: flex; align-items: center; gap: 12px; margin-bottom: 18px;
  padding: 8px 14px; border-radius: var(--rank-bar-radius, 999px); min-height: 52px;
  background: var(--rank-bar-bg, linear-gradient(90deg, color-mix(in srgb, var(--primary) 85%, transparent), color-mix(in srgb, var(--primary) 8%, transparent)));
  color: var(--rank-bar-ink, var(--primary-ink, #fff));
}
.rank-bar-badge {
  flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
  min-width: 38px; height: 38px; padding: 0 10px; border-radius: 999px;
  font-size: 19px; font-weight: 900; line-height: 1;
  background: var(--rank-badge-bg, rgba(0, 0, 0, .28)); color: inherit;
}
.rank-bar-title { font-size: clamp(15px, 2vw, 20px); font-weight: 800; min-width: 0; }
.rank-bar-nav { margin-left: auto; display: flex; gap: 8px; flex: 0 0 auto; }
/* In the bar the arrows are part of the flow, not overlaid on the viewport. */
.rank-bar .slider-arrow {
  position: static; transform: none; width: 34px; height: 34px;
  /* The block's own bar colours are the default, but the shared slider fields
     (Style → Arrows) still win when set, so one control covers both headings. */
  background: var(--slider-arrow-bg, var(--rank-nav-bg, rgba(255, 255, 255, .14)));
  border-color: var(--rank-nav-border, rgba(255, 255, 255, .35));
  color: var(--slider-arrow-color, inherit);
}
.rank-bar .slider-arrow:hover { background: var(--rank-nav-bg-hover, rgba(255, 255, 255, .26)); }

/* Cards keep a common height so the names line up even when the artwork does
   not; the numeral is sized off the ITEM, not the viewport, so the proportion
   holds whether six or three are in view. */
.block--ranking .slider-track { align-items: stretch; }
.rank-item {
  position: relative; height: 100%;
  display: flex; flex-direction: column; align-items: stretch;
  container-type: inline-size;
}
/* The card sits in the right ~66%; the numeral fills the gutter and is
   overlapped by roughly its last third, as in the reference designs. */
.rank-figure { position: relative; padding-left: 34%; }
/* Anchoring the numeral's RIGHT edge to the card's left edge (right: 66% =
   100% - the figure's 34% gutter) and then nudging it 30% of its own width to
   the right fixes the overlap at exactly a third — whatever the font size, the
   digit count, or how many cards are in view. */
.rank-num {
  position: absolute; right: 66%; top: 50%; transform: translate(30%, -50%);
  white-space: nowrap;
  font-size: clamp(44px, 6vw, 104px); /* fallback where cq units are unsupported */
  /* Sized off the card, not the viewport (Style → Number → Size), so the
     proportion holds however many are in view. */
  font-size: var(--rank-num-size, 54cqw);
  font-weight: var(--rank-num-weight, 900); line-height: .78;
  font-family: var(--font-heading, inherit); pointer-events: none; z-index: 0;
}
.rank-num--outline {
  color: transparent;
  -webkit-text-stroke: var(--rank-num-stroke, 2px) var(--rank-num, color-mix(in srgb, var(--ink) 55%, transparent));
}
.rank-num--solid { color: var(--rank-num, color-mix(in srgb, var(--ink) 30%, transparent)); }
/* Number inside (Style → Number → Place): on the artwork's lower-left corner,
   inside the card so it moves with it and is clipped by its corners. White by
   default with a soft shadow — it sits on a picture, not the page. */
.rank-figure.rank-figure--in { padding-left: 0; }
.rank-num.rank-num--in {
  right: auto; top: auto; left: 7%; bottom: 4%; transform: none; z-index: 2;
  font-size: var(--rank-num-size, 34cqw);
  filter: drop-shadow(0 2px 6px rgba(0, 0, 0, .5));
}
.rank-num--solid.rank-num--in { color: var(--rank-num, #fff); }
.rank-num--outline.rank-num--in { -webkit-text-stroke-color: var(--rank-num, #fff); }
.rank-link { position: relative; z-index: 1; display: block; width: 100%; }
.rank-card { position: relative; z-index: 1; display: block; width: 100%; border-radius: var(--rank-card-radius, 16px); overflow: hidden; }
.rank-img { display: block; width: 100%; height: auto; border-radius: inherit; }
/* Placeholder while an entry has no image yet (the editor's default rows). */
.rank-img--empty { aspect-ratio: 3 / 4; background: var(--card-bg, var(--surface)); }
/* Gradient frame — a 2px sleeve of the accent behind the artwork. */
.rank-card--glow {
  padding: 2px;
  background: var(--rank-frame, linear-gradient(150deg, color-mix(in srgb, var(--primary) 90%, #fff 10%), color-mix(in srgb, var(--primary) 35%, transparent)));
}
/* The artwork's own corner follows the frame's, less the sleeve it sits in. */
.rank-card--glow .rank-img { border-radius: calc(var(--rank-card-radius, 16px) - 2px); }
.rank-card--soft {
  padding: 6px;
  background: var(--rank-frame-bg, var(--card-bg, var(--surface)));
  border: 1px solid var(--rank-frame-border, var(--card-border, var(--border)));
}
.rank-card--soft .rank-img { border-radius: calc(var(--rank-card-radius, 16px) - 5px); }
.rank-card--none { border-radius: var(--rank-card-radius, var(--img-radius, 10px)); }
/* --- Ranking as a list (Content → Layout) ----------------------------------
   The same items read one under the other: number, artwork, name, and a mark
   where the row leads somewhere. */
.rank--list .rank-list {
  display: grid; grid-template-columns: repeat(var(--rank-list-cols, 1), minmax(0, 1fr));
  gap: 8px; margin: 0; padding: 0; list-style: none;
}
.rank--list .rank-list-row { margin: 0; }
.rank--list .rank-list-box {
  display: flex; align-items: center; gap: 14px;
  padding: 10px 14px; border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--surface); color: inherit; text-decoration: none;
  transition: border-color .15s ease, transform .15s ease;
}
.rank--list .rank-list-link:hover { border-color: var(--primary); }
/* In a list the number is a small badge in the row, not the big figure that
   sits behind a slider card — its container-query size has no card to read. */
.rank--list .rank-num {
  position: static; transform: none; flex: 0 0 auto; min-width: 1.6em; text-align: center;
  font-size: var(--rank-list-num-size, 20px); line-height: 1.2;
  -webkit-text-stroke-width: var(--rank-num-stroke, 1px);
}
.rank--list .rank-list-art { flex: 0 0 auto; width: 56px; height: 56px; }
.rank--list .rank-list-art .rank-img { width: 56px; height: 56px; object-fit: cover; }
.rank--list .rank-list-name { flex: 1 1 auto; min-width: 0; font-weight: 600; }
.rank--list .rank-list-go { flex: 0 0 auto; font-size: 20px; line-height: 1; color: var(--muted); }
@media (max-width: 768px) { .rank--list .rank-list { grid-template-columns: 1fr; } }
.rank-name {
  position: relative; z-index: 1; display: block; width: 100%;
  /* auto pushes the name to the bottom of the (stretched) item, so a row of
     mixed-height artwork still has its names on one line. */
  margin: auto 0 0; padding-top: 10px; text-align: center;
  font-size: 13px; color: var(--rank-name, var(--muted));
}
/* ---- Cards hover motion (Style tab → Card style) ------------------------
   Same contract as the ranking below: the hovered card wins the stacking
   fight against its later siblings, and the clipping layouts (slider,
   marquee) get vertical slack so nothing is cropped mid-move. A linked card's
   built-in 3px lift stays the default; these override it when chosen. */
.cards-hover-lift .ucard,
.cards-hover-scale .ucard,
.cards-hover-tilt .ucard,
.cards-hover-glow .ucard {
  transition: transform .22s ease, box-shadow .22s ease, border-color .18s ease;
}
.cards-hover-lift .ucard:hover,
.cards-hover-scale .ucard:hover,
.cards-hover-tilt .ucard:hover,
.cards-hover-glow .ucard:hover { z-index: 3; }
.cards-hover-lift .ucard:hover { transform: translateY(-8px); }
.cards-hover-scale .ucard:hover { transform: scale(1.04); }
.cards-hover-tilt .ucard:hover { transform: rotate(-1.5deg) scale(1.03); }
.cards-hover-glow .ucard:hover {
  transform: translateY(-4px);
  box-shadow: 0 10px 30px -6px color-mix(in srgb, var(--cards-hover-glow, var(--primary)) 65%, transparent);
}
.cards-hover-shine .ucard::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; z-index: 2;
  background: linear-gradient(100deg, transparent 40%, rgba(255, 255, 255, .45) 50%, transparent 60%);
  background-size: 220% 100%; background-position: -140% 0;
}
.cards-hover-shine .ucard:hover::after {
  background-position: 240% 0;
  transition: background-position .7s ease;
}
.cards-hover-lift .slider-viewport,
.cards-hover-scale .slider-viewport,
.cards-hover-tilt .slider-viewport,
.cards-hover-glow .slider-viewport,
.cards-hover-lift .cards-marquee,
.cards-hover-scale .cards-marquee,
.cards-hover-tilt .cards-marquee,
.cards-hover-glow .cards-marquee { padding: 36px 0; margin: -36px 0; }
@media (prefers-reduced-motion: reduce) {
  .cards-hover-lift .ucard, .cards-hover-scale .ucard,
  .cards-hover-tilt .ucard, .cards-hover-glow .ucard { transition: none; }
  .cards-hover-lift .ucard:hover, .cards-hover-scale .ucard:hover,
  .cards-hover-tilt .ucard:hover, .cards-hover-glow .ucard:hover { transform: none; }
  .cards-hover-shine .ucard:hover::after { transition: none; }
}

/* ---- Ranking card hover motion (Style tab → Card style) ----------------
   Opt-in per block via rank-hover-<anim> on the section. The whole item is the
   hover target (a finger or pointer rarely lands exactly on the artwork); the
   card is what moves, sleeve and all. */
.rank-hover-lift .rank-card,
.rank-hover-scale .rank-card,
.rank-hover-tilt .rank-card,
.rank-hover-glow .rank-card {
  transition: transform .22s ease, box-shadow .22s ease;
}
/* A moving card must win two fights it otherwise loses: siblings later in the
   DOM paint over it (items are position:relative with no z-index), and the
   slider viewport's overflow:hidden crops whatever leaves the row. So the
   hovered item is raised above its neighbours, and the viewport gets vertical
   slack — padding paired with the same negative margin, which changes no
   layout and reveals nothing horizontally, where clipping is the point. */
.rank-hover-lift .rank-item:hover,
.rank-hover-scale .rank-item:hover,
.rank-hover-tilt .rank-item:hover,
.rank-hover-glow .rank-item:hover { z-index: 3; }
.rank-hover-lift .slider-viewport,
.rank-hover-scale .slider-viewport,
.rank-hover-tilt .slider-viewport,
.rank-hover-glow .slider-viewport { padding: 36px 0; margin: -36px 0; }
.rank-hover-lift .rank-item:hover .rank-card { transform: translateY(-8px); }
.rank-hover-scale .rank-item:hover .rank-card { transform: scale(1.05); }
.rank-hover-tilt .rank-item:hover .rank-card { transform: rotate(-2deg) scale(1.04); }
.rank-hover-glow .rank-item:hover .rank-card {
  transform: translateY(-4px);
  box-shadow: 0 10px 30px -6px color-mix(in srgb, var(--rank-hover-glow, var(--primary)) 65%, transparent);
}
/* A band of light sweeping the artwork once per hover; the return trip is
   instant because the transition only exists in the hover state. */
/* ---- Ranking movement (Content → Auto move / Animation) ----------------
   Each step's curve; "slide" is the slider's own .4s ease. Zoom shrinks the
   cards a touch while the row travels (the slider marks itself is-moving). */
.rank-move-smooth .slider-track { transition-duration: .9s; transition-timing-function: cubic-bezier(.65, 0, .35, 1); }
.rank-move-bounce .slider-track { transition-duration: .75s; transition-timing-function: cubic-bezier(.34, 1.56, .64, 1); }
.rank-move-zoom .slider-track { transition-duration: .65s; transition-timing-function: cubic-bezier(.45, 0, .2, 1); }
.rank-move-zoom .rank-card { transition: transform .3s ease; }
.rank-move-zoom .slider.is-moving .rank-card { transform: scale(.9); }
/* Continuous strip: the cards twice over, run by half the track's width. */
.rank-mq-viewport { overflow: hidden; container-type: inline-size; margin: 0 -8px; }
.rank-mq-track { display: flex; align-items: stretch; width: max-content; animation: rank-mq 30s linear infinite; }
.rank-mq--pause .rank-mq-viewport:hover .rank-mq-track { animation-play-state: paused; }
.rank-mq-slide { flex: 0 0 auto; box-sizing: border-box; padding: 0 8px; width: calc(100cqw / var(--rank-pv, 6)); }
@keyframes rank-mq { to { transform: translateX(-50%); } }
.block--ranking[class*="rank-hover-"] .rank-mq-viewport { padding: 36px 0; margin: -36px -8px; }
@media (max-width: 768px) { .rank-mq-slide { width: calc(100cqw / var(--rank-pv-t, 2)); } }
@media (max-width: 640px) { .rank-mq-slide { width: calc(100cqw / var(--rank-pv-p, 1)); } }
@media (prefers-reduced-motion: reduce) {
  .rank-mq-track { animation: none; }
  .rank-move-zoom .slider.is-moving .rank-card { transform: none; }
}
.rank-hover-shine .rank-card::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  background: linear-gradient(100deg, transparent 40%, rgba(255, 255, 255, .45) 50%, transparent 60%);
  background-size: 220% 100%; background-position: -140% 0;
}
.rank-hover-shine .rank-item:hover .rank-card::after {
  background-position: 240% 0;
  transition: background-position .7s ease;
}
@media (prefers-reduced-motion: reduce) {
  .rank-hover-lift .rank-card, .rank-hover-scale .rank-card,
  .rank-hover-tilt .rank-card, .rank-hover-glow .rank-card { transition: none; }
  .rank-hover-lift .rank-item:hover .rank-card,
  .rank-hover-scale .rank-item:hover .rank-card,
  .rank-hover-tilt .rank-item:hover .rank-card,
  .rank-hover-glow .rank-item:hover .rank-card { transform: none; }
  .rank-hover-shine .rank-item:hover .rank-card::after { transition: none; }
}

@media (max-width: 768px) {
  .rank-bar { gap: 8px; padding: 6px 10px; border-radius: var(--rank-bar-radius-m, var(--rank-bar-radius, 16px)); }
  .rank-bar-badge { min-width: 32px; height: 32px; font-size: 16px; }
  .rank-figure { padding-left: 30%; }
  .rank-num { right: 70%; }
}

/* Blocks */
.block { padding: 48px 0; }
.block--hero { padding: 64px 0; background:
  radial-gradient(1200px 400px at 50% -10%, var(--hero-glow, color-mix(in srgb, var(--primary) 10%, transparent)), transparent); text-align: center; }
.block--hero h1 { font-size: clamp(32px, 5vw, 52px); line-height: 1.1; margin: 0 0 16px; letter-spacing: -.02em; }
/* --- Hero layouts (Content → Layout) ---------------------------------------
   Centred as it always was, aligned left, or the words beside the picture. */
.block--hero.hero--left { text-align: left; }
.block--hero.hero--left p { margin-left: 0; }
.block--hero .hero-split { display: grid; grid-template-columns: 1fr 1fr; gap: 48px; align-items: center; text-align: left; }
.block--hero.hero--split-rev .hero-split { direction: rtl; }
.block--hero.hero--split-rev .hero-split > * { direction: ltr; }
.block--hero .hero-split p { margin-left: 0; margin-right: 0; }
.block--hero .hero-split .hero-art img { margin: 0; width: 100%; }
@media (max-width: 860px) {
  .block--hero .hero-split { grid-template-columns: 1fr; gap: 28px; }
  .block--hero.hero--split-rev .hero-split { direction: ltr; }
}
.block--hero p { font-size: 18px; color: var(--muted); max-width: 620px; margin: 0 auto 28px; }
.block--hero img { margin: 40px auto 0; border-radius: var(--img-radius, var(--radius)); border: 1px solid var(--border); }

.block--text h2 { font-size: 28px; margin: 0 0 12px; letter-spacing: -.01em; }

/* Shared subheading under a block heading */
.block-sub { color: var(--muted); margin: 0 0 22px; max-width: 720px; }
.block-sub--center { text-align: center; margin-left: auto; margin-right: auto; max-width: 640px; }
.block--text .block-sub { margin: -2px 0 20px; }
.block--features .block-sub { margin: -28px auto 34px; }
.block--faq .block-sub { margin: -20px auto 28px; }
.block--imagetext .block-sub { margin: -4px 0 12px; }
.split-list { list-style: none; display: grid; gap: 12px; margin: 0; padding: 0; }
.split-list li { display: flex; align-items: flex-start; gap: 10px; color: var(--muted); }
.split-list-icon { display: inline-flex; margin-top: 2px; color: var(--primary); }
.split-list-icon svg { width: 19px; height: 19px; }
.split__body--panel { padding: 26px; border-radius: var(--radius); }
.split__body .split-btn {
  margin-top: 20px;
  background: var(--itb-bg, var(--theme-btn-bg, var(--primary)));
  color: var(--itb-text, var(--theme-btn-text, var(--primary-ink)));
  border-radius: var(--itb-radius, var(--theme-btn-radius, 10px));
  font-size: var(--itb-size, inherit);
}
.split__body .split-btn:hover {
  background: var(--itb-hbg, var(--itb-bg, var(--theme-btn-hbg, var(--theme-btn-bg, var(--primary)))));
  color: var(--itb-htext, var(--itb-text, var(--theme-btn-htext, var(--theme-btn-text, var(--primary-ink)))));
}
.block--text p { font-size: 17px; color: var(--muted); max-width: 720px; }

.block--cta { }
.block--cta .card {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 48px; text-align: center;
}
.block--cta h2 { font-size: 26px; margin: 0 0 8px; }
.block--cta p { color: var(--muted); margin: 0 0 24px; }

.container--narrow { max-width: 760px; }

/* Feature grid */
.block--features h2 { font-size: 28px; text-align: center; margin: 0 0 40px; letter-spacing: -.01em; }
.block--features .grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 24px; }
.block--features .feature { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 28px; }
.block--features .feature h3 { margin: 0 0 8px; font-size: 18px; }
.block--features .feature p { margin: 0; color: var(--muted); }
/* --- Feature grid looks (Style → Features) ---------------------------------
   Unset, a tile is the filled card it always was. Each look below replaces
   that surface with another way of separating one point from the next. */
.block--features .grid.grid--fixed {
  grid-template-columns: repeat(var(--feat-cols, 3), minmax(0, 1fr));
  gap: var(--feat-gap, 24px);
}
.block--features .grid { gap: var(--feat-gap, 24px); }
@media (max-width: 768px) {
  .block--features .grid.grid--fixed { grid-template-columns: repeat(var(--feat-cols-m, 1), minmax(0, 1fr)); }
}
.feat--plain .feature { background: transparent; border: 0; padding: 8px 0; }
.feat--bordered .feature { background: transparent; border: 1px solid var(--border); border-radius: var(--radius); padding: 24px; }
.feat--line .feature { background: transparent; border: 0; border-top: 2px solid var(--primary); border-radius: 0; padding: 18px 0 0; }
/* Numbered — the tile counts itself, which turns a grid of points into steps. */
.feat--numbered { counter-reset: feat; }
.feat--numbered .feature { background: transparent; border: 0; padding: 4px 0 4px 52px; position: relative; counter-increment: feat; }
.feat--numbered .feature::before {
  content: counter(feat, decimal-leading-zero); position: absolute; left: 0; top: 0;
  font-size: 22px; font-weight: 800; line-height: 1; color: var(--primary); opacity: .85;
}
/* The icon a row may lead with, and what it sits in. */
.block--features .feature-ic { display: inline-flex; margin-bottom: 12px; color: var(--primary); }
.block--features .feature-ic svg { width: 26px; height: 26px; }
.feat-ic--circle .feature-ic, .feat-ic--square .feature-ic, .feat-ic--soft .feature-ic {
  align-items: center; justify-content: center; width: 48px; height: 48px;
  background: color-mix(in srgb, var(--primary) 12%, transparent);
}
.feat-ic--circle .feature-ic { border-radius: 999px; }
.feat-ic--square .feature-ic { border-radius: 0; }
.feat-ic--soft .feature-ic { border-radius: 14px; }

/* Image + text */
.block--imagetext .split { display: grid; grid-template-columns: 1fr 1fr; gap: 48px; align-items: center; }
.block--imagetext .split--reverse .split__media { order: 2; }
.block--imagetext .split__media img { border-radius: var(--img-radius, var(--radius)); border: 1px solid var(--border); width: 100%; }
.block--imagetext h2 { font-size: 28px; margin: 0 0 12px; letter-spacing: -.01em; }
.block--imagetext p { color: var(--muted); font-size: 17px; margin: 0; }
@media (max-width: 720px) { .block--imagetext .split { grid-template-columns: 1fr; } .block--imagetext .split--reverse .split__media { order: 0; } }

/* Gallery */
.block--gallery h2 { font-size: 28px; text-align: center; margin: 0 0 32px; }
.block--gallery .gallery-sub { text-align: center; color: var(--muted); max-width: 640px; margin: -24px auto 28px; }
/* Gallery tag tabs. Colours are vars (Cards → Style → Tags: Tab colour / Active
   fill / Active text) with the original tokens as fallback, so an untouched
   block — Gallery included, which never sets these — looks exactly as before. */
.gallery-tabs { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; margin: 0 0 22px; }
.gallery-tab {
  padding: 6px 16px; border-radius: 999px; border: 1px solid var(--tab-color, var(--border)); background: transparent;
  color: var(--tab-color, var(--muted)); font-size: 13px; font-weight: 600; cursor: pointer;
  transition: color .15s ease, border-color .15s ease, background-color .15s ease;
}
/* Hover previews the active look, whatever it currently resolves to. */
.gallery-tab:hover { color: var(--tab-active-bg, var(--primary)); border-color: var(--tab-active-bg, var(--primary)); }
.gallery-tab.active { background: var(--tab-active-bg, var(--primary)); border-color: var(--tab-active-bg, var(--primary)); color: var(--tab-active-text, var(--primary-ink)); }
.gallery-item.tag-hide { display: none !important; }
/* While filtering, capped (show-more-hidden) items that match the tag appear. */
.block--gallery .gallery-grid.filtering .gallery-item.img-hidden:not(.tag-hide) { display: block; }
.block--gallery .gallery-grid { display: grid; grid-template-columns: repeat(var(--cols,3), 1fr); gap: 16px; align-items: start; }
.block--gallery .gallery-item { position: relative; display: block; margin: 0; }
/* Natural aspect ratio — the full image, never cropped. */
.block--gallery .gallery-item img { border-radius: var(--img-radius, var(--radius)); border: 1px solid var(--border); width: 100%; height: auto; display: block; }
.block--gallery a.gallery-item { transition: opacity .15s ease; }
.block--gallery a.gallery-item:hover { opacity: .92; }
.block--gallery .gallery-cap { display: block; margin-top: 8px; font-size: 13px; color: var(--muted); text-align: center; }
.block--gallery .img-hidden { display: none; }
/* Overlay button on the image (whole tile is the link; button is visual) */
.gallery-media { position: relative; display: block; }
.gallery-ov-btn {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); z-index: 1;
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 20px; border-radius: 999px; font-size: 13px; font-weight: 700; white-space: nowrap;
  background: var(--gal-ov-bg, var(--primary)); color: var(--gal-ov-text, var(--primary-ink));
  pointer-events: none; box-shadow: 0 4px 14px rgba(0,0,0,.25);
}
/* Style variants for the on-image button; colour vars from the Style tab still win. */
.gallery-ov-btn--secondary { background: var(--gal-ov-bg, rgba(0,0,0,.55)); color: var(--gal-ov-text, #fff); }
.gallery-ov-btn--outline { background: var(--gal-ov-bg, transparent); color: var(--gal-ov-text, #fff); box-shadow: inset 0 0 0 1.5px currentColor, 0 4px 14px rgba(0,0,0,.25); }
/* Hover mode: dimming scrim over the image behind the centred button. */
.gallery-scrim {
  position: absolute; inset: 0; border-radius: var(--img-radius, var(--radius));
  background: var(--gal-scrim, #000); opacity: 0; transition: opacity .2s ease; pointer-events: none;
}
.gallery-item--ov-hover:hover .gallery-scrim { opacity: var(--gal-scrim-opacity, .45); }
.gallery-ov-ic { display: inline-flex; }
.gallery-ov-ic svg { width: 14px; height: 14px; }
.gallery-item--ov-hover .gallery-ov-btn { opacity: 0; transition: opacity .2s ease; }
.gallery-item--ov-hover:hover .gallery-ov-btn { opacity: 1; }
.gallery-item:hover .gallery-ov-btn {
  background: var(--gal-ov-hbg, var(--gal-ov-bg, var(--primary)));
  color: var(--gal-ov-htext, var(--gal-ov-text, var(--primary-ink)));
}
/* Show more */
.gallery-more-wrap { text-align: center; margin-top: 22px; }
.gallery-more {
  padding: 10px 28px; border-radius: 999px; border: 1px solid var(--border);
  background: var(--gal-more-bg, var(--surface)); color: var(--gal-more-text, var(--ink));
  font-weight: 600; font-size: 14px; cursor: pointer; transition: color .15s ease, border-color .15s ease;
}
.gallery-more:hover {
  border-color: var(--primary);
  background: var(--gal-more-hbg, var(--gal-more-bg, var(--surface)));
  color: var(--gal-more-htext, var(--gal-more-text, var(--primary)));
}
@media (max-width: 768px){ .block--gallery .gallery-grid { grid-template-columns: repeat(var(--cols-m, 2), 1fr); gap: 12px; } }

/* FAQ */
.block--faq h2 { font-size: 28px; text-align: center; margin: 0 0 32px; }
.block--faq .faq-item { border-top: 1px solid var(--border); padding: 20px 0; }
.block--faq .faq-item h3 { margin: 0 0 6px; font-size: 17px; }
.block--faq .faq-item p { margin: 0; color: var(--muted); }
/* --- FAQ looks (Style → FAQ) -----------------------------------------------
   Unset, the rows are the ruled list they always were. */
.faq--card .faq-item { border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); padding: 18px 20px; margin-bottom: 10px; }
.faq--boxed .faq-item { border: 1px solid var(--border); border-top: 1px solid var(--border); padding: 18px 20px; }
.faq--boxed .faq-item + .faq-item { border-top: 0; }
.faq--boxed .faq-item:first-child { border-radius: var(--radius) var(--radius) 0 0; }
.faq--boxed .faq-item:last-child { border-radius: 0 0 var(--radius) var(--radius); }
.faq--plain .faq-item { border: 0; padding: 14px 0; }
/* Folded rows — <details>, so they work with no script at all. */
.faq--fold .faq-item summary {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  cursor: pointer; list-style: none;
}
.faq--fold .faq-item summary::-webkit-details-marker { display: none; }
.faq--fold .faq-item h3 { margin: 0; }
.faq--fold .faq-item p { margin-top: 10px; }
.faq--fold .faq-mark {
  position: relative; flex: 0 0 auto; width: 14px; height: 14px;
  transition: transform .2s ease; color: var(--muted);
}
.faq--fold .faq-mark::before, .faq--fold .faq-mark::after {
  content: ""; position: absolute; inset: 50% 0 auto; height: 2px; background: currentColor; border-radius: 2px;
}
.faq--fold .faq-mark::after { transform: rotate(90deg); transition: transform .2s ease, opacity .2s ease; }
.faq--fold .faq-item[open] .faq-mark::after { transform: rotate(0); opacity: 0; }

/* Footer block */

/* ---- Card star rating / per-card button / tag filter tabs ---- */
.ucard-stars { position: relative; display: inline-block; line-height: 1; font-size: 15px; letter-spacing: 2px; margin: 2px 0 4px; }
.ucard-stars .stars-bg { color: rgba(128,128,128,.35); }
.ucard-stars .stars-fill { position: absolute; left: 0; top: 0; overflow: hidden; white-space: nowrap; color: var(--star-color, #f0a52c); }
.ucard-body .ucard-btn { margin-top: 10px; padding: 8px 18px; font-size: 14px; display: inline-block; }
/* Where the card's button sits, and when it shows (Content → Button).
   Over the image it needs a box of its own; under the text it stays put. */
.ucard-media { position: relative; display: block; }
.ucard-media .ucard-btn {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  z-index: 2; margin: 0; white-space: nowrap;
  /* On a picture it reads as an overlay button, so it matches the one the
     gallery and a single image put there rather than the block's own size. */
  padding: 8px 20px; font-size: 13px;
}
/* A tint over the picture while the card is hovered (Style → Card → Hover
   image). Unset, no element is drawn at all. */
.ucard-scrim {
  position: absolute; inset: 0; z-index: 1; border-radius: inherit;
  background: var(--ucard-scrim, #000); opacity: 0;
  transition: opacity .2s ease; pointer-events: none;
}
.ucard:hover .ucard-scrim,
.ucard:focus-within .ucard-scrim { opacity: var(--ucard-scrim-opacity, .45); }
/* The wrapper stands in for the picture when a card puts its media to one
   side, so those layouts keep the size and spacing they had. */
.ucard--left .ucard-media, .ucard--right .ucard-media { flex: 0 0 auto; }
.ucard--left .ucard-media .ucard-img, .ucard--right .ucard-media .ucard-img { margin: 0; }
.ucard-media .ucard-btn.ucard-btn--al-left { left: 12px; transform: translateY(-50%); }
.ucard-media .ucard-btn.ucard-btn--al-right { left: auto; right: 12px; transform: translateY(-50%); }
/* "Only on hover": the space is kept either way, so nothing jumps, and a
   button nobody can see cannot be clicked. Keyboard focus counts as hover. */
.ucard-btn--on-hover { opacity: 0; pointer-events: none; transition: opacity .2s ease; }
.ucard:hover .ucard-btn--on-hover,
.ucard:focus-within .ucard-btn--on-hover { opacity: 1; pointer-events: auto; }
/* Button size (Style → Card → Button size). After the two rules above so it
   wins wherever the button sits; unset, neither class is on the element. */
.ucard .ucard-btn--sz-xs { padding: 4px 11px; font-size: 11.5px; }
.ucard .ucard-btn--sz-sm { padding: 6px 15px; font-size: 12.5px; }
.ucard .ucard-btn--sz-md { padding: 9px 20px; font-size: 14px; }
.ucard .ucard-btn--sz-lg { padding: 12px 26px; font-size: 15.5px; }
/* Alignment under the text (Style → Card → Button alignment). */
.ucard-body .ucard-btn--al-left,
.ucard-body .ucard-btn--al-center,
.ucard-body .ucard-btn--al-right { display: block; width: fit-content; }
.ucard-body .ucard-btn--al-left { margin-right: auto; }
.ucard-body .ucard-btn--al-center { margin-left: auto; margin-right: auto; }
.ucard-body .ucard-btn--al-right { margin-left: auto; }
/* A card whose media sits beside the text keeps the media column's size. */
.ucard--left .ucard-media, .ucard--right .ucard-media { flex: 0 0 auto; }
.tab-count { display: inline-flex; align-items: center; justify-content: center; min-width: 18px; height: 18px; padding: 0 5px; margin-left: 7px; border-radius: 999px; font-size: 11px; font-weight: 600; background: rgba(0,0,0,.15); }
.gallery-tab.active .tab-count { background: rgba(255,255,255,.25); }
.cards-grid .tag-hide { display: none !important; }

/* Cards tag-tab style/layout (Style tab → Tags — shown only when the block
   uses tags). ".cards-tabs" is the second class Cards' own wrapper carries —
   Gallery's plain ".gallery-tabs" never has it, so none of this reaches
   Gallery's tabs. Compound selectors throughout so these always outrank the
   plain .gallery-tab rules above regardless of source order. */
.cards-tabs.cards-tabs--underline .gallery-tab { border-color: transparent; border-radius: 0; padding: 8px 2px; box-shadow: inset 0 -2px 0 transparent; }
.cards-tabs.cards-tabs--underline .gallery-tab:hover { border-color: transparent; box-shadow: inset 0 -2px 0 var(--tab-active-bg, var(--primary)); }
.cards-tabs.cards-tabs--underline .gallery-tab.active { background: transparent; border-color: transparent; box-shadow: inset 0 -2px 0 var(--tab-active-bg, var(--primary)); color: var(--tab-active-text, var(--tab-active-bg, var(--primary))); }

.cards-tabs.cards-tabs--boxed .gallery-tab { border-radius: 8px; background: var(--surface); }
.cards-tabs.cards-tabs--boxed .gallery-tab.active { border-radius: 8px; }

.cards-tabs.cards-tabs--minimal .gallery-tab { border-color: transparent; background: transparent; padding: 6px 10px; }
.cards-tabs.cards-tabs--minimal .gallery-tab:hover { border-color: transparent; }
.cards-tabs.cards-tabs--minimal .gallery-tab.active { background: transparent; border-color: transparent; color: var(--tab-active-text, var(--tab-active-bg, var(--primary))); font-weight: 800; }

/* Width: Full stretches each tab to share the row equally (wraps to a new row
   rather than crushing them if there isn't room); Fit (default) is the
   original size-to-content, centred row. */
.cards-tabs.cards-tabs--full .gallery-tab { flex: 1 1 120px; text-align: center; }
/* Alignment only matters for Fit — Full already fills the row. */
.cards-tabs.cards-tabs--align-left { justify-content: flex-start; }
.cards-tabs.cards-tabs--align-right { justify-content: flex-end; }
.cards-tabs.cards-tabs--no-count .tab-count { display: none; }

/* ---- Transaction feed (tx_feed) ---- */
.block--txfeed h2 { text-align: center; font-size: 28px; margin: 0 0 8px; letter-spacing: -.01em; }
.tx-updated { text-align: center; color: var(--muted); font-size: 13px; margin: 0 0 18px; }
.txfeed-grid { display: grid; grid-template-columns: repeat(var(--tx-cols, 2), 1fr); gap: 12px 16px; }
.tx-row { display: flex; align-items: center; gap: 12px; padding: 12px 14px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); }
.tx-ic { display: flex; width: 40px; height: 40px; border-radius: 50%; align-items: center; justify-content: center; border: 1px solid var(--border); color: var(--primary); flex: 0 0 auto; }
.tx-ic svg { width: 20px; height: 20px; }
.tx-ic--bank { border: none; overflow: hidden; background: #fff; }
.tx-ic--bank img { width: 100%; height: 100%; object-fit: cover; border-radius: 50%; display: block; }
.tx-info { flex: 1 1 auto; display: grid; gap: 2px; min-width: 0; }
.tx-member { font-weight: 600; font-size: 14px; }
.tx-amount { font-size: 13px; color: var(--muted); }
.tx-date { font-size: 12px; color: var(--muted); }
.tx-status { flex: 0 0 auto; padding: 6px 14px; border-radius: 999px; font-size: 13px; font-weight: 600; background: var(--theme-btn-bg, var(--primary)); color: var(--theme-btn-text, var(--primary-ink)); white-space: nowrap; }
.tx-status--pending { background: transparent; box-shadow: inset 0 0 0 1.5px var(--primary); color: var(--primary); }
/* Feed refresh animations: whole-list fade (tx-swap) and one-by-one rotation
 * (leave from the top, enter at the bottom; FLIP glide for the rows between). */
.tx-row { opacity: 1; transition: opacity .3s ease, transform .3s ease; }
.tx-row.tx-leave { opacity: 0; transform: translateY(-10px) scale(.97); }
.tx-row.tx-enter { opacity: 0; transform: translateY(14px); transition: none; }
.txfeed-grid.tx-swap .tx-row { opacity: .25; }

/* ---- Marquee (scrolling text bar) ---- */
.block--marquee { padding: 14px 0; background: var(--mq-bg, linear-gradient(90deg, #1f2937, #0f172a)); color: var(--mq-ink, #f5f7fa); }
.mq-wrap { display: flex; align-items: center; gap: 12px; }
.mq-label { flex: 0 0 auto; font-weight: 700; }
.mq-view { overflow: hidden; flex: 1 1 auto; min-width: 0; }
.mq-track { display: flex; width: max-content; min-width: 200%; animation: mq-scroll var(--mq-dur, 25s) linear infinite; }
.mq-track--right { animation-direction: reverse; }
.mq--pause .mq-track:hover { animation-play-state: paused; }
.mq-seq { display: flex; flex: 1 0 auto; align-items: center; }
.mq-item { display: inline-flex; align-items: center; white-space: nowrap; }
/* --- Marquee looks (Content → Marquee) ------------------------------------- */
.mq--sm .mq-wrap { font-size: 12px; }
.mq--lg .mq-wrap { font-size: 17px; font-weight: 600; }
.mq--xl .mq-wrap { font-size: 22px; font-weight: 700; letter-spacing: -.01em; }
.block--marquee.mq--plain { background: transparent; color: inherit; border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); }
/* Each message in a pill of its own — the separator gives way to the shape. */
.mq--pill .mq-item {
  margin-right: 10px; padding: 5px 14px; border-radius: 999px;
  background: color-mix(in srgb, currentColor 14%, transparent);
}
.mq--pill .mq-sep { display: none; }
/* The ends fade instead of being cut off. */
.mq--fade .mq-view {
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}
.mq-link { display: inline-flex; align-items: center; color: inherit; text-decoration: none; }
.mq-link:hover { text-decoration: underline; text-underline-offset: 3px; }
.mq-ic { display: inline-flex; align-items: center; margin-right: 8px; }
.mq-ic svg { width: 1em; height: 1em; }
.mq-sep { margin: 0 18px; opacity: .55; }
@keyframes mq-scroll { from { transform: translateX(0); } to { transform: translateX(-50%); } }

/* ---- Icon links (quick menu strip) + section heading icon ---- */
.icon-links { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 12px 32px; }
.icon-links--left { justify-content: flex-start; }
.icon-link { display: inline-flex; align-items: center; gap: 8px; color: var(--il-text, var(--ink)); text-decoration: none; font-weight: 600; font-size: 15px; }
a.icon-link:hover { color: var(--il-icon, var(--primary)); }
.icon-link-ic { display: inline-flex; color: var(--il-icon, var(--primary)); }
.icon-link-ic svg { width: 20px; height: 20px; }
.head-ic { display: inline-flex; vertical-align: -0.12em; margin-right: 10px; color: var(--primary); }
.head-ic svg { width: 1em; height: 1em; }

/* ---- Bottom bar (app-style fixed nav) ----------------------------------
   Which screens it appears on is decided in the admin and arrives as
   --no-desktop / --no-tablet / --no-mobile classes, so the rules below only
   have to hide it. Everything sizeable is a variable with the default beside
   it, so an untouched bar follows the theme. */
.bottombar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 55;
  background: var(--bb-bg, var(--surface));
  border-top: var(--bb-bw, 1px) solid var(--bb-border, var(--border));
  color: var(--bb-text, var(--ink));
  /* Sits above the phone's home indicator rather than under it. */
  padding-bottom: env(safe-area-inset-bottom, 0px);
}
.bottombar .bb-row {
  display: flex; align-items: stretch; justify-content: space-around;
  gap: 2px; height: var(--bb-h, 64px); max-width: var(--container, 1200px); margin: 0 auto;
}
.bb-item {
  flex: 1 1 0; min-width: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  padding: 6px 4px; text-decoration: none; color: inherit; text-align: center;
  font-size: var(--bb-fs, 11px); line-height: 1.15;
}
.bb-item .bb-label { display: block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bb-ic { display: inline-flex; }
.bb-ic svg { width: var(--bb-ic, 22px); height: var(--bb-ic, 22px); }
.bb-item {
  transition: color .18s ease, background-color .18s ease, transform .18s ease, opacity .18s ease;
}
/* Hover and "current page" used to share one rule, so they could never differ.
   Three states now, each falling back to the one before it. */
.bb-item { background: var(--bb-item-bg, transparent); }
.bb-item:hover {
  color: var(--bb-text-hover, var(--bb-active, var(--primary)));
  background: var(--bb-item-hover-bg, transparent);
}
.bb-item[aria-current="page"] {
  color: var(--bb-active, var(--primary));
  background: var(--bb-item-active-bg, var(--bb-item-hover-bg, transparent));
}
/* The icon can carry its own three; unset it follows the label as before. */
.bb-item .bb-ic { color: var(--bb-ic-color, inherit); transition: color .18s ease; }
.bb-item:hover .bb-ic { color: var(--bb-ic-hover, var(--bb-ic-color, inherit)); }
.bb-item[aria-current="page"] .bb-ic { color: var(--bb-ic-active, var(--bb-ic-hover, var(--bb-ic-color, inherit))); }
/* What an ordinary item does when pointed at. Motion is opt-in, and anyone who
   asked their system for less does not get it. */
.bottombar--item-lift .bb-item:hover { transform: translateY(-3px); }
.bottombar--item-scale .bb-item:hover { transform: scale(1.12); }
.bottombar--item-fade .bb-item { opacity: .72; }
.bottombar--item-fade .bb-item:hover, .bottombar--item-fade .bb-item[aria-current="page"] { opacity: 1; }
.bottombar--item-underline .bb-item { position: relative; }
.bottombar--item-underline .bb-item::after {
  content: ""; position: absolute; left: 50%; right: 50%; bottom: 4px; height: 2px; border-radius: 2px;
  background: var(--bb-active, var(--primary)); transition: left .18s ease, right .18s ease;
}
.bottombar--item-underline .bb-item:hover::after,
.bottombar--item-underline .bb-item[aria-current="page"]::after { left: 22%; right: 22%; }
/* The featured icon is the featured item's, not the row's.
   The rule .bb-item .bb-ic above also matches it — one class shallower — so without
   these it took the ORDINARY items' icon colour in the flat variants. Its own
   three states, each falling back to the featured TEXT, which is what it
   showed before any of this was settable. */
.bb-item--featured .bb-ic { color: var(--bb-feat-ic, var(--bb-feat-text, var(--primary-ink, #fff))); }
.bb-item--featured:hover .bb-ic { color: var(--bb-feat-ic-hover, var(--bb-feat-ic, var(--bb-feat-hover-text, var(--bb-feat-text, var(--primary-ink, #fff))))); }
.bb-item--featured[aria-current="page"] .bb-ic { color: var(--bb-feat-ic-active, var(--bb-feat-ic-hover, var(--bb-feat-ic, var(--bb-feat-active-text, var(--bb-feat-text, var(--primary-ink, #fff)))))); }

/* The featured item keeps its own hover colours whatever the row does. */
.bb-item--featured:hover { color: var(--bb-feat-hover-text, var(--bb-feat-text, var(--primary-ink, #fff))); }
.bb-item--featured[aria-current="page"] { color: var(--bb-feat-active-text, var(--bb-feat-hover-text, var(--bb-feat-text, var(--primary-ink, #fff)))); }
.bottombar--bar .bb-item--featured:hover,
.bottombar--pill .bb-item--featured:hover,
.bottombar--compact .bb-item--featured:hover {
  background: var(--bb-feat-hover-bg, var(--bb-feat-bg, var(--primary)));
}
.bottombar--bar .bb-item--featured[aria-current="page"],
.bottombar--pill .bb-item--featured[aria-current="page"],
.bottombar--compact .bb-item--featured[aria-current="page"] {
  background: var(--bb-feat-active-bg, var(--bb-feat-hover-bg, var(--bb-feat-bg, var(--primary))));
}
.bottombar--raised .bb-item--featured[aria-current="page"] .bb-ic {
  background: var(--bb-feat-active-bg, var(--bb-feat-hover-bg, var(--bb-feat-bg, var(--primary))));
  color: var(--bb-feat-ic-active, var(--bb-feat-ic-hover, var(--bb-feat-ic, var(--bb-feat-active-text, var(--bb-feat-hover-text, var(--bb-feat-text, var(--primary-ink, #fff)))))));
}
.bottombar--raised .bb-item--featured:hover .bb-ic {
  background: var(--bb-feat-hover-bg, var(--bb-feat-bg, var(--primary)));
  color: var(--bb-feat-ic-hover, var(--bb-feat-ic, var(--bb-feat-hover-text, var(--bb-feat-text, var(--primary-ink, #fff)))));
}
/* Icons only — the row gets its height back. */
.bottombar--nolabels .bb-item { gap: 0; }

/* The one action the bar exists for: filled, and on the raised variant lifted
   out of the row into a circle that overlaps the top edge. */
.bb-item--featured {
  color: var(--bb-feat-text, var(--primary-ink, #fff));
  font-weight: 700;
  /* Its own size when one was set, else exactly what the row uses. */
  font-size: var(--bb-feat-fs, var(--bb-fs, 11px));
}
.bottombar--bar .bb-item--featured,
.bottombar--pill .bb-item--featured,
.bottombar--compact .bb-item--featured {
  background: var(--bb-feat-bg, var(--primary));
  border-radius: 10px; margin: 6px 2px;
}
.bottombar--raised .bb-item--featured { position: relative; }
/* The icon is lifted out of the flow, so a spacer of exactly its size keeps
   this label on the same line as its neighbours' at any height or icon size. */
.bottombar--raised .bb-item--featured::before {
  content: ""; display: block; width: var(--bb-ic, 22px); height: var(--bb-ic, 22px); flex: 0 0 auto;
}
.bottombar--raised .bb-item--featured .bb-ic {
  position: absolute; top: calc(var(--bb-h, 64px) * -0.42);
  display: flex; align-items: center; justify-content: center;
  width: calc(var(--bb-h, 64px) * 0.78); height: calc(var(--bb-h, 64px) * 0.78);
  border-radius: 999px;
  background: var(--bb-feat-bg, var(--primary));
  color: var(--bb-feat-ic, var(--bb-feat-text, var(--primary-ink, #fff)));
  box-shadow: 0 6px 18px -6px rgba(0, 0, 0, .5);
  border: 3px solid var(--bb-feat-ring, var(--bb-bg, var(--surface)));
}
.bottombar--raised .bb-item--featured .bb-ic svg { width: calc(var(--bb-ic, 22px) * 1.15); height: calc(var(--bb-ic, 22px) * 1.15); }

/* Floating pill: detached from the edges, so the page shows through beneath. */
.bottombar--pill {
  left: 12px; right: 12px; bottom: calc(12px + env(safe-area-inset-bottom, 0px));
  border: var(--bb-bw, 1px) solid var(--bb-border, var(--border));
  border-radius: var(--bb-radius, 18px);
  overflow: hidden;
  box-shadow: 0 10px 30px -12px rgba(0, 0, 0, .45);
  padding-bottom: 0;
}


/* The bar covers the end of the page, so give the page its height back — and
   the floating buttons, which live in the same corner, step up over it. Both
   follow the same per-screen rules as the bar itself, so a bar hidden on
   desktop leaves the desktop layout alone. */
body:has(.bottombar) { padding-bottom: var(--bb-h, 64px); }
body:has(.bottombar) .float-stack { bottom: calc(var(--bb-h, 64px) + 18px); }
/* The pill floats 12px clear of the edge, so the stack clears that too. */
body:has(.bottombar--pill) .float-stack { bottom: calc(var(--bb-h, 64px) + 30px); }
@media (min-width: 1025px) {
  body:has(.bottombar--no-desktop) { padding-bottom: 0; }
  body:has(.bottombar--no-desktop) .float-stack { bottom: 18px; }
}
@media (min-width: 769px) and (max-width: 1024px) {
  body:has(.bottombar--no-tablet) { padding-bottom: 0; }
  body:has(.bottombar--no-tablet) .float-stack { bottom: 18px; }
}
@media (max-width: 768px) {
  body:has(.bottombar--no-mobile) { padding-bottom: 0; }
  body:has(.bottombar--no-mobile) .float-stack { bottom: 18px; }
}

@media (min-width: 1025px) { .bottombar--no-desktop { display: none; } }
@media (min-width: 769px) and (max-width: 1024px) { .bottombar--no-tablet { display: none; } }
@media (max-width: 768px) { .bottombar--no-mobile { display: none; } }

/* Light spilling up off the top edge. Placed after the pill so it replaces
   that variant's drop shadow rather than fighting it. */
.bottombar.bottombar--glow {
  box-shadow: 0 -2px var(--bb-glow-size, 18px) 0 var(--bb-glow, var(--primary));
}

/* Logo above the bar: a wrapper so the backdrop styles have something to paint,
   and three positions because the featured item is not always in the middle. */
.bb-logo {
  /* --bb-logo-offset nudges it up (positive) or down (negative) from where it
     rests on the bar's top edge. */
  position: absolute; bottom: calc(var(--bb-h, 64px) - 4px + var(--bb-logo-offset, 0px));
  display: inline-flex; align-items: center; justify-content: center;
  max-width: 60%; pointer-events: none;
}
.bb-logo img { height: var(--bb-logo-h, 46px); width: auto; max-width: 100%; display: block; }
.bb-logo--center { left: 50%; transform: translateX(-50%); }
.bb-logo--left { left: 14px; }
.bb-logo--right { right: 14px; }
/* Eight backdrops for the same picture. Every figure below is a var with the
   old literal as its fallback, so a bar styled before these controls existed
   renders byte-identically. --bb-logo-pad is the vertical padding; the boxy
   styles take twice that horizontally, which is the 6/12 they always had. */
.bb-logo--circle {
  padding: var(--bb-logo-pad, 8px); border-radius: 999px;
  background: var(--bb-logo-bg, var(--bb-bg, var(--surface)));
  border: var(--bb-logo-bw, 2px) solid var(--bb-logo-border, var(--bb-border, var(--border)));
  box-shadow: 0 var(--bb-logo-shadow, 0px) 22px -10px rgba(0, 0, 0, .55);
}
.bb-logo--card {
  padding: var(--bb-logo-pad, 6px) calc(var(--bb-logo-pad, 6px) * 2);
  border-radius: var(--bb-logo-radius, 12px);
  background: var(--bb-logo-bg, var(--bb-bg, var(--surface)));
  border: var(--bb-logo-bw, 1px) solid var(--bb-logo-border, var(--bb-border, var(--border)));
  box-shadow: 0 var(--bb-logo-shadow, 8px) 22px -10px rgba(0, 0, 0, .55);
}
/* An accent ring drawn outside the box, so the fill stays the logo's own. */
.bb-logo--ring {
  padding: var(--bb-logo-pad, 8px); border-radius: 999px;
  background: var(--bb-logo-bg, var(--bb-bg, var(--surface)));
  box-shadow: 0 0 0 var(--bb-logo-bw, 3px) var(--bb-logo-border, var(--bb-feat-bg, var(--primary)));
}
/* Border only — nothing behind the logo. */
.bb-logo--outline {
  padding: var(--bb-logo-pad, 6px) calc(var(--bb-logo-pad, 6px) * 2);
  border-radius: var(--bb-logo-radius, 12px);
  border: var(--bb-logo-bw, 2px) solid var(--bb-logo-border, var(--bb-feat-bg, var(--primary)));
}
/* A filled pill in the accent colour — the loudest of the set. */
.bb-logo--badge {
  padding: var(--bb-logo-pad, 6px) calc(var(--bb-logo-pad, 6px) * 2);
  border-radius: var(--bb-logo-radius, 999px);
  background: var(--bb-logo-bg, var(--bb-feat-bg, var(--primary)));
  box-shadow: 0 var(--bb-logo-shadow, 10px) 24px -12px rgba(0, 0, 0, .6);
}
/* Lifted off the bar by a shadow, with no chrome of its own. */
.bb-logo--shadow {
  filter: drop-shadow(0 var(--bb-logo-shadow, 6px) 14px var(--bb-logo-border, rgba(0, 0, 0, .55)));
}
.bb-logo--glow { filter: drop-shadow(0 0 var(--bb-logo-glow, 10px) var(--bb-logo-border, var(--bb-feat-bg, var(--primary)))); }

/* Motion. Every one of these is off unless it was chosen in the admin. */
@keyframes bb-float { 0%, 100% { translate: 0 0; } 50% { translate: 0 -6px; } }
@keyframes bb-pulse { 0%, 100% { scale: 1; } 50% { scale: 1.06; } }
@keyframes bb-bounce { 0%, 100% { translate: 0 0; } 40% { translate: 0 -7px; } 60% { translate: 0 -3px; } }
@keyframes bb-glow {
  0%, 100% { box-shadow: 0 6px 18px -6px rgba(0, 0, 0, .5); }
  50% { box-shadow: 0 6px 18px -6px rgba(0, 0, 0, .5), 0 0 0 8px color-mix(in srgb, var(--bb-feat-bg, var(--primary)) 30%, transparent); }
}
@keyframes bb-sheen { 0% { background-position: -140% 0; } 60%, 100% { background-position: 240% 0; } }

.bb-logo--float { animation: bb-float 3.2s ease-in-out infinite; }
.bb-logo--pulse { animation: bb-pulse 2.4s ease-in-out infinite; }
/* A band of light travelling across the logo, masked to the image itself. */
.bb-logo--sheen { position: absolute; overflow: hidden; }
.bb-logo--sheen::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(100deg, transparent 40%, rgba(255, 255, 255, .55) 50%, transparent 60%);
  background-size: 220% 100%;
  animation: bb-sheen 3.6s ease-in-out infinite;
}

.bottombar--feat-pulse .bb-item--featured { animation: bb-pulse 2s ease-in-out infinite; }
.bottombar--feat-bounce .bb-item--featured { animation: bb-bounce 2.4s ease-in-out infinite; }
/* The glow belongs on the circle when there is one, else on the whole item. */
.bottombar--feat-glow.bottombar--raised .bb-item--featured .bb-ic { animation: bb-glow 2.2s ease-in-out infinite; }
.bottombar--feat-glow:not(.bottombar--raised) .bb-item--featured {
  animation: bb-glow 2.2s ease-in-out infinite; border-radius: 10px;
}
.bottombar--feat-shine .bb-item--featured { position: relative; overflow: hidden; }
.bottombar--feat-shine .bb-item--featured::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(100deg, transparent 40%, rgba(255, 255, 255, .45) 50%, transparent 60%);
  background-size: 220% 100%;
  animation: bb-sheen 3s ease-in-out infinite;
}

@media (prefers-reduced-motion: reduce) {
  .bb-logo--float, .bb-logo--pulse, .bb-logo--sheen::after,
  .bottombar--feat-pulse .bb-item--featured,
  .bottombar--feat-bounce .bb-item--featured,
  .bottombar--feat-glow .bb-item--featured,
  .bottombar--feat-glow .bb-item--featured .bb-ic,
  .bottombar--feat-shine .bb-item--featured::before { animation: none; }
  .bb-item, .bottombar--item-underline .bb-item::after { transition: none; }
  .bottombar--item-lift .bb-item:hover, .bottombar--item-scale .bb-item:hover { transform: none; }
}

/* ---- Announcement popup ------------------------------------------------
   Three shapes off one card: a centred modal, a sheet on the bottom edge,
   and a corner card that leaves the page usable. POPUP_JS decides whether it
   is shown at all; the .open class is only ever about the animation. ------ */
.popup { position: fixed; inset: 0; z-index: 1000; display: flex; pointer-events: none; }
.popup[hidden] { display: none; }
/* pointer-events is off on the container so a corner card leaves the rest of
   the page clickable; the backdrop has to opt back in or clicking outside a
   centred popup does nothing. */
.popup-backdrop {
  position: absolute; inset: 0; pointer-events: auto;
  background: var(--pop-backdrop, rgba(0, 0, 0, .6));
  opacity: 0; transition: opacity .25s ease; backdrop-filter: blur(2px);
}
.popup.open .popup-backdrop { opacity: 1; }
.popup-card {
  position: relative; z-index: 1; pointer-events: auto; overflow: hidden;
  width: 100%; max-width: var(--pop-w, 460px);
  background: var(--pop-bg, var(--surface, #f7f8fa));
  color: var(--pop-text, var(--ink, #16202c));
  border: 1px solid var(--pop-border, var(--border, rgba(255, 255, 255, .12)));
  border-radius: var(--pop-radius, 16px);
  box-shadow: 0 30px 80px rgba(0, 0, 0, .45);
  transition: transform .28s cubic-bezier(.2, .8, .2, 1), opacity .28s ease;
}
/* The glyph, not an icon from the set — same call the mobile menu's close makes,
   and it takes the card's own colour on every theme. */
.popup-x {
  position: absolute; top: 8px; right: 10px; z-index: 2;
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; padding: 0; cursor: pointer; font-size: 17px; line-height: 1;
  color: inherit; background: transparent;
  border: 0; border-radius: 999px; opacity: .55; transition: opacity .2s ease, background .2s ease;
}
.popup-x:hover { opacity: 1; background: rgba(127, 127, 127, .18); }
.popup-img { display: block; width: 100%; height: auto; }
.popup-body { padding: 20px 22px 4px; }
/* An h2 so a theme that paints its headings (SA's gold, say) paints this too;
   a heading colour set on the Template screen is emitted inline and wins. */
.popup-head {
  margin: 0; padding-right: 26px;
  font-family: var(--font-heading, inherit); font-size: 20px; font-weight: 700; line-height: 1.3;
}
.popup-text { margin-top: 8px; font-size: 14px; line-height: 1.65; opacity: .85; }
.popup-text p { margin: 0; min-height: 1px; }
.popup-actions { display: flex; flex-wrap: wrap; gap: 10px; padding: 16px 22px 4px; }
.popup-actions .header-cta { flex: 1 1 auto; justify-content: center; }
.popup-off {
  display: flex; align-items: center; gap: 8px; padding: 14px 22px 18px;
  font-size: 12.5px; opacity: .7; cursor: pointer;
}
.popup-off input { width: 14px; height: 14px; accent-color: var(--primary, #6d8cff); cursor: pointer; }
/* Only the two blocking shapes freeze the page behind them. */
html.popup-lock { overflow: hidden; }

/* centred modal */
.popup--center { align-items: center; justify-content: center; padding: 24px; }
.popup--center .popup-card { transform: translateY(12px) scale(.97); opacity: 0; }
.popup--center.open .popup-card { transform: none; opacity: 1; }

/* sheet on the bottom edge — full width, rounded on top only */
.popup--sheet { align-items: flex-end; justify-content: center; }
.popup--sheet .popup-card {
  max-width: var(--pop-w, 560px); border-radius: var(--pop-radius, 16px) var(--pop-radius, 16px) 0 0;
  border-bottom: 0; transform: translateY(100%);
}
.popup--sheet.open .popup-card { transform: none; }

/* corner card — no backdrop, the page stays live behind it. The container needs
   a width of its own: pinned to a corner it would otherwise shrink-wrap, and
   the card's width:100% would resolve against nothing. */
.popup--corner {
  inset: auto; padding: 18px;
  width: 100%; max-width: calc(var(--pop-w, 340px) + 36px);
}
.popup--corner .popup-card { max-width: var(--pop-w, 340px); opacity: 0; }
.popup--corner.open .popup-card { opacity: 1; transform: none; }
.popup--bottom-right { right: 0; bottom: 0; }
.popup--bottom-left { left: 0; bottom: 0; }
.popup--top-right { right: 0; top: 0; }
.popup--top-left { left: 0; top: 0; }
.popup--bottom-right .popup-card, .popup--top-right .popup-card { transform: translateX(24px); }
.popup--bottom-left .popup-card, .popup--top-left .popup-card { transform: translateX(-24px); }
/* Clear of the bottom bar, which owns the same corner. */
body:has(.bottombar) .popup--bottom-right, body:has(.bottombar) .popup--bottom-left {
  bottom: calc(var(--bb-h, 64px) + 8px);
}

/* The screen gate is enforced twice: POPUP_JS drops the element on load so a
   hidden screen never spends one of the visitor's views, and these rules cover
   a resize past a breakpoint after that. */
@media (min-width: 1025px) { .popup--no-desktop { display: none; } }
@media (min-width: 769px) and (max-width: 1024px) { .popup--no-tablet { display: none; } }
@media (max-width: 768px) { .popup--no-mobile { display: none; } }

@media (prefers-reduced-motion: reduce) {
  .popup-card, .popup-backdrop { transition: none; }
}

/* ---- Mobile overrides (kept LAST so they beat the base rules above) ---- */
@media (max-width: 768px) {
  /* A corner card on a phone is a sheet in practice — full width reads better
     than a 340px card floating in a 375px viewport. */
  .popup--corner { left: 0; right: 0; padding: 12px; }
  .popup--corner .popup-card { max-width: none; transform: translateY(16px); }
  .popup--center { padding: 16px; }
  .popup-body { padding: 16px 18px 4px; }
  .popup-head { font-size: 18px; }
  .popup-actions { padding: 14px 18px 4px; }
  .popup-actions .header-cta { flex: 1 1 100%; }
  .popup-off { padding: 12px 18px 16px; }
  body.has-sb--left .site-header, body.has-sb--left .announce-bar { margin-left: 0; }
  body.has-sb--right .site-header, body.has-sb--right .announce-bar { margin-right: 0; }
  .site-sidebar { display: none; }
  body.has-sb--left { padding-left: 0; }
  body.has-sb--right { padding-right: 0; }
  /* Its own peek below 768 when the block gave one — including 0%, which is
     how "flush on mobile" is expressed. */
  .slider { --slider-peek-now: var(--slider-peek-m, var(--slider-peek, 0%)); }
  .center-slot { display: none; }
  .center-top { width: auto; }
  [data-fs-m] { font-size: var(--fs-m) !important; }
  [data-fw-m] { font-weight: var(--fw-m) !important; }
  [data-fg-m] { color: var(--fg-m) !important; }
  [data-ff-m] { font-family: var(--ff-m) !important; }
  [data-mt-m] { margin-top: var(--mt-m) !important; }
  [data-mb-m] { margin-bottom: var(--mb-m) !important; }
  /* A button whose corners differ on a phone (Style → Button). */
  [data-br-m] { border-radius: var(--br-m) !important; }
  .txfeed-grid { grid-template-columns: repeat(var(--tx-cols-m, 1), 1fr); }
  /* Transaction feed → Mobile → rows shown. By position, so a rotating feed
     keeps its top rows on screen. */
  [data-tx-count-m="1"] .tx-row:nth-child(n+2), [data-tx-count-m="2"] .tx-row:nth-child(n+3), [data-tx-count-m="3"] .tx-row:nth-child(n+4), [data-tx-count-m="4"] .tx-row:nth-child(n+5), [data-tx-count-m="5"] .tx-row:nth-child(n+6), [data-tx-count-m="6"] .tx-row:nth-child(n+7), [data-tx-count-m="7"] .tx-row:nth-child(n+8), [data-tx-count-m="8"] .tx-row:nth-child(n+9), [data-tx-count-m="9"] .tx-row:nth-child(n+10), [data-tx-count-m="10"] .tx-row:nth-child(n+11), [data-tx-count-m="11"] .tx-row:nth-child(n+12), [data-tx-count-m="12"] .tx-row:nth-child(n+13), [data-tx-count-m="13"] .tx-row:nth-child(n+14), [data-tx-count-m="14"] .tx-row:nth-child(n+15), [data-tx-count-m="15"] .tx-row:nth-child(n+16), [data-tx-count-m="16"] .tx-row:nth-child(n+17), [data-tx-count-m="17"] .tx-row:nth-child(n+18), [data-tx-count-m="18"] .tx-row:nth-child(n+19), [data-tx-count-m="19"] .tx-row:nth-child(n+20), [data-tx-count-m="20"] .tx-row:nth-child(n+21), [data-tx-count-m="21"] .tx-row:nth-child(n+22), [data-tx-count-m="22"] .tx-row:nth-child(n+23), [data-tx-count-m="23"] .tx-row:nth-child(n+24), [data-tx-count-m="24"] .tx-row:nth-child(n+25) { display: none; }
  .block--marquee { padding: 10px 0; }
  /* --- General mobile polish --- */
  .announce-inner { font-size: 12px; padding-top: 6px; padding-bottom: 6px; }
  .block { padding: 24px 0; }
  .block--hero { padding: 32px 0; }
  .block--page-header { padding: 36px 0; }

  /* --- Per-block mobile tuning --- */
  .block--hero p { font-size: 16px; }
  .block--text h2 { font-size: 23px; }
  .block--cta .card { padding: 30px 20px; }
  .block--cta h2 { font-size: 22px; }
  .block--features h2 { font-size: 23px; margin-bottom: 26px; }
  .block--features .feature { padding: 20px; }
  .block--imagetext .split { gap: 26px; }
  .split__body--panel { padding: 18px; }
  .block--steps .step { padding: 20px 16px; }
  .logo-strip { gap: 22px; }
  .logo-strip--marquee .logo-set { gap: 22px; padding-right: 22px; }
  .articles-bar { flex-wrap: wrap; align-items: flex-start; margin-bottom: 20px; }
  .cards-head { margin-bottom: 22px; }
  .btn { padding: 11px 20px; font-size: 14.5px; }
  .cta-buttons { gap: 10px; }
  .steps-cta { padding: 12px 26px; }
}

/* ===== SBO theme ===== */
:root{
  --primary:#2f6bff; --primary-ink:#ffffff;
  --ink:#e3ebf7; --muted:#93a4bd;
  --bg:#070c1c; --surface:#0f1830; --border:#1d2b4d; --radius:14px;
}
.block--marquee{ --mq-bg:linear-gradient(90deg,#101a34,#0d1730); --mq-ink:#e3ebf7; }
body{ background:radial-gradient(1200px 600px at 50% -10%, #14224a 0%, #070c1c 55%) no-repeat, #070c1c; }
.site-header{ background:var(--header-bg, rgba(9,14,32,.9)); border-bottom:var(--header-border-w, 1px) var(--header-border-style, solid) var(--header-border, var(--border)); backdrop-filter:blur(10px); }
.site-header .brand{ color:var(--header-brand, #fff); }
.site-nav a{ color:var(--nav-link, #b8c6dd); } .site-nav a:hover{ color:var(--nav-hover, #fff); }
.header-cta{ --btn-fill:var(--btn-bg, var(--theme-btn-bg, linear-gradient(180deg,#25d366,#12b357))); --btn-ink:var(--btn-text, var(--theme-btn-text, #03210f)); }
h1,h2,h3{ color:#f2f6fc; }
a{ color:#4f8bff; }
.btn{ background:var(--theme-btn-bg, linear-gradient(180deg,#3b78ff,#2f6bff)); box-shadow:0 6px 18px rgba(47,107,255,.35); }
.btn--secondary{ background:#16233f; color:#dbe6f7; }
.btn--outline{ background:transparent; color:#4f8bff; box-shadow:inset 0 0 0 1.5px #2f6bff; }
.card,.ucard,.feature,.block--cta .card{ background:linear-gradient(180deg,#101a34,#0d1730); border:1px solid var(--border); border-radius:var(--radius); }
.ucard-body p,.feature p,.faq-item p{ color:#9fb0c9; }
/* Article body must stay readable even when the theme text token is dark. */
.article-content,.article-content p,.article-content li{ color:#c9d5ea; }
.ph-current{ color:#e3ebf7; }
.block--faq .faq-item{ border-top:1px solid var(--border); }
.site-footer{ border-top:1px solid var(--footer-border, var(--border)); color:var(--footer-color, #8497b3); background:var(--footer-bg, transparent); }
.site-footer .footer-copy{ color:var(--footer-color, #8497b3); }
.slider-arrow{ background:var(--slider-arrow-bg, #101a34); border-color:var(--border); color:var(--slider-arrow-color, #dbe6f7); }
.slider-dot{ background:var(--slider-dot-color, #26365c); } .slider-dot[aria-current="true"]{ background:var(--slider-dot-active, #2f6bff); }

:root{--primary:#2f6bff;--primary-ink:#ffffff;--ink:#e3ebf7;--bg:#070c1c;--surface:#0f1830;--muted:#93a4bd;--border:#1d2b4d;--radius:14px;--container:1080px;--base-size:16px;--font-body:Anuphan,ui-sans-serif,system-ui,sans-serif;--font-heading:Anuphan,ui-sans-serif,system-ui,sans-serif;--theme-btn-radius:10px;--theme-btn-bg:linear-gradient(90deg, #19d08a, #11b679);--theme-btn-text:#0a1733;--theme-btn-hbg:linear-gradient(90deg, #11b679, #19d08a)}

.btn.btn--secondary{background:linear-gradient(180deg, #2563eb, #2563eb);box-shadow:none}
.header-cta.header-cta--secondary{--btn-fill:var(--btn-bg, linear-gradient(180deg, #2563eb, #2563eb));box-shadow:none}
.btn.btn--outline{box-shadow:inset 0 0 0 1.5px #1d2b72;color:#dcdfef}
.btn.btn--outline:hover{background:#0a1545;color:#b6bddd}
.header-cta.header-cta--outline{box-shadow:inset 0 0 0 1.5px #1d2b72;--btn-ink:var(--btn-text, #dcdfef)}
.header-cta.header-cta--outline:hover{background:var(--btn-hover-bg, #0a1545);color:var(--btn-hover-text, #b6bddd)}
