@layer theme {
/* site.css */
/* thallo-render default theme — modern-SaaS reference. Copy this theme into
   your app's themes/ directory as a starting point. Shell selectors are
   NAMESPACED (.site-header/.site-nav/.site-footer): block templates render
   semantic header/nav/footer elements of their own and must never inherit
   shell styling. Dark mode only re-maps the variables, and is keyed on
   html[data-theme="dark"] — the no-flash resolver's single source of truth
   (color-mode spec §3.3), NOT the OS media query, so an explicit light/dark
   choice always wins over the operating-system preference. */
:root {
  /* Typefaces as tokens (design settings): body is Figtree; display follows body unless the
     site picks a serif pairing. */
  --font-body: "Figtree", "Figtree Fallback", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-display: var(--font-body);
  --bg: #ffffff;
  --surface: #f6f7f9;
  --surface-2: #eef0f4;
  --ink: #0f172a;
  --muted: #64748b;
  --line: #e2e8f0;
  --accent: #2563eb;
  --accent-ink: #ffffff;
  /* Text over pictures and dark scrims: light whatever the colour mode or the site's settings.
     (--accent-ink is the label ON the accent, and is black on a light brand colour.) */
  --on-media: #ffffff;
  /* media-less --hero slide base (modern-blocks): ALWAYS dark — the overlay
     ink is white in both modes; no dark-mode override on purpose. */
  --hero-fallback-bg: #0f172a;
  /* Elevation scale (Tailwind-derived). Each token composes its color from
     --shadow-color and its opacity from calc(<base>% * --shadow-strength), so an
     element can retint (colored shadow) or restrength (opacity modifier) its shadow. */
  --shadow-color: #0f172a;   /* slate-900; dark mode + operators override */
  --shadow-strength: 1;
  --shadow-none: none;
  --shadow-2xs: 0 1px color-mix(in srgb, var(--shadow-color) calc(5% * var(--shadow-strength)), transparent);
  --shadow-xs:  0 1px 2px 0 color-mix(in srgb, var(--shadow-color) calc(5% * var(--shadow-strength)), transparent);
  --shadow-sm:  0 1px 3px 0 color-mix(in srgb, var(--shadow-color) calc(10% * var(--shadow-strength)), transparent), 0 1px 2px -1px color-mix(in srgb, var(--shadow-color) calc(10% * var(--shadow-strength)), transparent);
  --shadow-md:  0 4px 6px -1px color-mix(in srgb, var(--shadow-color) calc(10% * var(--shadow-strength)), transparent), 0 2px 4px -2px color-mix(in srgb, var(--shadow-color) calc(10% * var(--shadow-strength)), transparent);
  --shadow-lg:  0 10px 15px -3px color-mix(in srgb, var(--shadow-color) calc(10% * var(--shadow-strength)), transparent), 0 4px 6px -4px color-mix(in srgb, var(--shadow-color) calc(10% * var(--shadow-strength)), transparent);
  --shadow-xl:  0 20px 25px -5px color-mix(in srgb, var(--shadow-color) calc(10% * var(--shadow-strength)), transparent), 0 8px 10px -6px color-mix(in srgb, var(--shadow-color) calc(10% * var(--shadow-strength)), transparent);
  --shadow-2xl: 0 25px 50px -12px color-mix(in srgb, var(--shadow-color) calc(25% * var(--shadow-strength)), transparent);
  --shadow: var(--shadow-md);
  --radius: 12px;
  --radius-lg: 20px;
  /* The rest of the radius scale, as the Style tab's tokens name it (theme.json: radius.sm = 6px,
     radius.md = var(--radius)). Blocks read these for their own default corners — a badge, the
     tabs' strip — and until they were defined here `var(--radius-md)` was an invalid declaration:
     those corners shipped square while the stylesheet said rounded. */
  --radius-sm: 6px;
  --radius-md: var(--radius);
  --container: 72rem;
  --content: 46rem;
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 1rem;
  --space-4: 1.5rem;
  --space-5: 2.5rem;
  --space-6: 4rem;
  --space-7: 6rem;
}
html[data-theme="dark"] {
  --bg: #0b1120;
  --surface: #111a2e;
  --surface-2: #16213a;
  --ink: #e2e8f0;
  --muted: #94a3b8;
  --line: #1e293b;
  --accent: #3b82f6;
  --accent-ink: #ffffff;
  /* Shadows recompute from the scale; dark just darkens the tint and boosts strength. */
  --shadow-color: #000000;
  --shadow-strength: 2.5;
}

* { box-sizing: border-box; }

/* Skip link (theme-runtime spec §7): visually hidden until keyboard focus. */
.skip-link {
  position: absolute; left: var(--space-3); top: var(--space-3); z-index: 100;
  padding: var(--space-2) var(--space-3); background: var(--surface); color: var(--ink);
  border-radius: 0.375rem; transform: translateY(-200%);
}
.skip-link:focus { transform: none; }

html { scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 17px/1.65 var(--font-body);
  -webkit-font-smoothing: antialiased;
}
/* Form controls don't inherit fonts by UA default — this keeps author-authored controls
   (e.g. inside an html block) on the theme face; every theme/shop control already opts
   in individually, so this is a guarantee, not a change. */
button, input, select, textarea { font: inherit; }
/* A heading that wraps shares its words between its lines, instead of leaving one alone on the last. */
h1, h2, h3, h4 { font-family: var(--font-display); line-height: 1.15; letter-spacing: -0.02em; text-wrap: balance; }
h1 { font-size: clamp(1.9rem, 1.4rem + 2vw, 2.75rem); }
h2 { font-size: clamp(1.5rem, 1.2rem + 1.2vw, 2rem); }
a { color: var(--accent); }
img { max-width: 100%; display: block; }

.site-header {
  position: sticky;
  top: 0;
  z-index: 10;
  /* The colour this bar is painted with, named for the Style tab's Background opacity: with no
     colour chosen, that setting mixes THIS one (THEMING.md §12.3). */
  --t-surface-default: var(--bg);
  background: var(--bg);
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line);
}
.site-header__inner {
  max-width: var(--container);
  margin-inline: auto;
  padding: var(--space-3) var(--space-4);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}
.site-name { font-weight: 700; font-size: 1.05rem; color: var(--ink); text-decoration: none; display: inline-flex; align-items: center; }
.site-logo { display: block; height: 2rem; width: auto; max-width: 12rem; object-fit: contain; }
/* Dark-logo variant (site-identity spec): the swap applies ONLY inside the
   template-emitted --has-dark modifier — without a dark upload the single
   light logo stays visible in dark mode, unchanged. */
.site-logo--dark { display: none; }
html[data-theme="dark"] .site-name--has-dark .site-logo--light { display: none; }
html[data-theme="dark"] .site-name--has-dark .site-logo--dark { display: block; }

/* Region-backed chrome (global-regions spec): modifier classes from region settings. */
/* Sticky raises the bar; it does not repaint it. (It once set a solid background here, after the
   translucent one above, so switching Sticky on cost the header its blur.) */
.thallo-region-header--sticky { position: sticky; top: 0; z-index: 40; }
.thallo-region-header--full .site-header__inner,
.thallo-region-footer--full .site-footer__inner { max-width: none; }
.thallo-region .site-header__inner,
.thallo-region .site-footer__inner { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); flex-wrap: wrap; }
/* The header & footer stage with no page to show (partials/region-stage-placeholder.twig): a placeholder body between the regions. */
.thallo-region-preview__main { max-width: 72rem; margin: 0 auto; padding: var(--space-6) var(--space-4); }
.thallo-region-preview__placeholder {
  border: 2px dashed var(--line);
  border-radius: var(--radius);
  padding: var(--space-7) var(--space-5);
  text-align: center;
  color: var(--muted);
  font-size: 0.95rem;
}
.site-nav { display: flex; gap: var(--space-4); flex-wrap: wrap; }
/* The fallback nav is now a list inside the shared mobile disclosure
   (theme-runtime spec §7) — bare list reset; navigation.css owns the 48rem
   show/hide behavior via .site-nav__mobile / .site-nav__list. */
.site-nav__list {
  display: flex; gap: var(--space-4); flex-wrap: wrap; align-items: center;
  list-style: none; margin: 0; padding: 0;
}
.site-nav a {
  color: var(--muted);
  text-decoration: none;
  font-size: 0.95rem;
  transition: color 0.15s ease;
}
.site-nav a:hover { color: var(--ink); }

.preview-banner {
  display: flex;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-4);
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  font-size: 0.9rem;
  color: var(--muted);
}

/* Text for assistive technology only — e.g. the "(opens in a new tab)" a navigation link adds
   when it opens a new window, which a sighted reader infers from the browser and a screen
   reader cannot. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

main { min-height: 60vh; padding-block: var(--space-5) var(--space-7); }

/* Centered layout constrains ONLY the entry-content wrapper (spec P2):
   block roots are main-direct (display:contents wrappers) and own their
   width; blocks.css carries their .layout--centered presentation. */
.entry-content {
  max-width: var(--content);
  margin-inline: auto;
  padding-inline: var(--space-4);
}
.body { margin-top: var(--space-3); white-space: pre-wrap; }

.site-footer {
  border-top: 1px solid var(--line);
  color: var(--muted);
  --t-surface-default: var(--surface);
  background: var(--surface);
}
.site-footer__inner {
  max-width: var(--container);
  margin-inline: auto;
  padding: var(--space-5) var(--space-4);
}

/* Preview admin bar (admin-bar feature): status dot + edit/design/exit links. */
.preview-banner__status { display: inline-flex; align-items: center; gap: 0.5rem; }
.preview-banner__dot { width: 0.55rem; height: 0.55rem; border-radius: 999px; flex-shrink: 0; }
.preview-banner__dot--live { background: #16a34a; }
.preview-banner__dot--draft { background: #d97706; }
.preview-banner__dot--warn { background: #dc2626; }
.preview-banner__actions { display: inline-flex; align-items: center; gap: var(--space-4); }
.preview-banner__action {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  color: var(--muted);
  text-decoration: none;
  font-weight: 500;
}
.preview-banner__action:hover { color: var(--ink); }
.preview-banner__action svg { width: 0.9rem; height: 0.9rem; flex-shrink: 0; }
/* Responsive preview bar — 48rem: the theme's named v1 breakpoint. One clean
   row on mobile: the status ellipsizes instead of wrapping, and the actions
   collapse to icon-only (labels visually hidden, never removed — the SVGs are
   aria-hidden, so the hidden text IS each link's accessible name). */
@media (max-width: 48rem) {
  .preview-banner { align-items: center; }
  /* Block formatting so the anonymous text node actually ellipsizes (a flex
     container clips but never renders the ellipsis glyph). */
  .preview-banner__status {
    display: block; min-width: 0; overflow: hidden;
    white-space: nowrap; text-overflow: ellipsis;
  }
  .preview-banner__dot { display: inline-block; vertical-align: middle; margin-right: 0.5rem; }
  .preview-banner__actions { gap: var(--space-2); flex-shrink: 0; }
  .preview-banner__action { padding: var(--space-2); margin: calc(-1 * var(--space-2)) 0; }
  .preview-banner__action svg { width: 1.1rem; height: 1.1rem; }
  .preview-banner__action-label {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
    white-space: nowrap; border: 0;
  }
}

/* ── Error / not-found pages (404, error) ───────────────────────────────────
   Centered hero, translated from the Tailwind UI "centered" 404 into theme
   tokens: brand comes from --accent, so theme_colors_style() and dark mode
   recolor it for free. Shared by 404.twig and error.twig. */
.error-page {
  min-height: 60vh;
  display: grid;
  align-content: center;
  justify-items: center;
  gap: var(--space-3);
  text-align: center;
  padding-inline: var(--space-4);
}
.error-page__code {
  margin: 0;
  color: var(--accent);
  font-weight: 600;
  font-size: 1rem;
  letter-spacing: 0.01em;
}
.error-page__title {
  margin: 0;
  font-size: clamp(2.5rem, 1.8rem + 3.4vw, 4.5rem);
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -0.03em;
  text-wrap: balance;
}
.error-page__lead {
  margin: 0;
  max-width: 46ch;
  color: var(--muted);
  font-size: 1.15rem;
  text-wrap: pretty;
}
.error-page__actions {
  margin-top: var(--space-2);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
}
.error-page__btn {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.7rem 1.15rem;
  border-radius: var(--radius);
  font-weight: 600;
  font-size: 0.95rem;
  line-height: 1;
  text-decoration: none;
  transition: background 0.15s ease, color 0.15s ease, box-shadow 0.15s ease;
}
.error-page__btn--primary {
  background: var(--accent);
  color: var(--accent-ink);
  box-shadow: var(--shadow-xs);
}
.error-page__btn--primary:hover {
  background: color-mix(in srgb, var(--accent) 88%, #000);
}

/* ── Editorial listing rows (storefront-performance spec §8) ─────────────── */
.listing-rows { margin: 0; padding: 0; list-style: none; }
.listing-row {
  display: flex;
  gap: 1.25rem;
  padding: 1.25rem 0;
  border-bottom: 1px solid var(--line);
  position: relative;
  content-visibility: auto;
  contain-intrinsic-size: auto 110px;
}
.listing-row__media { flex: 0 0 auto; }
.listing-row__media img {
  width: 160px;
  aspect-ratio: 160 / 110;
  object-fit: cover;
  border-radius: 0.5rem;
  display: block;
}
.listing-row__content { min-width: 0; display: grid; gap: 0.25rem; align-content: start; }
.listing-row__title { font-weight: 650; color: var(--ink); text-decoration: none; }
.listing-row__date, .listing-row__meta { font-size: 0.85rem; color: var(--muted); }
.listing-row__excerpt {
  margin: 0;
  color: var(--muted);
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
/* Whole-row affordance ONLY for linked rows (spec §8): stretched link keeps the
   semantic title anchor; routeless rows get no hover/focus treatment. */
.listing-row--linked .listing-row__title::after { content: ""; position: absolute; inset: 0; }
.listing-row--linked:hover .listing-row__title { text-decoration: underline; }
.listing-row--linked:focus-within { outline: 2px solid var(--accent); outline-offset: 2px; }
@media (max-width: 48rem) {
  .listing-row { gap: 0.875rem; }
  .listing-row__media img { width: 96px; aspect-ratio: 96 / 72; }
}
@media (max-width: 20rem) {
  .listing-row { flex-direction: column; }
}

/* ── A single post (entry/post.twig): categories, title, date and lead in the reading column,
   the cover at the container width, then the body's own blocks; the newest other posts and the
   way back to them all below. ──────────────────────────────────────────────────────────── */
.post__header { padding-block: var(--space-5) var(--space-3); display: grid; gap: var(--space-2); }
.post__categories { margin: 0; display: flex; flex-wrap: wrap; gap: var(--space-2); }
.post__category {
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--accent);
  text-decoration: none;
}
a.post__category:hover { text-decoration: underline; }
.post__title {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(2rem, 1.4rem + 2.4vw, 3rem);
  line-height: 1.15;
  letter-spacing: -0.02em;
  text-wrap: balance;
}
.post__meta { margin: 0; font-size: 0.9rem; color: var(--muted); }
.post__lead { margin: var(--space-2) 0 0; font-size: 1.2rem; line-height: 1.55; color: var(--muted); }
.post__cover { max-width: var(--container); margin: 0 auto var(--space-5); padding-inline: var(--space-4); }
.post__cover img { display: block; width: 100%; height: auto; aspect-ratio: 16 / 9; object-fit: cover; border-radius: var(--radius-lg); }
.post__more { margin-top: var(--space-6); padding-block: var(--space-5); border-top: 1px solid var(--line); }
.post__more-title { margin: 0 0 var(--space-2); font-size: 1.25rem; }
.post__all { font-weight: 600; color: var(--accent); text-decoration: none; }
.post__all:hover { text-decoration: underline; }
@media (max-width: 48rem) {
  .post__header { padding-block: var(--space-4) var(--space-3); }
  .post__cover { padding-inline: 0; }
  .post__cover img { border-radius: 0; }
}

/* ── Cross-document view transitions (storefront-performance spec §7): root crossfade
   only — no named elements, no morphs, no JS. The opt-in itself sits inside the
   reduced-motion guard so `reduce` users get instant navigation, not a shorter fade.
   Unsupported browsers ignore the whole rule. Custom themes remove or override this in
   their own CSS. ── */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
  ::view-transition-old(root),
  ::view-transition-new(root) {
    animation-duration: 150ms;
  }
}

/* Below-the-fold relief (spec §6): the footer is the ONLY other content-visibility
   surface (listing rows carry their own). 300px ≈ the default footer's scale; `auto`
   retains the learned size after first paint. */
.site-footer {
  content-visibility: auto;
  contain-intrinsic-size: auto 300px;
}

/* Metric-matched fallback (default-theme-font spec §4): generated with
   @capsizecss/core 4.1.3 + @capsizecss/metrics 4.2.0, verified against the shipped
   subset's head/hhea tables (fonttools): unitsPerEm 1000, ascent 950, descent -250,
   lineGap 0 — exact match with the capsize Figtree tuple. size-adjust additionally
   derives from capsize's latin xWidthAvg = 449 (@capsizecss/metrics 4.2.0), an
   aggregate head/hhea cannot prove — the metrics package is the width authority.
   Upstream source Figtree[wght].ttf sha256
   6d7fb937ffd4ec82f3030857d910846c0d510eb1a0cb5b23f832a980de39c305; deterministic
   subset command (pyftsubset --unicodes=<GF latin> --layout-features='*'
   --flavor=woff2) committed verbatim in fonts/PROVENANCE.md. Regenerate when the
   binary changes. */
@font-face {
  font-family: "Figtree Fallback";
  src: local("Arial"), local("ArialMT");
  size-adjust: 100.7176%;
  ascent-override: 94.3231%;
  descent-override: 24.8219%;
  line-gap-override: 0%;
}

/* blocks.css */
/* ── Starter block library (thallo:blocks:seed) ─────────────────────────────
   One rule set per starter, selectors exactly on the thallo-block-* classes
   the block templates emit. Standalone on purpose: a custom theme adopts the
   starter blocks by copying THIS ONE FILE (templates already fall back to the
   pack default per-template; assets do not). Uses only the variables site.css
   defines (--bg, --surface, --ink, --muted, --line, --accent, --accent-ink,
   spacing/radius/shadow tokens). Band blocks (hero, section, cta) are
   full-bleed by default and carry their OWN inner containers; the dormant
   .layout--centered rules at the end apply only in themes that emit the
   layout classes on <main>. */
.thallo-block { margin-block: var(--space-5); }

/* icon() inline SVGs (icon-library spec): size tracks font-size and color
   tracks currentColor — CSS wins over the SVGs' width/height attributes. */
.thallo-icon { width: 1em; height: 1em; display: inline-block; vertical-align: -0.125em; }

/* Chrome context (global-regions spec): region blocks flow inline within the
   already-contained header/footer inner — no page-band margins, no double
   containment from blocks that carry their own max-width wrappers. */
.thallo-region .thallo-block { margin-block: 0; max-width: none; padding-inline: 0; margin-inline: 0; }
/* The navigation block's own styles live in navigation.css (dedicated asset).
   Its in-region flex-grow rule (align start/center/end needs room to act) moved
   there too, so the whole block is self-contained in one file. */

/* hero — full-bleed gradient band (PageHero anatomy: wrapper + media,
   vertical = centered stack, horizontal = two columns, --reverse swaps) */
.thallo-block-hero {
  margin-block: 0 var(--space-5);
  padding-block: var(--space-7);
  border-bottom: 0;
}
/* background — schema enum: gradient (the original look) | none | muted | inverted.
   The gradient has a colour and a strength of its own (Block tab): two variables, each falling
   back to what the hero always drew — the site accent, at a faint 9%. */
.thallo-block-hero--bg-gradient {
  background: linear-gradient(
    180deg,
    color-mix(in srgb, var(--hero-gradient, var(--accent)) var(--hero-gradient-strength, 9%), var(--bg)),
    var(--bg)
  );
}
.thallo-block-hero--gradient-strength-medium { --hero-gradient-strength: 18%; }
.thallo-block-hero--gradient-strength-strong { --hero-gradient-strength: 32%; }
/* The families are the site accent's palette (ThemeColors), light and dark: a test holds these
   rules to that table, so a hero's emerald is the emerald a site accent would be. */
.thallo-block-hero--gradient-red { --hero-gradient: #dc2626; }
.thallo-block-hero--gradient-orange { --hero-gradient: #c2410c; }
.thallo-block-hero--gradient-amber { --hero-gradient: #b45309; }
.thallo-block-hero--gradient-yellow { --hero-gradient: #a16207; }
.thallo-block-hero--gradient-lime { --hero-gradient: #4d7c0f; }
.thallo-block-hero--gradient-green { --hero-gradient: #15803d; }
.thallo-block-hero--gradient-emerald { --hero-gradient: #047857; }
.thallo-block-hero--gradient-teal { --hero-gradient: #0f766e; }
.thallo-block-hero--gradient-cyan { --hero-gradient: #0e7490; }
.thallo-block-hero--gradient-sky { --hero-gradient: #0369a1; }
.thallo-block-hero--gradient-blue { --hero-gradient: #2563eb; }
.thallo-block-hero--gradient-indigo { --hero-gradient: #4f46e5; }
.thallo-block-hero--gradient-violet { --hero-gradient: #7c3aed; }
.thallo-block-hero--gradient-purple { --hero-gradient: #9333ea; }
.thallo-block-hero--gradient-fuchsia { --hero-gradient: #c026d3; }
.thallo-block-hero--gradient-pink { --hero-gradient: #db2777; }
.thallo-block-hero--gradient-rose { --hero-gradient: #e11d48; }
html[data-theme="dark"] .thallo-block-hero--gradient-red { --hero-gradient: #ef4444; }
html[data-theme="dark"] .thallo-block-hero--gradient-orange { --hero-gradient: #f97316; }
html[data-theme="dark"] .thallo-block-hero--gradient-amber { --hero-gradient: #d97706; }
html[data-theme="dark"] .thallo-block-hero--gradient-yellow { --hero-gradient: #ca8a04; }
html[data-theme="dark"] .thallo-block-hero--gradient-lime { --hero-gradient: #65a30d; }
html[data-theme="dark"] .thallo-block-hero--gradient-green { --hero-gradient: #22c55e; }
html[data-theme="dark"] .thallo-block-hero--gradient-emerald { --hero-gradient: #10b981; }
html[data-theme="dark"] .thallo-block-hero--gradient-teal { --hero-gradient: #14b8a6; }
html[data-theme="dark"] .thallo-block-hero--gradient-cyan { --hero-gradient: #06b6d4; }
html[data-theme="dark"] .thallo-block-hero--gradient-sky { --hero-gradient: #0ea5e9; }
html[data-theme="dark"] .thallo-block-hero--gradient-blue { --hero-gradient: #3b82f6; }
html[data-theme="dark"] .thallo-block-hero--gradient-indigo { --hero-gradient: #6366f1; }
html[data-theme="dark"] .thallo-block-hero--gradient-violet { --hero-gradient: #8b5cf6; }
html[data-theme="dark"] .thallo-block-hero--gradient-purple { --hero-gradient: #a855f7; }
html[data-theme="dark"] .thallo-block-hero--gradient-fuchsia { --hero-gradient: #d946ef; }
html[data-theme="dark"] .thallo-block-hero--gradient-pink { --hero-gradient: #ec4899; }
html[data-theme="dark"] .thallo-block-hero--gradient-rose { --hero-gradient: #f43f5e; }
.thallo-block-hero--bg-none { background: transparent; }
.thallo-block-hero--bg-muted { background: var(--surface-2); }
/* An ink fill takes the page ground as its text: the pair that inverts in BOTH colour modes.
   Never --accent-ink here — that is the label on the accent, and on a light brand colour it is
   black. */
.thallo-block-hero--bg-inverted { background: var(--ink); color: var(--bg); }
.thallo-block-hero--bg-inverted .thallo-block-hero__title { color: var(--bg); }
.thallo-block-hero--bg-inverted .thallo-block-hero__description {
  color: color-mix(in srgb, var(--bg) 72%, transparent);
}
.thallo-block-hero__inner {
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}
.thallo-block-hero--horizontal .thallo-block-hero__inner {
  display: grid;
  grid-template-columns: 1fr;
  align-items: center;
}
@media (min-width: 52rem) {
  .thallo-block-hero--horizontal .thallo-block-hero__inner { grid-template-columns: 1fr 1fr; }
  /* split — schema enum: equal (above) | copy | media: the wider column takes three fifths. */
  .thallo-block-hero--split-copy .thallo-block-hero__inner { grid-template-columns: 3fr 2fr; }
  .thallo-block-hero--split-media .thallo-block-hero__inner { grid-template-columns: 2fr 3fr; }
  .thallo-block-hero--horizontal.thallo-block-hero--reverse .thallo-block-hero__wrapper { order: 2; }
  .thallo-block-hero--horizontal.thallo-block-hero--reverse .thallo-block-hero__media { order: 1; }
}
.thallo-block-hero--vertical .thallo-block-hero__wrapper { text-align: center; }
.thallo-block-hero--vertical .thallo-block-hero__description,
.thallo-block-hero--vertical .thallo-block-hero__media img { margin-inline: auto; }
.thallo-block-hero--vertical .thallo-block-hero__links { justify-content: center; }
.thallo-block-hero__headline {
  margin: 0 0 var(--space-3);
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--accent);
}
.thallo-block-hero__title {
  margin: 0;
  font-size: clamp(2.25rem, 1.6rem + 3vw, 3.75rem);
  line-height: 1.08;
  letter-spacing: -0.03em;
}
.thallo-block-hero__description {
  max-width: var(--content);
  margin: var(--space-3) 0 0;
  color: var(--muted);
  font-size: clamp(1.05rem, 1rem + 0.4vw, 1.3rem);
  line-height: 1.55;
}
.thallo-block-hero__links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-4);
}
/* aside blocks fill the media column: no band clamp, no inner gutter */
.thallo-block-hero__media--blocks { min-width: 0; }
.thallo-block-hero__media--blocks > .thallo-block { max-width: none; padding-inline: 0; margin-inline: 0; }
/* The media box is the `media` style target: it carries the corners and the shadow (so a
   radius or shadow setting lands here) and clips the image to them. */
.thallo-block-hero__media:not(.thallo-block-hero__media--blocks) {
  max-width: min(100%, 40rem);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  overflow: hidden;
}
.thallo-block-hero__media img {
  display: block;
  /* Layout reservation (storefront-performance spec §5): explicit width + ratio
     reserve the media box before the image loads — no CLS on the hero. */
  width: 100%;
  max-height: 26rem;
  aspect-ratio: 16 / 9;
  object-fit: cover;
}
/* Links rows: the button block collapses its align wrapper and takes the
   context-forced size (hero=xl, cta=lg) — the Nuxt UI links behavior. */
.thallo-block-hero__links .thallo-block-button,
.thallo-block-cta__links .thallo-block-button { display: contents; }
.thallo-block-hero__links .thallo-block-button__link { padding: 0.85rem 1.9rem; font-size: 1.05rem; }
.thallo-block-cta__links .thallo-block-button__link { padding: 0.7rem 1.6rem; font-size: 1rem; }

/* spacer */
.thallo-block-spacer { margin: 0; }
.thallo-block-spacer--small { height: var(--space-3); }
.thallo-block-spacer--medium { height: var(--space-5); }
.thallo-block-spacer--large { height: var(--space-6); }

/* cta — contained band (PageCTA anatomy: 5 variants, orientation, reverse). The root is the
   band's spacing and width box; __inner is the `panel` style target — the variants paint its
   background, border and shadow, so colours, border, corners and shadow settings land there. */
.thallo-block-cta { padding-inline: var(--space-4); }
.thallo-block-cta__inner {
  max-width: var(--container);
  margin-inline: auto;
  padding: var(--space-6) var(--space-5);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}
.thallo-block-cta--horizontal .thallo-block-cta__inner {
  display: grid;
  grid-template-columns: 1fr;
  align-items: center;
}
@media (min-width: 52rem) {
  .thallo-block-cta--horizontal .thallo-block-cta__inner { grid-template-columns: 1fr 1fr; }
  .thallo-block-cta--horizontal.thallo-block-cta--reverse .thallo-block-cta__wrapper { order: 2; }
}
.thallo-block-cta--vertical .thallo-block-cta__wrapper { text-align: center; }
.thallo-block-cta--vertical .thallo-block-cta__links { justify-content: center; }
/* a chosen links alignment beats the orientation's default */
.thallo-block-cta--links-start .thallo-block-cta__links { justify-content: flex-start; }
.thallo-block-cta--links-center .thallo-block-cta__links { justify-content: center; }
.thallo-block-cta--links-end .thallo-block-cta__links { justify-content: flex-end; }
.thallo-block-cta__title { margin: 0; font-size: clamp(1.6rem, 1.3rem + 1.2vw, 2.25rem); letter-spacing: -0.02em; }
.thallo-block-cta__description {
  margin: var(--space-3) 0 0; max-width: var(--content);
  /* softened from the panel's text colour (the Style tab's), not pinned to a theme token */
  color: color-mix(in srgb, currentColor 72%, transparent);
}
.thallo-block-cta--vertical .thallo-block-cta__description { margin-inline: auto; }
.thallo-block-cta__links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-4);
}
/* variants — solid (inverted band), outline (ring), soft (tint), subtle (tint+ring), naked */
.thallo-block-cta--solid .thallo-block-cta__inner { background: var(--ink); color: var(--bg); }
.thallo-block-cta--outline .thallo-block-cta__inner { background: var(--bg); border: 1px solid var(--line); box-shadow: var(--shadow); }
.thallo-block-cta--soft .thallo-block-cta__inner { background: var(--surface); }
.thallo-block-cta--subtle .thallo-block-cta__inner { background: var(--surface); border: 1px solid var(--line); }
.thallo-block-cta--naked .thallo-block-cta__inner { padding-inline: 0; }
.thallo-block-cta--solid .thallo-block-cta__links .thallo-block-button__link--solid {
  background: var(--bg);
  color: var(--ink);
}

/* image */
.thallo-block-image {
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--space-4);
}
.thallo-block-image img {
  max-width: 100%;
  box-shadow: var(--shadow);
}
/* Width is a settings token on the figure (t-w-*); a full-bleed figure loses its gutter. */
.thallo-block-image.t-w-full { padding-inline: 0; }
.thallo-block-image.t-w-full img { width: 100%; border-radius: 0; box-shadow: none; }
/* Exact sizes are the img's width/height attributes (blocks/image.twig). A height makes a box the
   picture fills — cropped, never stretched — which matters once max-width holds it inside a
   narrower column. Fill is the column's width. */
.thallo-block-image img[height] { object-fit: cover; }
.thallo-block-image--fill img { width: 100%; }
.thallo-block-image figcaption {
  color: var(--muted);
  font-size: 0.9rem;
  margin-top: var(--space-2);
  text-align: center;
}

/* rich_text — comfortable reading measure */
.thallo-block-rich_text {
  max-width: var(--content);
  margin-inline: auto;
  padding-inline: var(--space-4);
}

/* heading — a single heading/label on the content measure. Type scale comes from the
   theme's base h1–h6; this only handles placement + alignment (color is inline). */
.thallo-block-heading {
  max-width: var(--content);
  margin-inline: auto;
  padding-inline: var(--space-4);
}
/* Alignment, colour and typography are settings (t-text-*, t-fg-*, t-size-*). */

/* container — free-form styled wrapper; per-instance backgrounds come in as
   CSS custom properties on the style attribute (typed validated fields only). */
.thallo-block-container {
  position: relative;
  isolation: isolate;
  /* Min height sets --thallo-root-layout (never `display`), so managed visibility stays the one
     authority over display; the local initialisation stops a nested container inheriting an
     ancestor's flex sizing (container-layout spec §3.5). */
  --thallo-root-layout: block;
  display: var(--thallo-root-layout);
  flex-direction: column;
}
/* background_image — a positioned <img> layer (srcset, priority-image contract), never a
   background-image style. z-index 0 sits under __inner (z-index 1). */
.thallo-block-container__bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
  border-radius: inherit;
}
.thallo-block-container__bg--contain { object-fit: contain; }
.thallo-block-container__bg--auto { object-fit: none; }
.thallo-block-container__bg--pos-center { object-position: center; }
.thallo-block-container__bg--pos-top { object-position: top; }
.thallo-block-container__bg--pos-bottom { object-position: bottom; }
.thallo-block-container__bg--pos-left { object-position: left; }
.thallo-block-container__bg--pos-right { object-position: right; }
/* overlay — schema enum: none | light | dark, with an opacity step 25 | 50 | 75 */
.thallo-block-container__overlay {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  border-radius: inherit;
}
.thallo-block-container--overlay-light .thallo-block-container__overlay { background: #fff; }
.thallo-block-container--overlay-dark .thallo-block-container__overlay { background: #000; }
.thallo-block-container--overlay-25 .thallo-block-container__overlay { opacity: 0.25; }
.thallo-block-container--overlay-50 .thallo-block-container__overlay { opacity: 0.5; }
.thallo-block-container--overlay-75 .thallo-block-container__overlay { opacity: 0.75; }
/* Layout defaults (container-layout spec §3.4–§3.8). Everything here is a THEME default: the
   compiled settings layer outranks it, so an authored or class-supplied value always wins and a
   reset (revert-layer) lands back on these rules. */
.thallo-block-container__inner {
  position: relative;
  z-index: 1;
  /* Initialised locally: a boxed ancestor's gutter must not reach a full-width nested container.
     The content-width utility sets this variable on the element that carries it. */
  --thallo-default-gutter: 0px;
  padding-inline: var(--thallo-default-gutter);
  /* Inert unless the root is a column flex box (a band with a min height), where the inner area
     takes the remaining height inside root's padding. */
  flex: 1 1 auto;
  /* As a flex item its inline margins are the gutter's `auto`, which stops the cross-axis stretch
     a block-level box gets for free — without this a boxed content area shrink-wraps its text
     inside a tall band instead of filling the measure. */
  width: 100%;
  /* The default mode (spec §3.8, §11.1): a flex column whose gaps are --space-5, the margin they
     replace — so a container nobody has touched stacks its children at the distances block flow
     gave them, and `none` is a choice rather than where a new row or grid starts. */
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

/* containment release (spec §3.6) */
.thallo-block-container__inner > .thallo-block-image,
.thallo-block-container__inner > .thallo-block-rich_text,
.thallo-block-container__inner > .thallo-block-heading,
.thallo-block-container__inner > .thallo-block-tabs,
.thallo-block-container__inner > .thallo-block-button,
.thallo-block-container__inner > .thallo-block-carousel,
.thallo-block-container__inner > .thallo-block-logo,
.thallo-block-container__inner > .thallo-block-icon,
.thallo-block-container__inner > .thallo-block-video,
.thallo-block-container__inner > .thallo-block-audio,
.thallo-block-container__inner > .thallo-block-file,
.thallo-block-container__inner > .thallo-block-html,
.thallo-block-container__inner > .thallo-block-shortcode,
.thallo-block-container__inner > .thallo-block-separator,
.thallo-block-container__inner > .thallo-block-form,
.thallo-block-container__inner > .thallo-block-gallery,
.thallo-block-container__inner > .thallo-block-code,
.thallo-block-container__inner > .thallo-block-map,
.thallo-block-container__inner > .thallo-block-entry_title,
.thallo-block-container__inner > .thallo-block-entry_date,
.thallo-block-container__inner > .thallo-block-entry_cover,
.thallo-block-container__inner > .thallo-block-entry_excerpt,
.thallo-block-container__inner > .thallo-block-entry_field,
.thallo-block-container__inner > .thallo-block-entry_terms,
.thallo-block-container__inner > .thallo-block-entry_neighbours,
.thallo-block-container__inner > .thallo-block-entry_related,
.thallo-block-container__inner > .thallo-preview-block > .thallo-block-image,
.thallo-block-container__inner > .thallo-preview-block > .thallo-block-rich_text,
.thallo-block-container__inner > .thallo-preview-block > .thallo-block-heading,
.thallo-block-container__inner > .thallo-preview-block > .thallo-block-tabs,
.thallo-block-container__inner > .thallo-preview-block > .thallo-block-button,
.thallo-block-container__inner > .thallo-preview-block > .thallo-block-carousel,
.thallo-block-container__inner > .thallo-preview-block > .thallo-block-logo,
.thallo-block-container__inner > .thallo-preview-block > .thallo-block-icon,
.thallo-block-container__inner > .thallo-preview-block > .thallo-block-video,
.thallo-block-container__inner > .thallo-preview-block > .thallo-block-audio,
.thallo-block-container__inner > .thallo-preview-block > .thallo-block-file,
.thallo-block-container__inner > .thallo-preview-block > .thallo-block-html,
.thallo-block-container__inner > .thallo-preview-block > .thallo-block-shortcode,
.thallo-block-container__inner > .thallo-preview-block > .thallo-block-separator,
.thallo-block-container__inner > .thallo-preview-block > .thallo-block-form,
.thallo-block-container__inner > .thallo-preview-block > .thallo-block-gallery,
.thallo-block-container__inner > .thallo-preview-block > .thallo-block-code,
.thallo-block-container__inner > .thallo-preview-block > .thallo-block-map,
.thallo-block-container__inner > .thallo-preview-block > .thallo-block-entry_title,
.thallo-block-container__inner > .thallo-preview-block > .thallo-block-entry_date,
.thallo-block-container__inner > .thallo-preview-block > .thallo-block-entry_cover,
.thallo-block-container__inner > .thallo-preview-block > .thallo-block-entry_excerpt,
.thallo-block-container__inner > .thallo-preview-block > .thallo-block-entry_field,
.thallo-block-container__inner > .thallo-preview-block > .thallo-block-entry_terms,
.thallo-block-container__inner > .thallo-preview-block > .thallo-block-entry_neighbours,
.thallo-block-container__inner > .thallo-preview-block > .thallo-block-entry_related {
  max-width: none;
  margin-inline: 0;
  padding-inline: 0;
}
/* end containment release */

/* Spacing (spec §3.8): the gaps are the one source of spacing between a container's children, so
   no child carries a default vertical margin — in either mode, at any breakpoint, after a reset.
   No rule here names a mode: there is no mode in which the margin comes back. */
.thallo-block-container__inner > .thallo-block,
.thallo-block-container__inner > .thallo-preview-block > .thallo-block { margin-block: 0; }
/* A rich text contributes no outer paragraph margin of its own; the margins between its own
   paragraphs are untouched. On the stage the body sits inside an edit region, so the outermost
   element is one level deeper — without that form the page and the canvas would space a rich text
   differently. */
.thallo-block-rich_text > :first-child,
.thallo-block-rich_text > .thallo-edit-region > :first-child { margin-top: 0; }
.thallo-block-rich_text > :last-child,
.thallo-block-rich_text > .thallo-edit-region > :last-child { margin-bottom: 0; }
/* A list reads as a list. The admin's editor writes each item's text as a paragraph
   (<li><p>…</p></li>), so the paragraph's margin would open a gap between items; the items sit a
   short step apart instead, indented by a bullet's width rather than the browser's 40px. */
.thallo-block-rich_text :is(ul, ol) { padding-inline-start: 1.25em; }
.thallo-block-rich_text li > p { margin: 0; }
.thallo-block-rich_text li + li { margin-top: 0.35em; }
/* The container's width, height, alignment, flex mode and gap were modifier classes driven by
   data fields; they are layout SETTINGS now (container-layout spec §4), so the rules that served
   them are gone. What replaces them lives in the compiled settings layer, over the layout defaults
   above. Padding, margin, corners, border, shadow and colours remain settings too (t-p*, t-m*,
   t-radius-*, t-bw-*/t-bs-*, t-shadow-*, t-bg-*/t-fg-*/t-bc-*). */
/* background_video — a muted looping cover layer behind the overlay, over any
   background_image. z-index 0 sits under __inner (z-index 1). */
.thallo-block-container__video {
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
  border-radius: inherit;
}
/* URL-embed (YouTube/Vimeo) background: a clipped cover wrapper holding the iframe.
   The iframe fills the width at 16:9 and centers vertically, so a wide container
   crops top/bottom (covers). A much taller-than-wide container can letterbox — a
   known limit of iframe backgrounds; a self-hosted/mp4 background avoids it. */
.thallo-block-container__video-cover {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
  border-radius: inherit;
}
.thallo-block-container__video-frame {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 100%;
  aspect-ratio: 16 / 9;
  min-height: 100%;
  transform: translate(-50%, -50%);
  border: 0;
}

/* feature — a compact icon + title + description leaf (drop several into a grid) */
.thallo-block-feature { display: flex; align-items: flex-start; gap: var(--space-3); margin-block: 0; }
/* the marker: the icon inline, or a number badge; colours from the theme's tokens when chosen */
.thallo-block-feature__marker { flex: none; color: var(--accent); }
.thallo-block-feature__marker--icon { font-size: 1.4rem; line-height: 1.3; display: inline-flex; align-items: center; justify-content: center; }
.thallo-block-feature__marker--number {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 2.5rem; height: 2.5rem; padding-inline: var(--space-2);
  border-radius: var(--radius-md); background: var(--surface-2);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.875rem; font-weight: 600;
}
.thallo-block-feature__marker--bg-transparent { background: transparent; }
.thallo-block-feature__marker--bg-surface { background: var(--surface); }
.thallo-block-feature__marker--bg-surface-2 { background: var(--surface-2); }
.thallo-block-feature__marker--bg-accent { background: var(--accent); }
.thallo-block-feature__marker--bg-text { background: var(--ink); }
.thallo-block-feature__marker--icon[class*="--bg-"] { padding: var(--space-2); border-radius: var(--radius-md); }
.thallo-block-feature__marker--fg-accent { color: var(--accent); }
.thallo-block-feature__marker--fg-text { color: var(--ink); }
.thallo-block-feature__marker--fg-muted { color: var(--muted); }
.thallo-block-feature__marker--fg-accent-contrast { color: var(--accent-ink); }
.thallo-block-feature__marker--fg-background { color: var(--bg); }
/* size: the icon glyph, and the badge's box and text, on one scale (md is the base) */
.thallo-block-feature__marker--icon.thallo-block-feature__marker--size-sm { font-size: 1.1rem; }
.thallo-block-feature__marker--icon.thallo-block-feature__marker--size-lg { font-size: 1.8rem; }
.thallo-block-feature__marker--icon.thallo-block-feature__marker--size-xl { font-size: 2.4rem; }
.thallo-block-feature__marker--number.thallo-block-feature__marker--size-sm { min-width: 2rem; height: 2rem; font-size: 0.75rem; }
.thallo-block-feature__marker--number.thallo-block-feature__marker--size-lg { min-width: 3rem; height: 3rem; font-size: 1rem; }
.thallo-block-feature__marker--number.thallo-block-feature__marker--size-xl { min-width: 3.75rem; height: 3.75rem; font-size: 1.25rem; }
.thallo-block-feature__body { min-width: 0; flex: 1; }
.thallo-block-feature__title { margin: 0; font-size: 1.05rem; text-wrap: pretty; }
.thallo-block-feature__title a { color: inherit; text-decoration: none; }
.thallo-block-feature__title a:hover { color: var(--accent); }
.thallo-block-feature__description { margin: var(--space-2) 0 0; color: var(--muted); font-size: 0.95rem; text-wrap: pretty; }
/* vertical: the marker above the text */
.thallo-block-feature--vertical { flex-direction: column; }
.thallo-block-feature--vertical .thallo-block-feature__body { flex: none; width: 100%; }
.thallo-block-feature--vertical .thallo-block-feature__title { font-size: 1.25rem; }
.thallo-block-feature--vertical .thallo-block-feature__marker { margin-bottom: var(--space-3); }
/* cards (the card block's variant names): padded, rounded, filling their grid cell */
.thallo-block-feature--outline,
.thallo-block-feature--soft,
.thallo-block-feature--subtle {
  height: 100%; box-sizing: border-box; padding: var(--space-5); border-radius: var(--radius-lg);
}
.thallo-block-feature--outline { background: var(--bg); border: 1px solid var(--line); }
.thallo-block-feature--soft { background: var(--surface); }
.thallo-block-feature--subtle { background: var(--surface); border: 1px solid var(--line); }

/* tabs — CSS-only radio tabs (Tabs pill recipe; authoring cap: 12 — theme-runtime spec §4) */
:where(.thallo-block-tabs, thallo-tabs) { max-width: var(--container); margin-inline: auto; padding-inline: var(--space-4); }
/* The strip's colours are four variables: the variant sets them, a chosen token overrides one. */
.thallo-block-tabs {
  --tabs-list-bg: var(--surface);
  --tabs-tab-fg: var(--muted);
  --tabs-active-bg: var(--bg);
  --tabs-active-fg: var(--ink);
  --shadow-tabs-active: var(--shadow);
  --tabs-active-underline: transparent;
}
.thallo-block-tabs__radio { position: absolute; opacity: 0; pointer-events: none; }
.thallo-block-tabs__list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1, 0.25rem);
  width: fit-content;
  padding: 0.25rem;
  border-radius: var(--radius-md);
  background: var(--tabs-list-bg);
}
.thallo-block-tabs__label {
  padding: 0.4rem 0.9rem;
  border-bottom: 2px solid transparent;
  border-radius: var(--radius-sm);
  font-size: 0.95rem;
  font-weight: 500;
  color: var(--tabs-tab-fg);
  cursor: pointer;
}
.thallo-block-tabs__panels { margin-top: var(--space-4); }
.thallo-block-tabs__panel { display: none; }
/* alignment of the strip */
.thallo-block-tabs--align-center .thallo-block-tabs__list { margin-inline: auto; }
.thallo-block-tabs--align-end .thallo-block-tabs__list { margin-inline-start: auto; }
.thallo-block-tabs--align-stretch .thallo-block-tabs__list { width: 100%; }
.thallo-block-tabs--align-stretch .thallo-block-tabs__label { flex: 1; text-align: center; }
/* underline: bare labels on a rule, the active one underlined in the accent */
.thallo-block-tabs--underline {
  --tabs-list-bg: transparent;
  --tabs-active-bg: transparent;
  --tabs-active-fg: var(--ink);
  --shadow-tabs-active: none;
  --tabs-active-underline: var(--accent);
}
.thallo-block-tabs--underline .thallo-block-tabs__list { padding: 0; gap: 0; border-radius: 0; border-bottom: 1px solid var(--line); }
.thallo-block-tabs--underline .thallo-block-tabs__label { border-radius: 0; padding-block: 0.6rem; margin-bottom: -1px; }
/* boxed: labels as boxes sitting on the panel */
.thallo-block-tabs--boxed {
  --tabs-list-bg: transparent;
  --tabs-active-bg: var(--surface);
  --tabs-active-fg: var(--ink);
  --shadow-tabs-active: none;
}
.thallo-block-tabs--boxed .thallo-block-tabs__list { padding: 0; gap: 0; border-radius: 0; }
.thallo-block-tabs--boxed .thallo-block-tabs__label { border: 1px solid var(--line); border-bottom: 0; border-radius: var(--radius-sm) var(--radius-sm) 0 0; margin-inline-end: -1px; }
.thallo-block-tabs--boxed .thallo-block-tabs__panels { margin-top: 0; border: 1px solid var(--line); border-radius: 0 var(--radius-md) var(--radius-md) var(--radius-md); background: var(--surface); }
/* chosen colours (theme tokens) override the variant's */
.thallo-block-tabs--list-bg-transparent { --tabs-list-bg: transparent; }
.thallo-block-tabs--list-bg-surface { --tabs-list-bg: var(--surface); }
.thallo-block-tabs--list-bg-surface-2 { --tabs-list-bg: var(--surface-2); }
.thallo-block-tabs--list-bg-accent { --tabs-list-bg: var(--accent); }
.thallo-block-tabs--list-bg-text { --tabs-list-bg: var(--ink); }
.thallo-block-tabs--list-bg-background { --tabs-list-bg: var(--bg); }
.thallo-block-tabs--tab-fg-accent { --tabs-tab-fg: var(--accent); }
.thallo-block-tabs--tab-fg-text { --tabs-tab-fg: var(--ink); }
.thallo-block-tabs--tab-fg-muted { --tabs-tab-fg: var(--muted); }
.thallo-block-tabs--tab-fg-accent-contrast { --tabs-tab-fg: var(--accent-ink); }
.thallo-block-tabs--tab-fg-background { --tabs-tab-fg: var(--bg); }
.thallo-block-tabs--active-bg-transparent { --tabs-active-bg: transparent; }
.thallo-block-tabs--active-bg-surface { --tabs-active-bg: var(--surface); }
.thallo-block-tabs--active-bg-surface-2 { --tabs-active-bg: var(--surface-2); }
.thallo-block-tabs--active-bg-accent { --tabs-active-bg: var(--accent); }
.thallo-block-tabs--active-bg-text { --tabs-active-bg: var(--ink); }
.thallo-block-tabs--active-bg-background { --tabs-active-bg: var(--bg); }
.thallo-block-tabs--active-fg-accent { --tabs-active-fg: var(--accent); }
.thallo-block-tabs--active-fg-text { --tabs-active-fg: var(--ink); }
.thallo-block-tabs--active-fg-muted { --tabs-active-fg: var(--muted); }
.thallo-block-tabs--active-fg-accent-contrast { --tabs-active-fg: var(--accent-ink); }
.thallo-block-tabs--active-fg-background { --tabs-active-fg: var(--bg); }
/* space inside the panels area */
.thallo-block-tabs--panel-pad-sm .thallo-block-tabs__panels { padding: var(--space-3); }
.thallo-block-tabs--panel-pad-md .thallo-block-tabs__panels { padding: var(--space-5); }
.thallo-block-tabs--panel-pad-lg .thallo-block-tabs__panels { padding: var(--space-7, var(--space-6)); }
/* nth radio checked -> nth label active + nth panel visible (cap: 12) */
.thallo-block-tabs__radio:nth-of-type(1):checked ~ .thallo-block-tabs__list .thallo-block-tabs__label:nth-of-type(1),
.thallo-block-tabs__radio:nth-of-type(2):checked ~ .thallo-block-tabs__list .thallo-block-tabs__label:nth-of-type(2),
.thallo-block-tabs__radio:nth-of-type(3):checked ~ .thallo-block-tabs__list .thallo-block-tabs__label:nth-of-type(3),
.thallo-block-tabs__radio:nth-of-type(4):checked ~ .thallo-block-tabs__list .thallo-block-tabs__label:nth-of-type(4),
.thallo-block-tabs__radio:nth-of-type(5):checked ~ .thallo-block-tabs__list .thallo-block-tabs__label:nth-of-type(5),
.thallo-block-tabs__radio:nth-of-type(6):checked ~ .thallo-block-tabs__list .thallo-block-tabs__label:nth-of-type(6),
.thallo-block-tabs__radio:nth-of-type(7):checked ~ .thallo-block-tabs__list .thallo-block-tabs__label:nth-of-type(7),
.thallo-block-tabs__radio:nth-of-type(8):checked ~ .thallo-block-tabs__list .thallo-block-tabs__label:nth-of-type(8),
.thallo-block-tabs__radio:nth-of-type(9):checked ~ .thallo-block-tabs__list .thallo-block-tabs__label:nth-of-type(9),
.thallo-block-tabs__radio:nth-of-type(10):checked ~ .thallo-block-tabs__list .thallo-block-tabs__label:nth-of-type(10),
.thallo-block-tabs__radio:nth-of-type(11):checked ~ .thallo-block-tabs__list .thallo-block-tabs__label:nth-of-type(11),
.thallo-block-tabs__radio:nth-of-type(12):checked ~ .thallo-block-tabs__list .thallo-block-tabs__label:nth-of-type(12) {
  background: var(--tabs-active-bg);
  color: var(--tabs-active-fg);
  box-shadow: var(--shadow-tabs-active);
  border-bottom: 2px solid var(--tabs-active-underline);
}
.thallo-block-tabs__radio:nth-of-type(1):checked ~ .thallo-block-tabs__panels .thallo-block-tabs__panel:nth-of-type(1),
.thallo-block-tabs__radio:nth-of-type(2):checked ~ .thallo-block-tabs__panels .thallo-block-tabs__panel:nth-of-type(2),
.thallo-block-tabs__radio:nth-of-type(3):checked ~ .thallo-block-tabs__panels .thallo-block-tabs__panel:nth-of-type(3),
.thallo-block-tabs__radio:nth-of-type(4):checked ~ .thallo-block-tabs__panels .thallo-block-tabs__panel:nth-of-type(4),
.thallo-block-tabs__radio:nth-of-type(5):checked ~ .thallo-block-tabs__panels .thallo-block-tabs__panel:nth-of-type(5),
.thallo-block-tabs__radio:nth-of-type(6):checked ~ .thallo-block-tabs__panels .thallo-block-tabs__panel:nth-of-type(6),
.thallo-block-tabs__radio:nth-of-type(7):checked ~ .thallo-block-tabs__panels .thallo-block-tabs__panel:nth-of-type(7),
.thallo-block-tabs__radio:nth-of-type(8):checked ~ .thallo-block-tabs__panels .thallo-block-tabs__panel:nth-of-type(8),
.thallo-block-tabs__radio:nth-of-type(9):checked ~ .thallo-block-tabs__panels .thallo-block-tabs__panel:nth-of-type(9),
.thallo-block-tabs__radio:nth-of-type(10):checked ~ .thallo-block-tabs__panels .thallo-block-tabs__panel:nth-of-type(10),
.thallo-block-tabs__radio:nth-of-type(11):checked ~ .thallo-block-tabs__panels .thallo-block-tabs__panel:nth-of-type(11),
.thallo-block-tabs__radio:nth-of-type(12):checked ~ .thallo-block-tabs__panels .thallo-block-tabs__panel:nth-of-type(12) {
  display: block;
}
/* Enhanced mode (theme-runtime spec §4): once the tabs module marks the root, the
   runtime owns panel visibility via the hidden attribute; the floor's display:none base
   + enumerated checked-pairing stand down and must not fight it. */
.thallo-block-tabs[data-thallo-enhanced~="tabs"] .thallo-block-tabs__panel { display: block; }
.thallo-block-tabs[data-thallo-enhanced~="tabs"] .thallo-block-tabs__panel[hidden] { display: none; }
.thallo-block-tab { margin-block: 0; }

/* button — standalone action (Button variant/size recipes) */
/* The root is a row (display: flex) so the content alignment setting (t-content-*) places the control. */
.thallo-block-button { max-width: var(--container); margin-inline: auto; padding-inline: var(--space-4); display: flex; }
/* color (primary default | neutral) sets a local accent; every variant consumes
   it, so a neutral button is the same recipe re-pointed at --ink. */
.thallo-block-button__link {
  --btn-accent: var(--accent);
  --btn-accent-ink: var(--accent-ink);
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  border-radius: var(--radius-btn, 999px);
  border: 1.5px solid transparent;
  font-weight: 600;
  line-height: 1.2;
  text-decoration: none;
  transition: background-color 0.15s ease, color 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease;
}
.thallo-block-button__link:hover { transform: translateY(-1px); }
.thallo-block-button__link--neutral { --btn-accent: var(--ink); --btn-accent-ink: var(--bg); }
/* Corners are a radius setting on the control (t-radius-*); unset reads --radius-btn (the site's radius setting). */
/* sizes */
.thallo-block-button__link--xs { padding: 0.3rem 0.8rem; font-size: 0.8rem; gap: 0.35em; }
.thallo-block-button__link--sm { padding: 0.45rem 1.1rem; font-size: 0.9rem; }
.thallo-block-button__link--md { padding: 0.6rem 1.4rem; font-size: 0.95rem; }
.thallo-block-button__link--lg { padding: 0.7rem 1.6rem; font-size: 1rem; }
.thallo-block-button__link--xl { padding: 0.85rem 1.9rem; font-size: 1.05rem; }
/* variants (all read --btn-accent) */
.thallo-block-button__link--solid { background: var(--btn-accent); color: var(--btn-accent-ink); box-shadow: var(--shadow); }
.thallo-block-button__link--outline {
  background: transparent;
  color: var(--btn-accent);
  border-color: color-mix(in srgb, var(--btn-accent) 55%, transparent);
}
.thallo-block-button__link--soft { background: color-mix(in srgb, var(--btn-accent) 12%, var(--bg)); color: var(--btn-accent); }
.thallo-block-button__link--subtle {
  background: color-mix(in srgb, var(--btn-accent) 12%, var(--bg));
  color: var(--btn-accent);
  border-color: color-mix(in srgb, var(--btn-accent) 25%, transparent);
}
.thallo-block-button__link--ghost { background: transparent; color: var(--btn-accent); }
.thallo-block-button__link--ghost:hover,
.thallo-block-button__link--soft:hover,
.thallo-block-button__link--subtle:hover { background: color-mix(in srgb, var(--btn-accent) 18%, var(--bg)); }
/* link variant reads like an inline text link, not a pill */
.thallo-block-button__link--link {
  background: transparent;
  color: var(--btn-accent);
  padding-inline: 0;
  border-radius: 0;
  box-shadow: none;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.thallo-block-button__link--link:hover { transform: none; text-decoration-thickness: 2px; }
/* block = full width, centered label */
.thallo-block-button__link--block { display: flex; width: 100%; justify-content: center; }
/* leading / trailing icons */
.thallo-block-button__icon { display: inline-flex; flex-shrink: 0; }
.thallo-block-button__icon svg { width: 1.15em; height: 1.15em; }

/* carousel — scroll-snap base; arrows/dots/autoplay are blocks.js enhancement */
:where(.thallo-block-carousel, thallo-carousel) { max-width: var(--container); margin-inline: auto; padding-inline: var(--space-4); position: relative; }
.thallo-block-carousel__viewport { overflow-x: auto; scroll-snap-type: x mandatory; scroll-behavior: smooth; scrollbar-width: thin; }
.thallo-block-carousel__track { display: flex; gap: var(--space-4); align-items: stretch; }
/* Slide sizing must survive the canvas/preview carrier (.thallo-preview-block,
   display: contents): the carrier's box doesn't exist, so `> *` alone would size
   the carrier (ignored) while the REAL slide — its child — became an auto-sized
   flex item. Every rule therefore pairs the direct-child selector with a
   carrier-piercing variant; :where() keeps both at identical specificity.
   max-width/margin-inline resets: many blocks carry standalone page-layout
   sizing (e.g. .thallo-block-image's max-width: var(--container) + auto
   margins) — as a slide, that cap silently overrides flex-basis: 100% and a
   wider carousel shows the next slide poking in. Slides fill their basis. */
.thallo-block-carousel__track > *,
.thallo-block-carousel__track > :where(.thallo-preview-block) > * { scroll-snap-align: start; flex: 0 0 100%; min-width: 0; max-width: none; margin-block: 0; margin-inline: 0; }
@media (min-width: 40rem) {
  .thallo-block-carousel--per-2 .thallo-block-carousel__track > *,
  .thallo-block-carousel--per-2 .thallo-block-carousel__track > :where(.thallo-preview-block) > * { flex-basis: calc(50% - var(--space-4) / 2); }
  .thallo-block-carousel--per-3 .thallo-block-carousel__track > *,
  .thallo-block-carousel--per-3 .thallo-block-carousel__track > :where(.thallo-preview-block) > * { flex-basis: calc(33.333% - var(--space-4) * 2 / 3); }
}

/* Once the runtime has taken over (arrows/dots/keyboard), the raw scroll-snap
   scrollbar is redundant plumbing; without JS it stays as the visible scroll
   affordance (no-JS floor). Hero sliders hide it unconditionally — their
   full-bleed image surface reads as broken with a scrollbar strip across it. */
.thallo-block-carousel--hero .thallo-block-carousel__viewport,
.thallo-block-carousel[data-thallo-enhanced="carousel"] .thallo-block-carousel__viewport { scrollbar-width: none; }
.thallo-block-carousel--hero .thallo-block-carousel__viewport::-webkit-scrollbar,
.thallo-block-carousel[data-thallo-enhanced="carousel"] .thallo-block-carousel__viewport::-webkit-scrollbar { display: none; }

/* Height presets (--h-*, slider-config ruling 2026-08-02): svh so mobile browser
   chrome doesn't cause unstable sizing, with a pixel floor per preset. Consumed
   as MIN-height by content slides (text may expand — never clipped to preserve
   the preset) and as the cover height by bare image slides; presentation applies
   under --hero. The template always emits one of these; the var() fallbacks on
   the consuming rules cover hand-written light-DOM markup (README examples). */
.thallo-block-carousel--h-compact { --carousel-height: max(40svh, 16rem); }
.thallo-block-carousel--h-standard { --carousel-height: max(60svh, 22rem); }
.thallo-block-carousel--h-tall { --carousel-height: max(80svh, 28rem); }
.thallo-block-carousel--h-full { --carousel-height: max(100svh, 34rem); }

/* Transition modes (--fade/--zoom, same ruling): ENHANCED-ONLY — keyed off the
   runtime marker so a no-JS visitor always keeps the scroll-snap slide floor
   (and the canvas, which never enhances, stays on the slide layout). Slides
   stack in one grid cell; the runtime moves data-thallo-active between slides —
   ONE shared active state for fade AND zoom; opacity cross-fades. No carrier
   pair on the > * rules: carriers only exist where enhancement never runs. */
/* speed — schema enum: slow | normal | fast; one pace for every mode (the runtime reads data-speed). */
.thallo-block-carousel--speed-slow { --carousel-duration: 2s; }
.thallo-block-carousel--speed-fast { --carousel-duration: 0.6s; }
.thallo-block-carousel--fade[data-thallo-enhanced~="carousel"] .thallo-block-carousel__track,
.thallo-block-carousel--zoom[data-thallo-enhanced~="carousel"] .thallo-block-carousel__track { display: grid; }
.thallo-block-carousel--fade[data-thallo-enhanced~="carousel"] .thallo-block-carousel__track > *,
.thallo-block-carousel--zoom[data-thallo-enhanced~="carousel"] .thallo-block-carousel__track > * {
  grid-area: 1 / 1;
  opacity: 0;
  /* Default 1.2s: slow enough to READ as a cross-fade (0.6s felt like a cut —
     2026-08 polish); shared by zoom, whose fade is the same rule. The block's
     speed choice re-maps --carousel-duration through the --speed-* classes. */
  transition: opacity var(--carousel-duration, 1.2s) ease-in-out;
  overflow: hidden; /* the zoom scale must never bleed outside the slide */
}
.thallo-block-carousel--fade[data-thallo-enhanced~="carousel"] .thallo-block-carousel__track > [data-thallo-active],
.thallo-block-carousel--zoom[data-thallo-enhanced~="carousel"] .thallo-block-carousel__track > [data-thallo-active] {
  opacity: 1;
  z-index: 1;
}
/* Zoom: a restrained IMAGE-ONLY scale on the active slide — text and controls
   never transform. forwards keeps the settled frame until the slide changes
   (removing data-thallo-active resets the animation for its next activation). */
.thallo-block-carousel--zoom[data-thallo-enhanced~="carousel"] .thallo-block-carousel__track > [data-thallo-active] img {
  animation: thallo-carousel-zoom 7s ease-out forwards;
}
@keyframes thallo-carousel-zoom {
  from { transform: scale(1); }
  to { transform: scale(1.06); }
}
/* Reduced motion (ruling): no cross-fade, no zoom — an immediate state change. */
@media (prefers-reduced-motion: reduce) {
  .thallo-block-carousel--fade[data-thallo-enhanced~="carousel"] .thallo-block-carousel__track > *,
  .thallo-block-carousel--zoom[data-thallo-enhanced~="carousel"] .thallo-block-carousel__track > * { transition: none; }
  .thallo-block-carousel--zoom[data-thallo-enhanced~="carousel"] .thallo-block-carousel__track > [data-thallo-active] img { animation: none; }
}

/* Hero slider preset (modern-blocks spec §2): presentation only — mechanics inherit. */
.thallo-block-carousel--hero { max-width: none; padding-inline: 0; }                       /* 1: full-bleed */
/* 1a: flush opening — a hero slider as the page's FIRST block sits directly
   under the header. Two 40px spacings stack there: main's top padding
   (site.css) and the block rhythm margin (.thallo-block, --space-5). The
   padding can't be removed from here, so the margin flips negative to cancel
   it: +space-5 → -space-5 nets to zero. Carrier-pierced pair for the canvas. */
main > article > .thallo-block-carousel--hero:first-child,
main > article > :where(.thallo-preview-block):first-child > .thallo-block-carousel--hero { margin-top: calc(-1 * var(--space-5)); }
.thallo-block-carousel--hero .thallo-block-carousel__track { gap: 0; }                     /* 1b: slides sit flush — no page-background stripe between full-bleed slides */
.thallo-block-carousel--hero .thallo-block-carousel__track > *,
.thallo-block-carousel--hero .thallo-block-carousel__track > :where(.thallo-preview-block) > * { flex: 0 0 100%; } /* 2: one per view (after --per-N) */
/* 2b: a BARE image block as a slide (no hero wrapper) keeps its standalone
   card styling — side padding, natural-width img, shadow. In a full-bleed
   hero slider it must read as a slide: edge-to-edge cover image. */
.thallo-block-carousel--hero .thallo-block-carousel__track > .thallo-block-image,
.thallo-block-carousel--hero .thallo-block-carousel__track > :where(.thallo-preview-block) > .thallo-block-image { padding-inline: 0; display: flex; }
/* The height preset (the hero-slide min-height floor) gives every image slide
   the SAME height regardless of source aspect ratio; object-fit: cover crops
   instead of distorting. The flex figure + min-height: 100% pair covers mixed
   sliders: if a sibling hero slide stretches the track taller, the image fills
   the difference. */
.thallo-block-carousel--hero .thallo-block-carousel__track > .thallo-block-image img,
.thallo-block-carousel--hero .thallo-block-carousel__track > :where(.thallo-preview-block) > .thallo-block-image img { width: 100%; height: var(--carousel-height, max(60svh, 22rem)); min-height: 100%; object-fit: cover; border-radius: 0; box-shadow: none; display: block; }
.thallo-block-carousel--hero .thallo-block-hero { min-height: var(--carousel-height, max(60svh, 22rem)); padding-block: 0; } /* 3: stacked grid; height preset drives the floor */
.thallo-block-carousel--hero .thallo-block-hero__inner {
  display: grid; min-height: inherit; max-width: none; margin: 0; padding: 0;
}
.thallo-block-carousel--hero .thallo-block-hero__wrapper,
.thallo-block-carousel--hero .thallo-block-hero__media { grid-area: 1 / 1; }
.thallo-block-carousel--hero .thallo-block-hero__media { z-index: 0; align-self: stretch; }
.thallo-block-carousel--hero .thallo-block-hero__media img {
  width: 100%; height: 100%; max-width: none; max-height: none; margin: 0;
  aspect-ratio: auto; object-fit: cover; box-shadow: none;
}
.thallo-block-carousel--hero .thallo-block-hero__wrapper {
  z-index: 2; align-self: end; padding: var(--space-6);
}
.thallo-block-carousel--hero .thallo-block-hero__inner::after {                           /* 4: scrim between media and text */
  content: ''; grid-area: 1 / 1; z-index: 1; align-self: stretch;
  background: linear-gradient(to top, rgb(0 0 0 / 0.65), transparent 55%);
}
.thallo-block-carousel--hero .thallo-block-hero__wrapper,
.thallo-block-carousel--hero .thallo-block-hero__wrapper :is(h1, h2, h3, p) {
  color: var(--on-media);                                                                /* 5: on-media token */
}
/* 6: no-image fallback — when media exists, the media + scrim (rule 4) fully cover
   this surface, so this background never shows through. A media-less slide has
   neither, so it falls straight to this dark base — which is exactly what makes
   the unconditional on-media ink (rule 5) readable instead of white-on-near-white.
   Uses the theme-invariant --hero-fallback-bg (NOT --ink, which flips light in dark
   mode) because --on-media stays light in both modes and under every setting. */
.thallo-block-carousel--hero .thallo-block-hero { background: var(--hero-fallback-bg); }

.thallo-block-carousel__prev, .thallo-block-carousel__next {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--bg);
  color: var(--ink);
  cursor: pointer;
  box-shadow: var(--shadow);
  z-index: 1;
}
.thallo-block-carousel__prev { left: calc(var(--space-4) / 2); }
.thallo-block-carousel__next { right: calc(var(--space-4) / 2); }
/* Hover-reveal (2026-08 polish): pointer devices see the arrows only while
   hovering the carousel — decluttered at rest. Scoped to (hover)+(pointer:
   fine) so TOUCH devices, which have no hover, keep them always visible; and
   :focus-within is a reveal trigger of equal rank, so a keyboard user never
   tabs onto an invisible button. pointer-events: none while hidden — an
   invisible edge button must not swallow clicks meant for the slide. */
@media (hover: hover) and (pointer: fine) {
  .thallo-block-carousel__prev, .thallo-block-carousel__next {
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.2s ease;
  }
  .thallo-block-carousel:hover .thallo-block-carousel__prev,
  .thallo-block-carousel:hover .thallo-block-carousel__next,
  .thallo-block-carousel:focus-within .thallo-block-carousel__prev,
  .thallo-block-carousel:focus-within .thallo-block-carousel__next {
    opacity: 1;
    pointer-events: auto;
  }
}
@media (prefers-reduced-motion: reduce) {
  .thallo-block-carousel__prev, .thallo-block-carousel__next { transition: none; }
}
.thallo-block-carousel__dots { display: flex; justify-content: center; gap: 0.6rem; margin-top: var(--space-3); }
.thallo-block-carousel__dot {
  width: 0.7rem;
  height: 0.7rem;
  border-radius: 999px;
  border: 0;
  background: var(--line);
  cursor: pointer;
  padding: 0;
}
.thallo-block-carousel__dot[aria-current="true"] { background: var(--accent); }
/* Autoplay pause/play toggle (runtime-injected, appended to the root like the
   arrows): same circular-chip language as prev/next, anchored bottom-right. */
.thallo-block-carousel__pause {
  position: absolute;
  right: calc(var(--space-4) / 2);
  bottom: calc(var(--space-4) / 2);
  width: 2rem;
  height: 2rem;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--bg);
  color: var(--ink);
  cursor: pointer;
  box-shadow: var(--shadow);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.8rem;
  line-height: 1;
  z-index: 1;
}
/* 7: hero overlay chrome — a full-bleed slider carries its controls ON the image
   (the modern pattern), not dangling below it. Dots go white-on-media for
   contrast; the pause chip shares the same row, bottom-right. */
.thallo-block-carousel--hero .thallo-block-carousel__dots {
  position: absolute;
  inset-inline: 0;
  bottom: var(--space-4);
  margin-top: 0;
  z-index: 1;
}
.thallo-block-carousel--hero .thallo-block-carousel__dot { background: rgba(255, 255, 255, 0.55); }
.thallo-block-carousel--hero .thallo-block-carousel__dot[aria-current="true"] { background: #fff; }
.thallo-block-carousel--hero .thallo-block-carousel__pause { right: var(--space-4); bottom: var(--space-4); }
/* visually-hidden 'Slide N of M' status region injected by the runtime carousel module */
.thallo-block-carousel__status { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }

/* logo — the site logo (setting-backed) */
.thallo-block-logo { max-width: var(--container); margin-inline: auto; padding-inline: var(--space-4); }
/* The link is its own box, as wide as the logo: an inline link sat on a line of text and kept the
   room a line reserves below the letters, a gap under the logo no setting could reach. */
.thallo-block-logo__link { display: flex; width: fit-content; align-items: center; text-decoration: none; color: inherit; }
.thallo-block-logo__image { display: block; width: auto; }
.thallo-block-logo--small .thallo-block-logo__image { height: 1.75rem; }
.thallo-block-logo--medium .thallo-block-logo__image { height: 2.5rem; }
.thallo-block-logo--large .thallo-block-logo__image { height: 3.5rem; }
.thallo-block-logo__name { font-weight: 700; font-size: 1.25rem; letter-spacing: -0.02em; }
/* Dark-logo variant (site-identity spec): mirrors the site.css rule pair;
   applies only inside the template-emitted --has-dark modifier. */
.thallo-block-logo__image--dark { display: none; }
html[data-theme="dark"] .thallo-block-logo--has-dark .thallo-block-logo__image--light { display: none; }
html[data-theme="dark"] .thallo-block-logo--has-dark .thallo-block-logo__image--dark { display: block; }

/* icon — a single decorative Lucide glyph, optionally linked; sizes scale
   font-size (the .thallo-icon svg is 1em) and color rides currentColor */
.thallo-block-icon { max-width: var(--container); margin-inline: auto; padding-inline: var(--space-4); color: var(--accent); }
.thallo-block-icon--small { font-size: 1.5rem; }
.thallo-block-icon--medium { font-size: 2.5rem; }
.thallo-block-icon--large { font-size: 4rem; }
.thallo-block-icon--start { text-align: start; }
.thallo-block-icon--center { text-align: center; }
.thallo-block-icon--end { text-align: end; }
.thallo-block-icon__link { color: inherit; display: inline-flex; }

/* color_mode — a segmented light/system/dark switch. The active option
   (aria-checked="true") is set by the blocks.js runtime from the stored
   preference; the pill re-skins automatically under html[data-theme]. */
:where(.thallo-block-color_mode, thallo-color-mode-toggle) {
  display: inline-flex; gap: 2px; padding: 3px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 999px;
}
.thallo-block-color_mode__option {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2rem; height: 2rem; padding: 0;
  border: 0; background: transparent; color: var(--muted);
  border-radius: 999px; cursor: pointer;
  transition: background-color .15s ease, color .15s ease;
}
.thallo-block-color_mode__option svg { width: 1.1rem; height: 1.1rem; }
.thallo-block-color_mode__option:hover { color: var(--ink); }
.thallo-block-color_mode__option[aria-checked="true"] {
  background: var(--bg); color: var(--ink); box-shadow: var(--shadow);
}

/* copyright shortcode — muted small print */
.thallo-shortcode-copyright { margin: 0; font-size: 0.85rem; color: var(--muted); }

/* social_links — a row of brand glyphs */
.thallo-block-social_links { display: flex; gap: var(--space-3); align-items: center; }
.thallo-block-social_links .thallo-block-social_link { margin-block: 0; }
.thallo-block-social_link__link { color: var(--muted); font-size: 1.25rem; display: inline-flex; }
.thallo-block-social_link__link:hover { color: var(--ink); }

/* video / audio */
.thallo-block-video { max-width: var(--container); margin-inline: auto; padding-inline: var(--space-4); }
/* The frame (iframe or native player) is the `frame` style target: corners and shadow land here. */
.thallo-block-video__frame, .thallo-block-video__player {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  border: 0;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  background: var(--surface);
}
.thallo-block-video--full { max-width: none; padding-inline: 0; }
.thallo-block-video--full .thallo-block-video__frame,
.thallo-block-video--full .thallo-block-video__player { border-radius: 0; }
.thallo-block-video__caption { color: var(--muted); font-size: 0.9rem; margin-top: var(--space-2); text-align: center; }
.thallo-block-audio { max-width: var(--content); margin-inline: auto; padding-inline: var(--space-4); }
.thallo-block-audio__player { width: 100%; }
.thallo-block-audio__title { font-weight: 600; margin-bottom: var(--space-2); }

/* map — a Google map of a place. The frame (the map, or the click-to-load placeholder) is the
   `frame` style target: corners, border and shadow land there. Its height is the block's size. */
.thallo-block-map { max-width: var(--container); margin-inline: auto; padding-inline: var(--space-4); }
.thallo-block-map__frame {
  display: block;
  width: 100%;
  height: 22.5rem;
  border: 0;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  background: var(--surface);
  overflow: hidden;
}
.thallo-block-map--small .thallo-block-map__frame { height: 15rem; }
.thallo-block-map--large .thallo-block-map__frame { height: 30rem; }
@media (max-width: 48rem) {
  .thallo-block-map--medium .thallo-block-map__frame { height: 18rem; }
  .thallo-block-map--large .thallo-block-map__frame { height: 22.5rem; }
}
.thallo-block-map__consent {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-4);
  text-align: center;
  color: var(--muted);
  background: var(--surface);
}
.thallo-block-map__pin {
  display: grid;
  place-items: center;
  width: 3rem;
  height: 3rem;
  border-radius: 50%;
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 12%, transparent);
}
.thallo-block-map__pin .thallo-icon { width: 1.5rem; height: 1.5rem; }
.thallo-block-map__consent--loaded { padding: 0; background: var(--surface); }
.thallo-block-map__notice { margin: 0; max-width: 28rem; font-size: 0.9rem; }
.thallo-block-map__load {
  font: inherit;
  font-weight: 600;
  padding: 0.55rem 1.1rem;
  border: 0;
  border-radius: var(--radius-sm);
  color: var(--accent-ink);
  background: var(--accent);
  cursor: pointer;
}
.thallo-block-map__load:hover { filter: brightness(1.08); }
.thallo-block-map__open { font-size: 0.9rem; color: var(--accent); }
.thallo-block-map__map { display: block; width: 100%; height: 100%; border: 0; }
.thallo-block-map__caption {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2);
  margin-top: var(--space-2);
  color: var(--muted);
  font-size: 0.9rem;
}
.thallo-block-map__directions { font-weight: 600; color: var(--accent); text-decoration: none; }
.thallo-block-map__directions:hover { text-decoration: underline; }
.thallo-block-map__empty {
  padding: var(--space-5) var(--space-4);
  border: 2px dashed var(--line);
  border-radius: var(--radius-lg);
  color: var(--muted);
  text-align: center;
}

/* file — a download link/button to an uploaded blob. */
.thallo-block-file { max-width: var(--content); margin-inline: auto; padding-inline: var(--space-4); }
.thallo-block-file__link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  color: var(--ink);
  text-decoration: none;
  font-weight: 500;
  transition: background-color .15s ease, border-color .15s ease;
}
.thallo-block-file__link:hover,
.thallo-block-file__link:focus-visible { background: var(--surface); }
.thallo-block-file__link svg { width: 1.1em; height: 1.1em; flex-shrink: 0; }
@media (prefers-reduced-motion: reduce) {
  .thallo-block-file__link { transition: none; }
}

/* html / shortcode — layout-neutral wrappers */
.thallo-block-html, .thallo-block-shortcode {
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--space-4);
}

/* shortcodes/thallo-version — a status pill with a dot. Its look is the shortcode block's
   `content` target: background, text and border colour, border, radius and shadow from the Style
   tab land on this element and, being settings, win over these defaults. A site's custom CSS can
   still recolour it through the tokens (fg, bg, dot); the floor is the plain <span>. */
.thallo-shortcode-version {
  --version-fg: var(--accent);
  --version-bg: color-mix(in srgb, var(--accent) 12%, var(--surface));
  display: inline-flex; align-items: center; gap: var(--space-2);
  padding: 0.375rem 0.875rem; border-radius: 999px;
  /* No border until one is asked for — but with a style and a colour, so a width set in the Style
     tab shows by itself. */
  border: 0 solid var(--line);
  background: var(--version-bg); color: var(--version-fg);
  font-family: var(--font-mono, ui-monospace, monospace); font-size: 0.8rem; line-height: 1.4;
  width: max-content; max-width: 100%;
}
/* The dot is drawn in the text's colour, so recolouring the text brings it along. */
.thallo-shortcode-version::before {
  content: ""; width: 0.5rem; height: 0.5rem; border-radius: 50%; background: var(--version-dot, currentColor); flex: none;
}
/* params.dot = false, and params.dot_color = one of the theme's colour names. */
.thallo-shortcode-version--no-dot::before { display: none; }
.thallo-shortcode-version--dot-accent { --version-dot: var(--accent); }
.thallo-shortcode-version--dot-text { --version-dot: var(--ink); }
.thallo-shortcode-version--dot-muted { --version-dot: var(--muted); }
.thallo-shortcode-version--dot-accent-contrast { --version-dot: var(--accent-ink); }
.thallo-shortcode-version--dot-background { --version-dot: var(--bg); }
.thallo-shortcode-version--development { --version-fg: var(--muted); }

/* ── Centered page layout (opt-in via main.layout--centered) ────────────────
   Band blocks present CONTAINED (width-clamped, centered) instead of edge-to-
   edge bands — no card radius; corners stay square. Dormant in themes that
   never emit layout classes — full-bleed stays the classless default
   (standalone-ness holds).
   The generic container is EXCLUDED: it's a self-governed wrapper with its own
   width and radius box controls, so the layout mode must not clamp its width or
   impose a radius over the author's setting. */
.layout--centered .thallo-block-hero,
.layout--centered .thallo-block-cta {
  max-width: var(--container);
  margin-inline: auto;
}
.layout--centered .thallo-block-hero { padding-block: var(--space-6); }

/* ── Full-width page layout (opt-in via main.layout--full) ───────────────────
   Symmetric to .layout--centered: instead of boxing bands, full mode releases
   EVERY width clamp — band inner wrappers, self-clamped blocks, AND the reading
   measure — so content spans the whole viewport, held off the edges only by
   each block's own padding-inline. Additive/scoped: dormant unless <main>
   carries .layout--full. */
.layout--full .thallo-block-hero__inner,
.layout--full .thallo-block-cta__inner,
.layout--full .thallo-block-container__inner,
.layout--full .thallo-block-image,
.layout--full :where(.thallo-block-tabs, thallo-tabs),
.layout--full .thallo-block-button,
.layout--full :where(.thallo-block-carousel, thallo-carousel),
.layout--full .thallo-block-logo,
.layout--full .thallo-block-icon,
.layout--full .thallo-block-video,
.layout--full .thallo-block-audio,
.layout--full .thallo-block-html,
.layout--full .thallo-block-shortcode,
.layout--full .thallo-block-rich_text,
.layout--full .thallo-block-form,
.layout--full .thallo-block-separator,
.layout--full .entry-content {
  max-width: none;
}

/* ═══════════════════════════════════════════════════════════════════════════
   Primitive blocks (theme rewrite) — authored in our BEM/token convention,
   design sourced from tw-class.css / docs/refs.md. Interactive disclosure blocks
   (accordion, collapsible) are native <details>; stepper lives in stepper.css.
   ═══════════════════════════════════════════════════════════════════════════ */

/* separator — a horizontal rule with an optional centered label/icon (replaces
   the legacy divider). Line style ← --type, thickness ← --size. */
/* A page-level separator spans the page's width, not the viewport: the same clamp the other
   self-governed leaves carry (button, tabs, video…); nested, it fills its parent. */
.thallo-block-separator {
  display: flex; align-items: center; margin-block: var(--space-4);
  max-width: var(--container); margin-inline: auto; padding-inline: var(--space-4);
}
.thallo-block-separator__line { flex: 1 1 auto; border-top: 1px solid var(--line); }
.thallo-block-separator--type-dashed .thallo-block-separator__line { border-top-style: dashed; }
.thallo-block-separator--type-dotted .thallo-block-separator__line { border-top-style: dotted; }
.thallo-block-separator--size-sm .thallo-block-separator__line { border-top-width: 2px; }
.thallo-block-separator--size-md .thallo-block-separator__line { border-top-width: 3px; }
.thallo-block-separator--size-lg .thallo-block-separator__line { border-top-width: 4px; }
.thallo-block-separator--size-xl .thallo-block-separator__line { border-top-width: 5px; }
.thallo-block-separator__content {
  display: inline-flex; align-items: center; gap: var(--space-2);
  margin-inline: var(--space-3); white-space: nowrap;
  font-size: 0.9rem; font-weight: 500; color: var(--ink);
}
.thallo-block-separator__icon { display: inline-flex; }
.thallo-block-separator__icon svg { width: 1.1em; height: 1.1em; }

/* accordion — a stack of native <details> disclosures (replaces legacy faq).
   CSS-only: exclusive-open (non-multiple) is handled by the template's
   <details name>; here we only style. Chevron rotates under [open]. */
.thallo-block-accordion { width: 100%; }
.thallo-block-accordion__title {
  font-size: 1.25rem; font-weight: 600; color: var(--ink);
  margin: 0 0 var(--space-3);
}
.thallo-block-accordion__item { border-bottom: 1px solid var(--line); }
.thallo-block-accordion__item:last-child { border-bottom: 0; }
.thallo-block-accordion__summary {
  display: flex; align-items: center; gap: var(--space-2);
  padding-block: var(--space-2); min-width: 0;
  font-weight: 500; color: var(--ink); cursor: pointer;
  list-style: none;
}
.thallo-block-accordion__summary::-webkit-details-marker { display: none; }
.thallo-block-accordion__summary:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px;
}
.thallo-block-accordion__question {
  flex: 1 1 auto; min-width: 0; text-align: start; overflow-wrap: anywhere;
}
.thallo-block-accordion__chevron {
  flex-shrink: 0; display: inline-flex; margin-inline-start: auto;
  color: var(--muted); transition: transform .2s ease;
}
.thallo-block-accordion__chevron svg { width: 1.25rem; height: 1.25rem; }
.thallo-block-accordion__item[open] .thallo-block-accordion__chevron {
  transform: rotate(180deg);
}
.thallo-block-accordion__panel { padding-bottom: var(--space-3); }
.thallo-block-accordion__answer { color: var(--muted); }
.thallo-block-accordion__answer > :first-child { margin-top: 0; }
.thallo-block-accordion__answer > :last-child { margin-bottom: 0; }
@media (prefers-reduced-motion: reduce) {
  .thallo-block-accordion__chevron { transition: none; }
}

/* accordion_item — a single Q&A disclosure rendered standalone (the accordion
   parent renders its items inline, so this is the drop-on-its-own fallback). */
.thallo-block-accordion_item { border-bottom: 1px solid var(--line); }
.thallo-block-accordion_item__summary {
  display: flex; align-items: center; gap: var(--space-2);
  padding-block: var(--space-2);
  font-weight: 500; color: var(--ink); cursor: pointer; list-style: none;
}
.thallo-block-accordion_item__summary::-webkit-details-marker { display: none; }
.thallo-block-accordion_item__question { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.thallo-block-accordion_item__answer { padding-bottom: var(--space-3); color: var(--muted); }
.thallo-block-accordion_item__answer > :first-child { margin-top: 0; }
.thallo-block-accordion_item__answer > :last-child { margin-bottom: 0; }

/* card — maps to refs.md pageCard. A content card; drop several into a grid or
   columns for feature grids / testimonial walls. Surface <- --variant, layout <-
   --horizontal, source order <- --reverse. */
.thallo-block-card {
  display: flex; flex-direction: column; align-items: flex-start;
  flex: 1; gap: var(--space-1);
  padding: var(--space-4); border-radius: var(--radius-lg);
  background: var(--bg); color: var(--ink);
}
.thallo-block-card__icon {
  display: inline-flex; align-items: center;
  margin-bottom: var(--space-2); color: var(--accent);
}
.thallo-block-card__icon svg { width: 1.25rem; height: 1.25rem; flex: none; }
.thallo-block-card__title {
  margin: 0; font-size: 1rem; font-weight: 600; line-height: 1.4; color: var(--ink);
  text-wrap: pretty;
}
.thallo-block-card__description {
  margin: 0; font-size: 0.9375rem; line-height: 1.5; color: var(--muted);
  text-wrap: pretty;
}
.thallo-block-card__title + .thallo-block-card__description { margin-top: var(--space-1); }
.thallo-block-card__body { flex: 1; width: 100%; margin-top: var(--space-3); }
.thallo-block-card--variant-solid { background: var(--ink); color: var(--bg); }
.thallo-block-card--variant-solid .thallo-block-card__title { color: var(--bg); }
.thallo-block-card--variant-solid .thallo-block-card__icon,
.thallo-block-card--variant-solid .thallo-block-card__description {
  color: color-mix(in srgb, var(--bg) 70%, transparent);
}
.thallo-block-card--variant-soft { background: var(--surface); }
.thallo-block-card--variant-subtle { background: var(--surface); border: 1px solid var(--line); }
.thallo-block-card--variant-outline { background: var(--bg); border: 1px solid var(--line); }
.thallo-block-card--variant-ghost { background: transparent; }
.thallo-block-card--variant-naked { background: transparent; padding: 0; }
@media (min-width: 64rem) {
  .thallo-block-card--horizontal {
    display: grid; grid-template-columns: 1fr 1fr;
    column-gap: var(--space-5); align-items: center;
  }
  .thallo-block-card--horizontal .thallo-block-card__body { margin-top: 0; }
}
.thallo-block-card--reverse { flex-direction: column-reverse; }
.thallo-block-card--reverse .thallo-block-card__body { margin-top: 0; margin-bottom: var(--space-3); }
@media (min-width: 64rem) {
  .thallo-block-card--horizontal.thallo-block-card--reverse .thallo-block-card__body {
    order: -1; margin-bottom: 0;
  }
}

/* collapsible — native <details> disclosure, CSS-only (no JS). A grid-rows
   0fr->1fr transition on __panel animates the reveal without measuring JS. */
.thallo-block-collapsible {
  border: 1px solid var(--line);
  background: var(--surface);
}
.thallo-block-collapsible__summary {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-3);
  font-weight: 500; color: var(--ink);
  cursor: pointer; list-style: none; user-select: none;
}
.thallo-block-collapsible__summary::-webkit-details-marker { display: none; }
.thallo-block-collapsible__summary:focus-visible {
  outline: 2px solid var(--accent); outline-offset: -2px;
}
.thallo-block-collapsible__label { min-width: 0; }
.thallo-block-collapsible__chevron {
  display: inline-flex; flex-shrink: 0; color: var(--muted);
  transition: transform .2s ease;
}
.thallo-block-collapsible__chevron svg { width: 1.25rem; height: 1.25rem; }
.thallo-block-collapsible[open] .thallo-block-collapsible__chevron { transform: rotate(180deg); }
.thallo-block-collapsible__panel {
  display: grid; grid-template-rows: 0fr;
  transition: grid-template-rows .2s ease-out;
}
.thallo-block-collapsible[open] .thallo-block-collapsible__panel { grid-template-rows: 1fr; }
.thallo-block-collapsible__panel-inner {
  overflow: hidden;
  padding: 0 var(--space-3) var(--space-3);
  color: var(--muted);
}
@media (prefers-reduced-motion: reduce) {
  .thallo-block-collapsible__chevron,
  .thallo-block-collapsible__panel { transition: none; }
}

/* links — a vertical list of navigation links (maps to refs.md pageLinks). Items
   are a plain array, not child blocks. Active link takes --accent; the rest read
   muted and warm to --ink on hover. */
.thallo-block-links { display: flex; flex-direction: column; gap: var(--space-2); }
.thallo-block-links__title {
  margin: 0; font-size: 0.8rem; font-weight: 600; color: var(--ink);
}
.thallo-block-links__list {
  display: flex; flex-direction: column; gap: var(--space-1);
  list-style: none; margin: 0; padding: 0;
}
.thallo-block-links__item { min-width: 0; }
.thallo-block-links__link {
  display: inline-flex; align-items: center; gap: 0.4em;
  padding: 0.3em 0.5em; border-radius: var(--radius);
  color: var(--muted); text-decoration: none; font-weight: 500;
  transition: color .15s ease;
}
.thallo-block-links__link:hover,
.thallo-block-links__link:focus-visible { color: var(--ink); }
.thallo-block-links__link--active { color: var(--accent); }
.thallo-block-links__icon { display: inline-flex; flex-shrink: 0; }
.thallo-block-links__icon svg { width: 1.1em; height: 1.1em; }
.thallo-block-links__label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (prefers-reduced-motion: reduce) {
  .thallo-block-links__link { transition: none; }
}

/* footer — a <footer> bar (refs.md `footer`). Optional top band over a
   left/center/right row: stacked + centered on small screens, spread on wide.
   Tokens only; dark mode re-maps them. */
/* A footer block is the whole footer: it spans its container, so placed in the footer region —
   whose inner is a flex row — it is not shrunk to its content and pushed to one side. */
.thallo-block-footer { flex: 1 1 100%; width: 100%; }
.thallo-block-footer__top {
  padding-block: var(--space-6);
  border-bottom: 1px solid var(--line);
}
.thallo-block-footer__bar {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
  padding-block: var(--space-5);
}
.thallo-block-footer__left { color: var(--muted); font-size: 0.9rem; }
.thallo-block-footer__center {
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: var(--space-3) var(--space-4);
}
.thallo-block-footer__right { display: flex; align-items: center; gap: var(--space-3); }
@media (min-width: 64rem) {
  .thallo-block-footer__bar { flex-direction: row; justify-content: space-between; }
  .thallo-block-footer__left { flex: 1 1 0; }
  .thallo-block-footer__right { flex: 1 1 0; justify-content: flex-end; }
}

/* logos — a "trusted by" logo strip (refs.md pageLogos, replaces logo_cloud).
   Default = centered wrapping row; --scroll = seamless pure-CSS marquee (the
   template renders the run twice and this shifts the track -50%). --grayscale
   desaturates + dims until hover. */
.thallo-block-logos { position: relative; overflow: hidden; }
.thallo-block-logos__title {
  margin: 0 0 var(--space-4); text-align: center;
  font-size: 1.125rem; font-weight: 600; color: var(--ink);
}
.thallo-block-logos__track {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: var(--space-4) var(--space-6); margin-top: var(--space-5);
}
.thallo-block-logos__item { flex: 0 0 auto; }
.thallo-block-logos__image {
  height: 2.5rem; width: auto; object-fit: contain;
  transition: filter .2s ease, opacity .2s ease;
}
.thallo-block-logos--grayscale .thallo-block-logos__image { filter: grayscale(1); opacity: 0.7; }
.thallo-block-logos--grayscale .thallo-block-logos__image:hover { filter: grayscale(0); opacity: 1; }
.thallo-block-logos--scroll .thallo-block-logos__track {
  flex-wrap: nowrap; justify-content: flex-start; width: max-content;
  gap: var(--space-6);
  animation: thallo-logos-marquee 30s linear infinite;
}
@keyframes thallo-logos-marquee {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}
@media (prefers-reduced-motion: reduce) {
  .thallo-block-logos--scroll .thallo-block-logos__track {
    animation: none !important;
    flex-wrap: wrap; justify-content: center; width: auto;
  }
  .thallo-block-logos__image { transition: none; }
}

/* stepper_item — a single step rendered standalone (the stepper parent renders
   its items inline with a numbered marker; this is the drop-on-its-own fallback,
   marker unnumbered). Full stepper styling lives in stepper.css. */
.thallo-block-stepper_item { display: flex; gap: var(--space-3); align-items: flex-start; }
.thallo-block-stepper_item__marker {
  flex-shrink: 0; width: 1.75rem; height: 1.75rem; border-radius: 999px;
  background: var(--accent); color: var(--accent-ink);
}
.thallo-block-stepper_item__step-title { margin: 0; font-size: 1.05rem; color: var(--ink); }
.thallo-block-stepper_item__description { margin: var(--space-2) 0 0; color: var(--muted); font-size: 0.95rem; }

/* style — a token-scoping wrapper (style-block spec §4.5). It paints nothing itself;
   it only re-defines design-token custom properties for its subtree, which descendant
   blocks already consume. The scoped values arrive via the block's inline <style>. */
.thallo-block-style { display: block; }
.thallo-block-style__inner { display: block; }


/* ── Pricing blocks (refs.md pricingPlan/pricingPlans/pricingTable) ──────────
   Self-contained rounded cards (deliberate radius exception to the squared
   band blocks). Semantic Nuxt tokens mapped to theme tokens (site.css). */
.thallo-block-pricing_plan {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-4);
  border-radius: var(--radius-lg);
  background: var(--bg);
  border: 1px solid var(--line);
}
.thallo-block-pricing_plan--variant-solid {
  background: var(--ink);
  color: var(--bg);
  border-color: transparent;
}
.thallo-block-pricing_plan--variant-soft { background: var(--surface); border-color: transparent; }
.thallo-block-pricing_plan--variant-subtle { background: var(--surface); border-color: var(--line); }
.thallo-block-pricing_plan--highlight {
  border: 2px solid var(--accent);
}
.thallo-block-pricing_plan__badge {
  align-self: flex-start;
  padding: 0.15rem 0.6rem;
  border-radius: var(--radius);
  background: var(--accent);
  color: var(--accent-ink);
  font-size: 0.8rem;
  font-weight: 600;
}
.thallo-block-pricing_plan__body { display: flex; flex-direction: column; gap: var(--space-2); flex: 1; }
.thallo-block-pricing_plan__title { margin: 0; font-size: 1.5rem; font-weight: 600; color: inherit; }
.thallo-block-pricing_plan__description { margin: 0; color: var(--muted); }
.thallo-block-pricing_plan__price-wrapper { display: flex; align-items: baseline; gap: 0.5rem; flex-wrap: wrap; }
.thallo-block-pricing_plan__price { font-size: 2.25rem; font-weight: 700; color: inherit; }
.thallo-block-pricing_plan__discount { color: var(--muted); text-decoration: line-through; font-size: 1.25rem; }
.thallo-block-pricing_plan__billing { display: flex; flex-direction: column; }
.thallo-block-pricing_plan__billing-period {
  font-size: 0.8rem; font-weight: 500;
  color: color-mix(in srgb, var(--ink) 65%, var(--muted));
}
.thallo-block-pricing_plan__billing-cycle { font-size: 0.8rem; color: var(--muted); }
.thallo-block-pricing_plan__features {
  list-style: none; margin: var(--space-2) 0 0; padding: 0;
  display: flex; flex-direction: column; gap: 0.75rem;
}
.thallo-block-pricing_plan__feature { display: flex; align-items: center; gap: 0.5rem; }
.thallo-block-pricing_plan__feature-icon {
  display: inline-flex; width: 1.25rem; height: 1.25rem; color: var(--accent); flex-shrink: 0;
}
.thallo-block-pricing_plan__feature-icon svg { width: 100%; height: 100%; }
.thallo-block-pricing_plan__footer { display: flex; flex-direction: column; gap: var(--space-2); align-items: stretch; }
.thallo-block-pricing_plan__tagline { margin: 0; font-weight: 600; text-align: center; }
.thallo-block-pricing_plan__cta {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0.6rem 1.2rem;
  border: 1px solid transparent;
  border-radius: var(--radius);
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
}
.thallo-block-pricing_plan__cta--solid { background: var(--accent); color: var(--accent-ink); }
.thallo-block-pricing_plan__cta--outline {
  background: transparent; color: var(--accent); border-color: var(--accent);
}
.thallo-block-pricing_plan__terms { margin: 0; font-size: 0.75rem; color: var(--muted); text-align: center; }
/* solid variant dims secondary text */
.thallo-block-pricing_plan--variant-solid .thallo-block-pricing_plan__description,
.thallo-block-pricing_plan--variant-solid .thallo-block-pricing_plan__discount,
.thallo-block-pricing_plan--variant-solid .thallo-block-pricing_plan__billing-period,
.thallo-block-pricing_plan--variant-solid .thallo-block-pricing_plan__billing-cycle {
  color: color-mix(in srgb, var(--bg) 65%, transparent);
}
/* horizontal card: body and footer side by side */
@media (min-width: 64em) {
  .thallo-block-pricing_plan--orientation-horizontal { flex-direction: row; align-items: center; }
  .thallo-block-pricing_plan--orientation-horizontal .thallo-block-pricing_plan__body { flex: 2; }
  .thallo-block-pricing_plan--orientation-horizontal .thallo-block-pricing_plan__footer { flex: 1; }
}
.thallo-block-pricing_plans__items { display: flex; flex-direction: column; gap: var(--space-4); }
.thallo-block-pricing_plans__items > .thallo-block { margin-block: 0; }
@media (min-width: 48em) {
  .thallo-block-pricing_plans--orientation-horizontal .thallo-block-pricing_plans__items {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    align-items: start;
  }
  /* The plan count is a --count-{n} modifier on the root (1–6), never an inline variable. */
  .thallo-block-pricing_plans--count-2.thallo-block-pricing_plans--orientation-horizontal
    .thallo-block-pricing_plans__items { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .thallo-block-pricing_plans--count-3.thallo-block-pricing_plans--orientation-horizontal
    .thallo-block-pricing_plans__items { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .thallo-block-pricing_plans--count-4.thallo-block-pricing_plans--orientation-horizontal
    .thallo-block-pricing_plans__items { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .thallo-block-pricing_plans--count-5.thallo-block-pricing_plans--orientation-horizontal
    .thallo-block-pricing_plans__items { grid-template-columns: repeat(5, minmax(0, 1fr)); }
  .thallo-block-pricing_plans--count-6.thallo-block-pricing_plans--orientation-horizontal
    .thallo-block-pricing_plans__items { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  /* compact off widens the gap; scale + not-compact widens it more (room for the
     enlarged featured card). */
  .thallo-block-pricing_plans--orientation-horizontal:not(.thallo-block-pricing_plans--compact)
    .thallo-block-pricing_plans__items { gap: var(--space-4); }
  .thallo-block-pricing_plans--scale.thallo-block-pricing_plans--orientation-horizontal:not(.thallo-block-pricing_plans--compact)
    .thallo-block-pricing_plans__items { gap: var(--space-5); }
  /* featured plan enlarges only when the group opts into scale. */
  .thallo-block-pricing_plans--scale .thallo-block-pricing_plan--highlight { transform: scale(1.05); z-index: 1; }
}
.thallo-block-pricing_table { border-radius: var(--radius-lg); }
.thallo-block-pricing_table__table { width: 100%; border-collapse: collapse; display: none; }
.thallo-block-pricing_table__list { display: flex; flex-direction: column; gap: var(--space-4); }
@media (min-width: 48em) {
  .thallo-block-pricing_table__table { display: table; }
  .thallo-block-pricing_table__list { display: none; }
}
.thallo-block-pricing_table__tier {
  padding: var(--space-3); text-align: left; vertical-align: top; border-bottom: 1px solid var(--line);
}
.thallo-block-pricing_table__tier-badge {
  display: inline-block; padding: 0.1rem 0.5rem; border-radius: var(--radius);
  background: var(--accent); color: var(--accent-ink); font-size: 0.75rem; font-weight: 600;
}
.thallo-block-pricing_table__tier-title { display: block; font-size: 1.125rem; font-weight: 600; color: var(--ink); }
.thallo-block-pricing_table__tier-description { display: block; font-size: 0.85rem; color: var(--muted); }
.thallo-block-pricing_table__tier-price { display: block; font-size: 1.75rem; font-weight: 700; color: var(--ink); }
.thallo-block-pricing_table__section > th {
  text-align: left; padding: var(--space-3) var(--space-3) 0.5rem; font-weight: 600; color: var(--ink);
}
.thallo-block-pricing_table__row-header {
  text-align: left; padding: 0.75rem var(--space-3); font-weight: 400; color: var(--ink);
  border-bottom: 1px solid var(--line);
}
.thallo-block-pricing_table__cell {
  padding: 0.75rem var(--space-3); text-align: center; color: var(--muted); border-bottom: 1px solid var(--line);
}
.thallo-block-pricing_table__check { display: inline-flex; width: 1.25rem; height: 1.25rem; color: var(--accent); }
.thallo-block-pricing_table__check svg { width: 100%; height: 100%; }
.thallo-block-pricing_table__dash { color: var(--muted); }
.thallo-block-pricing_table__cta {
  display: inline-flex; align-items: center; justify-content: center; margin-top: 0.5rem;
  padding: 0.4rem 0.9rem; border: 1px solid transparent; border-radius: var(--radius);
  font-size: 0.85rem; font-weight: 600; text-decoration: none;
}
.thallo-block-pricing_table__cta--solid { background: var(--accent); color: var(--accent-ink); }
.thallo-block-pricing_table__cta--outline {
  background: transparent; color: var(--accent); border-color: var(--accent);
}
/* featured column shading (only when the table opts into highlight) */
.thallo-block-pricing_table--highlight .thallo-block-pricing_table__tier.is-highlighted,
.thallo-block-pricing_table--highlight .thallo-block-pricing_table__cell.is-highlighted { background: var(--surface); }
.thallo-block-pricing_table--highlight .thallo-block-pricing_table__tier.is-highlighted {
  border-top-left-radius: var(--radius-lg); border-top-right-radius: var(--radius-lg);
}
/* mobile item cards */
.thallo-block-pricing_table__item {
  border: 1px solid var(--line); border-radius: var(--radius-lg); padding: var(--space-4);
  display: flex; flex-direction: column; gap: 0.5rem;
}
.thallo-block-pricing_table__item.is-highlighted { border: 2px solid var(--accent); }
.thallo-block-pricing_table__item-head {
  display: flex; flex-direction: column; gap: 0.25rem; padding-bottom: 0.5rem; border-bottom: 1px solid var(--line);
}
.thallo-block-pricing_table__item-feature { display: flex; align-items: center; justify-content: space-between; gap: 1rem; }
/* standalone fallbacks */
.thallo-block-pricing_tier {
  display: flex; flex-direction: column; gap: 0.25rem; padding: var(--space-4);
  border: 1px solid var(--line); border-radius: var(--radius-lg);
}
.thallo-block-pricing_tier.is-highlighted { border: 2px solid var(--accent); }
.thallo-block-pricing_feature__title { color: var(--ink); }

/* ── Blog posts (refs.md blogPosts/blogPost) ────────────────────────────────
   Dynamic listing of post cards; rounded self-contained cards. */
.thallo-block-blog_posts__grid { display: grid; gap: var(--space-4); grid-template-columns: 1fr; }
@media (min-width: 48em) {
  .thallo-block-blog_posts--columns-2 .thallo-block-blog_posts__grid { grid-template-columns: repeat(2, 1fr); }
  .thallo-block-blog_posts--columns-3 .thallo-block-blog_posts__grid { grid-template-columns: repeat(3, 1fr); }
  .thallo-block-blog_posts--columns-4 .thallo-block-blog_posts__grid { grid-template-columns: repeat(4, 1fr); }
}
.thallo-block-blog_posts__card {
  display: flex; flex-direction: column; overflow: hidden;
  border-radius: var(--radius-lg); background: var(--bg); border: 1px solid var(--line);
}
.thallo-block-blog_posts--variant-soft .thallo-block-blog_posts__card { background: var(--surface); border-color: transparent; }
.thallo-block-blog_posts--variant-subtle .thallo-block-blog_posts__card { background: var(--surface); border-color: var(--line); }
.thallo-block-blog_posts--variant-ghost .thallo-block-blog_posts__card,
.thallo-block-blog_posts--variant-naked .thallo-block-blog_posts__card { background: transparent; border-color: transparent; }
.thallo-block-blog_posts__image { display: block; aspect-ratio: 16 / 9; overflow: hidden; }
.thallo-block-blog_posts__image img { width: 100%; height: 100%; object-fit: cover; }
.thallo-block-blog_posts__body { display: flex; flex-direction: column; gap: 0.5rem; padding: var(--space-4); }
.thallo-block-blog_posts__meta { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.thallo-block-blog_posts__badge {
  padding: 0.1rem 0.5rem; border-radius: var(--radius);
  background: var(--surface-2); color: var(--muted); font-size: 0.75rem; font-weight: 600;
}
.thallo-block-blog_posts__title { margin: 0; font-size: 1.25rem; font-weight: 600; color: var(--ink); }
.thallo-block-blog_posts__title a { color: inherit; text-decoration: none; }
.thallo-block-blog_posts__description { margin: 0; color: var(--muted); }
.thallo-block-blog_posts__date { font-size: 0.85rem; color: var(--muted); }
.thallo-block-blog_posts__empty {
  padding: var(--space-4); border: 1px dashed var(--line); border-radius: var(--radius-lg);
  color: var(--muted); text-align: center;
}
/* horizontal card: image beside body */
@media (min-width: 48em) {
  .thallo-block-blog_posts--orientation-horizontal .thallo-block-blog_posts__card { flex-direction: row; }
  .thallo-block-blog_posts--orientation-horizontal .thallo-block-blog_posts__image { flex: 0 0 40%; aspect-ratio: auto; }
}

/* form block (form-block spec): contact form with sealed descriptor. Inherits the
   theme's field/button tokens; the honeypot is visually removed but stays in the DOM. */
/* Self-constrains to the reading measure like every other content block (rich_text,
   heading): the entry body renders blocks as DIRECT <main> children, so each block
   owns its width — without this the form pins to the viewport's left edge. */
.thallo-block-form {
  display: grid;
  gap: 1.1rem;
  max-width: var(--content);
  margin-inline: auto;
  padding-inline: var(--space-4);
}
.thallo-block-form__heading { margin: 0; font-size: 1.5rem; font-weight: 600; color: var(--ink); }
.thallo-block-form__intro { margin: 0; color: var(--muted); }
.thallo-block-form__field { display: grid; gap: 0.375rem; }
/* Tailwind-form-style labels + controls: compact padding, a modest radius, and an
   accent focus ring — deliberately NOT the theme's large --radius/--space-3 pills. */
.thallo-block-form__field label { font-size: 0.875rem; font-weight: 500; color: var(--ink); }
.thallo-block-form__field input, .thallo-block-form__field textarea {
  width: 100%;
  padding: 0.5rem 0.75rem;
  border: 1px solid color-mix(in srgb, var(--line) 85%, var(--ink));
  border-radius: 0.5rem;
  background: var(--bg);
  color: var(--ink);
  font: inherit;
  font-size: 0.95rem;
  line-height: 1.5;
  transition: border-color 0.15s ease, outline-color 0.15s ease;
}
.thallo-block-form__field input::placeholder, .thallo-block-form__field textarea::placeholder { color: var(--muted); }
/* Focus ring via outline (not box-shadow) — accessible AND keeps the shadow-token
   single-source invariant (ShadowTokensTest) intact. */
.thallo-block-form__field input:focus, .thallo-block-form__field textarea:focus {
  border-color: var(--accent);
  outline: 2px solid color-mix(in srgb, var(--accent) 45%, transparent);
  outline-offset: 1px;
}
.thallo-block-form__field--checkbox { grid-auto-flow: column; justify-content: start; align-items: center; }
.thallo-block-form__checkbox { display: flex; gap: var(--space-2); align-items: center; font-weight: 400; }
.thallo-block-form__checkbox input { width: auto; }
.thallo-block-form__field textarea { min-height: 7rem; resize: vertical; }
/* Visual style comes from the shared button classes; this only pins alignment/cursor. */
.thallo-block-form__submit { justify-self: start; cursor: pointer; }
.thallo-block-form__hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.thallo-block-form__result { padding: 0.6rem 0.75rem; border-radius: 0.5rem; }
.thallo-block-form__result:empty { display: none; }
.thallo-block-form__result--error { background: color-mix(in srgb, #dc2626 12%, var(--bg)); color: #b91c1c; }
.thallo-block-form__result--ok { background: color-mix(in srgb, var(--accent) 12%, var(--bg)); color: var(--accent); }
.thallo-block-form--disabled {
  padding: var(--space-4); border: 1px dashed var(--line); border-radius: var(--radius); color: var(--muted);
}

/* Custom-element floor (web-components spec §5): autonomous elements default to
   display:inline; the structural elements are page sections. The toggle's
   display comes from the :where() alias above (inline-flex, for the segmented
   control row) — a bare `thallo-color-mode-toggle { display: ... }` type
   selector here would be 0,0,1 and beat the zero-specificity alias, breaking
   the flex layout, so no separate display rule is added for it. */
thallo-carousel, thallo-tabs { display: block; }
/* Feature off -> the toggle hides entirely (server stamps the flag on <html>).
   0,1,1 still wins over the :where() alias's 0,0,0. */
html:not([data-color-mode-enabled="true"]) thallo-color-mode-toggle { display: none; }

/* animated_text (modern-blocks spec §3): static floor is fully visible. Reveal CSS
   engages ONLY under --prepared (JS adds it after IO is confirmed usable); the word
   stack reserves true max width via same-cell grid. */
/* visually-hidden stable-phrase span (mirrors .thallo-block-carousel__status): carries
   prefix + first alternative + suffix for assistive tech, since `tag: 'p'` (and other
   roles that ignore aria-label) would otherwise drop the rotating word entirely. */
.thallo-block-animated_text__sr { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }
:where(.thallo-block-animated_text__rotate) { display: inline-grid; vertical-align: baseline; }
.thallo-block-animated_text__word { grid-area: 1 / 1; visibility: hidden; }
.thallo-block-animated_text__word--active { visibility: visible; }
/* Word-swap animations (2026-08: the effect previously styled only the one-time
   scroll-in reveal — every rotation was an instant visibility cut, so
   fade/slide-up/blur looked identical). Scoped to --prepared so the
   server-rendered first word never animates before the runtime takes over.

   FADE is a true CROSS-fade, and needs no JS: the words already overlap in one
   grid cell, and the outgoing word's visibility flip is DELAYED until its
   opacity finishes fading — so both words paint during the swap, yet the
   settled state keeps non-active words visibility: hidden (the exact-visible-
   phrase contract: innerText/copy-paste never pick up the hidden stack).
   Slide-up and blur animate the INCOMING word; blur settles from a deep blur
   with a slight scale-down over a longer ease-out. */
.thallo-block-animated_text--prepared.thallo-block-animated_text--fade .thallo-block-animated_text__word {
  opacity: 0;
  transition: opacity 0.5s ease, visibility 0s linear 0.5s;
}
.thallo-block-animated_text--prepared.thallo-block-animated_text--fade .thallo-block-animated_text__word--active {
  opacity: 1;
  transition: opacity 0.5s ease;
}
.thallo-block-animated_text--prepared.thallo-block-animated_text--slide-up .thallo-block-animated_text__word--active { animation: thallo-at-word-slide-up 0.5s ease; }
.thallo-block-animated_text--prepared.thallo-block-animated_text--blur .thallo-block-animated_text__word--active { animation: thallo-at-word-blur 0.7s ease-out; }
@keyframes thallo-at-word-slide-up { from { opacity: 0; transform: translateY(0.5em); } }
@keyframes thallo-at-word-blur {
  from { opacity: 0; filter: blur(14px); transform: scale(1.05); }
  60% { filter: blur(3px); }
}
/* Per-segment styling (2026-08 follow-up): one class family, applied to the
   prefix span, the rotate stack, or the suffix span. em-based sizes track the
   host heading scale. */
.thallo-block-animated_text__seg--sm { font-size: 0.75em; }
.thallo-block-animated_text__seg--lg { font-size: 1.25em; }
.thallo-block-animated_text__seg--xl { font-size: 1.5em; }
.thallo-block-animated_text__seg--bold { font-weight: 700; }
.thallo-block-animated_text__seg--italic { font-style: italic; }
.thallo-block-animated_text--prepared:not(.thallo-block-animated_text--in-view) { opacity: 0; }
.thallo-block-animated_text--prepared.thallo-block-animated_text--in-view { animation: thallo-at-fade 500ms ease-out both; }
.thallo-block-animated_text--prepared.thallo-block-animated_text--slide-up.thallo-block-animated_text--in-view { animation-name: thallo-at-slide-up; }
.thallo-block-animated_text--prepared.thallo-block-animated_text--blur.thallo-block-animated_text--in-view { animation-name: thallo-at-blur; }
@keyframes thallo-at-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes thallo-at-slide-up { from { opacity: 0; transform: translateY(0.6em); } to { opacity: 1; transform: none; } }
@keyframes thallo-at-blur { from { opacity: 0; filter: blur(8px); } to { opacity: 1; filter: none; } }
@media (prefers-reduced-motion: reduce) {
  .thallo-block-animated_text--prepared { opacity: 1 !important; animation: none !important; }
  .thallo-block-animated_text__word { animation: none !important; transition: none !important; }
}

/* gallery (modern-blocks spec §4): the grid + real anchors are the no-JS floor. */
.thallo-block-gallery { display: grid; gap: var(--space-2); max-width: var(--container); margin-inline: auto; padding-inline: var(--space-4); }
.thallo-block-gallery--cols-2 { grid-template-columns: repeat(2, 1fr); }
.thallo-block-gallery--cols-3 { grid-template-columns: repeat(3, 1fr); }
.thallo-block-gallery--cols-4 { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 40rem) { .thallo-block-gallery { grid-template-columns: repeat(2, 1fr); } }
.thallo-block-gallery__item { display: block; min-width: 0; color: inherit; overflow: hidden; }
/* An item is a nested image block, not a bare img: neutralize its standalone
   container before applying gallery geometry. Natural mode keeps its authored
   ratio/caption; fixed crops make the figure the containing block and overlay the
   caption so it cannot break the tile's aspect ratio. */
.thallo-block-gallery__item .thallo-block-image {
  max-width: none; height: 100%; margin: 0; padding: 0; position: relative;
}
.thallo-block-gallery__item .thallo-block-image img {
  display: block; width: 100%; max-width: none; height: auto; box-shadow: none;
}
.thallo-block-gallery--square .thallo-block-gallery__item { aspect-ratio: 1; }
.thallo-block-gallery--landscape .thallo-block-gallery__item { aspect-ratio: 3 / 2; }
.thallo-block-gallery--square .thallo-block-image img,
.thallo-block-gallery--landscape .thallo-block-image img { height: 100%; object-fit: cover; }
.thallo-block-gallery--square .thallo-block-image figcaption,
.thallo-block-gallery--landscape .thallo-block-image figcaption {
  position: absolute; inset: auto 0 0; margin: 0; padding: var(--space-2);
  color: var(--on-media); background: rgb(0 0 0 / 0.62);
}
/* Lightbox (2026-08 modernization): the dialog IS the full-viewport stage —
   near-opaque blurred backdrop so the page never glares through, a contained
   centered image, and overlay chrome (side arrows, top-right close,
   bottom-center counter) in the translucent white-on-dark chip language.
   The bar is display: contents so each control positions against the stage. */
.thallo-block-gallery__dialog {
  border: 0;
  padding: 0;
  background: transparent;
  width: 100vw;
  height: 100svh;
  max-width: none;
  max-height: none;
}
/* [open]-scoped: an unconditional display would override the UA's
   dialog:not([open]) { display: none } and leave a CLOSED full-viewport
   dialog invisibly covering the page. */
.thallo-block-gallery__dialog[open] {
  display: grid;
  place-items: center;
}
.thallo-block-gallery__dialog::backdrop {
  background: rgb(9 11 17 / 0.92);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}
.thallo-block-gallery__dialog img {
  max-width: min(94vw, 90rem);
  max-height: 82svh;
  object-fit: contain;
  border-radius: 0.5rem;
  box-shadow: var(--shadow-2xl);
  display: block;
  margin: 0;
}
.thallo-block-gallery__bar { display: contents; }
.thallo-block-gallery__prev,
.thallo-block-gallery__next,
.thallo-block-gallery__close {
  position: absolute;
  width: 2.75rem;
  height: 2.75rem;
  border: 0;
  border-radius: 999px;
  background: rgb(255 255 255 / 0.14);
  color: #fff;
  font-size: 1.35rem;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background-color 0.15s ease;
}
.thallo-block-gallery__prev:hover,
.thallo-block-gallery__next:hover,
.thallo-block-gallery__close:hover { background: rgb(255 255 255 / 0.28); }
.thallo-block-gallery__prev:focus-visible,
.thallo-block-gallery__next:focus-visible,
.thallo-block-gallery__close:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
.thallo-block-gallery__prev { left: max(1rem, env(safe-area-inset-left)); top: 50%; transform: translateY(-50%); }
.thallo-block-gallery__next { right: max(1rem, env(safe-area-inset-right)); top: 50%; transform: translateY(-50%); }
.thallo-block-gallery__close { top: max(1rem, env(safe-area-inset-top)); right: max(1rem, env(safe-area-inset-right)); }
.thallo-block-gallery__status {
  position: absolute;
  bottom: max(1.25rem, env(safe-area-inset-bottom));
  left: 50%;
  transform: translateX(-50%);
  padding: 0.3rem 0.85rem;
  border-radius: 999px;
  background: rgb(0 0 0 / 0.5);
  color: rgb(255 255 255 / 0.92);
  font-size: 0.85rem;
  letter-spacing: 0.02em;
}
@media (prefers-reduced-motion: no-preference) {
  .thallo-block-gallery__dialog[open] { animation: thallo-at-fade 150ms ease-out; }
}

/* Canvas empty-states for region blocks (blog_posts__empty precedent): preview-only
   markup, so these bind only inside the editor canvas. */
.thallo-block-carousel__empty,
.thallo-block-gallery__empty {
  padding: var(--space-4); border: 1px dashed var(--line); border-radius: var(--radius-lg);
  color: var(--muted); text-align: center;
}
.thallo-block-gallery__empty { grid-column: 1 / -1; }

/* code — a snippet with a language label and a copy button. The root is the width and
   spacing box; __panel is the framed figure that carries the corners and the shadow (the
   block's `panel` style target), so t-radius-* / t-shadow-* land here. */
.thallo-block-code {
  max-width: var(--content); margin-inline: auto; padding-inline: var(--space-4);
}
.thallo-block-code__panel {
  margin: 0; border: 1px solid var(--line); border-radius: var(--radius-lg); overflow: hidden;
  background: var(--bg);
}
/* The title bar of a window: tinted, over a light body, with its three lights. */
.thallo-block-code__caption {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--line);
  background: var(--surface);
  font-size: 0.8125rem; color: var(--muted);
}
.thallo-block-code__label { font-family: var(--font-mono, ui-monospace, monospace); text-transform: lowercase; }
/* Three lights, drawn: one gradient tile repeated three times. Decoration, so never in the
   markup — and not box-shadow, which in this theme is elevation and comes from the shadow tokens. */
.thallo-block-code__label::before {
  content: ""; display: inline-block; vertical-align: middle;
  width: 2.8125rem; height: 0.5625rem; margin-inline-end: var(--space-2);
  background: radial-gradient(circle at 0.28125rem 50%, var(--line) 0 0.28125rem, transparent 0.3rem)
    0 0 / 0.9375rem 100% repeat-x;
}
/* Long lines wrap (pre-wrap, breaking inside a long token when nothing else fits): the snippet
   never scrolls sideways, so every line is readable and copyable in place. */
.thallo-block-code__pre {
  margin: 0; padding: var(--space-3) var(--space-4);
  white-space: pre-wrap; overflow-wrap: anywhere;
  color: var(--ink);
  font-family: var(--font-mono, ui-monospace, monospace); font-size: 0.875rem; line-height: 1.6;
  tab-size: 2;
}
/* A shell snippet's lines (blocks/code.twig). Each is a block holding its own newline: that
   newline adds no second line, and gives an empty line its height (both held by the browser
   proof `code-shell-lines`). */
.thallo-block-code__line { display: block; }
/* The prompt is DRAWN: generated content is in neither the text the Copy button takes nor a
   selection, so what leaves the page is a command that can be pasted. The hanging indent puts it
   in the margin of its own line, and a long command wraps under the command, not under the "$". */
.thallo-block-code__line--prompt { padding-inline-start: 2ch; text-indent: -2ch; }
.thallo-block-code__line--prompt::before { content: "$ "; color: var(--accent); }
.thallo-block-code__line--comment { color: var(--muted); }
/* The note sits on the caption's right, pushing the actions (Copy) after it. */
.thallo-block-code__note { margin-inline-start: auto; font-family: var(--font-mono, ui-monospace, monospace); color: var(--muted); }
/* size: compact — a dense snippet set smaller and closer. */
.thallo-block-code--compact .thallo-block-code__pre { font-size: 0.8rem; line-height: 1.55; padding: 0.875rem 1.125rem; }
.thallo-block-code__copy {
  font: inherit; color: inherit; background: var(--bg); border: 1px solid var(--line);
  border-radius: var(--radius-sm, 6px); padding: 0.125rem var(--space-2); cursor: pointer;
}
.thallo-block-code__copy:hover, .thallo-block-code__copy:focus-visible { border-color: var(--accent); color: var(--accent); }

/* Field blocks (type layouts spec §4) — the entry's own title, date, cover, excerpt, terms, fields,
   neighbours and related list, placed by a layout. Text sits on the reading measure like a heading;
   the cover takes the container width. entry_content is a pass-through: the entry's blocks keep
   their own containment. */
.thallo-block-entry_title, .thallo-block-entry_date, .thallo-block-entry_excerpt, .thallo-block-entry_field, .thallo-block-entry_terms, .thallo-block-entry_neighbours, .thallo-block-entry_related {
  max-width: var(--content);
  margin-inline: auto;
  padding-inline: var(--space-4);
}
.thallo-block-entry_date,
.thallo-block-entry_field { display: block; color: var(--muted); font-size: 0.95rem; }
.thallo-block-entry_excerpt { color: var(--muted); font-size: clamp(1.05rem, 1rem + 0.3vw, 1.2rem); line-height: 1.55; }
.thallo-block-entry_excerpt--clamp-1,
.thallo-block-entry_excerpt--clamp-2,
.thallo-block-entry_excerpt--clamp-3,
.thallo-block-entry_excerpt--clamp-4,
.thallo-block-entry_excerpt--clamp-5,
.thallo-block-entry_excerpt--clamp-6 { display: -webkit-box; -webkit-box-orient: vertical; overflow: hidden; }
.thallo-block-entry_excerpt--clamp-1 { -webkit-line-clamp: 1; line-clamp: 1; }
.thallo-block-entry_excerpt--clamp-2 { -webkit-line-clamp: 2; line-clamp: 2; }
.thallo-block-entry_excerpt--clamp-3 { -webkit-line-clamp: 3; line-clamp: 3; }
.thallo-block-entry_excerpt--clamp-4 { -webkit-line-clamp: 4; line-clamp: 4; }
.thallo-block-entry_excerpt--clamp-5 { -webkit-line-clamp: 5; line-clamp: 5; }
.thallo-block-entry_excerpt--clamp-6 { -webkit-line-clamp: 6; line-clamp: 6; }

.thallo-block-entry_cover {
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--space-4);
}
.thallo-block-entry_cover__image { display: block; width: 100%; max-width: 100%; }
.thallo-block-entry_cover--16-9 .thallo-block-entry_cover__image { aspect-ratio: 16 / 9; object-fit: cover; }
.thallo-block-entry_cover--4-3 .thallo-block-entry_cover__image { aspect-ratio: 4 / 3; object-fit: cover; }
.thallo-block-entry_cover--1-1 .thallo-block-entry_cover__image { aspect-ratio: 1; object-fit: cover; }
.thallo-block-entry_cover--natural .thallo-block-entry_cover__image { height: auto; }

.thallo-block-entry_terms--badges { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.thallo-block-entry_terms--badges .thallo-block-entry_terms__term {
  padding: 0.15em 0.65em;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface);
  font-size: 0.85rem;
  text-decoration: none;
}
.thallo-block-entry_terms--text .thallo-block-entry_terms__term + .thallo-block-entry_terms__term::before { content: ", "; }

.thallo-block-entry_neighbours { display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--space-4); }
.thallo-block-entry_neighbours__link { display: flex; flex-direction: column; gap: var(--space-1); max-width: 48%; text-decoration: none; }
.thallo-block-entry_neighbours__link--next { margin-inline-start: auto; text-align: end; }
.thallo-block-entry_neighbours__label { color: var(--muted); font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.04em; }
.thallo-block-entry_neighbours__title { font-weight: 600; }

.thallo-block-entry_related__grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr)); gap: var(--space-4); }
.thallo-block-entry_related__card { display: flex; flex-direction: column; gap: var(--space-1); padding: var(--space-4); border: 1px solid var(--line); border-radius: var(--radius, 0.5rem); text-decoration: none; }
.thallo-block-entry_related__title { font-weight: 600; }
.thallo-block-entry_related__date { color: var(--muted); font-size: 0.85rem; }

/* The Entry list (type layouts plan B): the Layout tab arranges its cards — rows, or a grid of
   cards — on `__cards`; a card's own content is block flow, not a flex or grid of the loop's. Today's
   `.listing-row` is a flex row (thumbnail beside text); a card keeps its padding and rule and drops
   the flex — the starter's card holds a row container instead. The list itself sits where today's
   rows do: no block margin of its own. */
.thallo-block-entry_loop { margin-block: 0; }
.thallo-block-entry_loop__cards > .thallo-loop-card { display: block; }
.listing-empty { color: var(--muted); }

/* A card is a content area, as a container's is (its containment release above): its blocks leave
   the page's reading column and carry no block margin — the card's padding and the containers in it
   space them. On the stage each block sits in a selection wrapper, released alike. */
:is(.thallo-loop-card, .thallo-loop-card > .thallo-preview-block) > .thallo-block { margin-block: 0; }
:is(.thallo-loop-card, .thallo-loop-card > .thallo-preview-block) > :is(
  .thallo-block-image,
  .thallo-block-rich_text,
  .thallo-block-heading,
  .thallo-block-tabs,
  .thallo-block-button,
  .thallo-block-carousel,
  .thallo-block-logo,
  .thallo-block-icon,
  .thallo-block-video,
  .thallo-block-audio,
  .thallo-block-file,
  .thallo-block-html,
  .thallo-block-shortcode,
  .thallo-block-separator,
  .thallo-block-form,
  .thallo-block-gallery,
  .thallo-block-code,
  .thallo-block-map,
  .thallo-block-entry_title,
  .thallo-block-entry_date,
  .thallo-block-entry_cover,
  .thallo-block-entry_excerpt,
  .thallo-block-entry_field,
  .thallo-block-entry_terms,
  .thallo-block-entry_neighbours,
  .thallo-block-entry_related,
  .thallo-block-container
) {
  max-width: none;
  margin-inline: 0;
  padding-inline: 0;
}

/* A card's defaults are today's row (the user's B7 ruling): a container in it steps its children
   1.25rem apart (0.875rem on phones) rather than the page's 2.5rem; the cover is a 160px thumbnail
   (96px on phones), cropped and rounded while its aspect is natural; the title is the text size in
   the row's weight, the date small, the excerpt the text size. A value set on the block wins. */
.thallo-loop-card .thallo-block-container__inner { gap: 1.25rem; }
/* A container in a card may shrink below its longest word, as today's row's text column does
   (`.listing-row__content { min-width: 0 }`): a narrow card — a grid of cards on a phone — wraps its
   text inside the card instead of pushing it out. */
.thallo-loop-card .thallo-block-container { min-width: 0; }
.thallo-loop-card .thallo-block-entry_cover { flex: 0 0 auto; width: 160px; }
.thallo-loop-card .thallo-block-entry_cover--natural .thallo-block-entry_cover__image {
  aspect-ratio: 160 / 110;
  object-fit: cover;
  border-radius: 0.5rem;
}
.thallo-loop-card .thallo-block-entry_title { font-size: inherit; line-height: inherit; font-weight: 650; }
.thallo-loop-card .thallo-block-entry_title a { color: var(--ink); text-decoration: none; }
.thallo-loop-card .thallo-block-entry_title a:hover { text-decoration: underline; }
.thallo-loop-card .thallo-block-entry_date { font-size: 0.85rem; line-height: inherit; }
.thallo-loop-card .thallo-block-entry_excerpt { font-size: inherit; line-height: inherit; }
@media (max-width: 48rem) {
  .thallo-loop-card .thallo-block-container__inner { gap: 0.875rem; }
  .thallo-loop-card .thallo-block-entry_cover { width: 96px; }
  .thallo-loop-card .thallo-block-entry_cover--natural .thallo-block-entry_cover__image { aspect-ratio: 96 / 72; }
}

/* The listing page's title and navigation keep today's margins: the heading's own, the navigation
   none (its spacing is the pagination rule's). */
.thallo-block-listing_title { margin-block: 0.67em; }
.thallo-block-pagination { margin-block: 0; }

/* An empty field on a layout stage names itself (never rendered on the site). */
.thallo-field-empty {
  padding: var(--space-3) var(--space-4);
  border: 1px dashed var(--line);
  border-radius: var(--radius, 0.5rem);
  color: var(--muted);
  font-size: 0.9rem;
}

/* navigation.css */
/* ─────────────────────────────────────────────────────────────────────────
   navigation block — menu-sourced nav with a variant/color/highlight style
   model (concepts lifted from Nuxt UI's navigationMenu, re-expressed in this
   theme's tokens and a static, CSS-only submenu mechanism).

   Two layers:
   1. FLOOR (no JS): EVERY parent is a native <details>/<summary> disclosure
      (unified tree, theme-runtime spec §3.2) — click toggles work everywhere;
      hover mode ADDS a desktop-only :hover/:focus-within reveal on top of the
      same markup. Works in the preview canvas and for no-JS clients / SEO.
   2. ENHANCEMENT (runtime.js navigation module, live pages only): animation,
      Escape/outside-click close, one-open-sibling, hover intent. When present
      the script sets .thallo-block-navigation--js on the root, which
      suppresses the raw closed-details hover reveal so the delayed open
      state governs instead.

   Accent is funnelled through --nav-accent so `color` swaps one variable:
   primary → brand --accent, neutral → monochrome --ink.
   ───────────────────────────────────────────────────────────────────────── */
:where(.thallo-block-navigation, thallo-navigation) { --nav-accent: var(--accent); --nav-accent-ink: var(--accent-ink); }
.thallo-block-navigation--color-neutral { --nav-accent: var(--ink); --nav-accent-ink: var(--bg); }

/* ── Bar + list ──────────────────────────────────────────────────────────── */
.thallo-block-navigation__nav { display: block; }
.thallo-block-navigation__list {
  display: flex; gap: var(--space-2); flex-wrap: wrap; align-items: center;
  list-style: none; margin: 0; padding: 0;
}
.thallo-block-navigation--vertical .thallo-block-navigation__list {
  flex-direction: column; gap: var(--space-1); align-items: stretch;
}
.thallo-block-navigation--align-start .thallo-block-navigation__list { justify-content: flex-start; }
.thallo-block-navigation--align-center .thallo-block-navigation__list { justify-content: center; }
.thallo-block-navigation--align-end .thallo-block-navigation__list { justify-content: flex-end; }
.thallo-block-navigation--size-sm { font-size: 0.85rem; }
.thallo-block-navigation--size-md { font-size: 0.95rem; }
.thallo-block-navigation--size-lg { font-size: 1.1rem; }

/* ── Top-level link (a / span / summary all share __link) ────────────────── */
.thallo-block-navigation__item { min-width: 0; }
.thallo-block-navigation__link {
  position: relative;
  display: inline-flex; align-items: center; gap: 0.4em;
  padding: 0.4em 0.7em; border-radius: var(--radius);
  color: var(--muted); text-decoration: none; cursor: pointer;
  font: inherit; background: none; border: 0; white-space: nowrap;
  transition: color .15s ease, background-color .15s ease;
}
.thallo-block-navigation__link:hover,
.thallo-block-navigation__link:focus-visible { color: var(--ink); }
.thallo-block-navigation__icon { display: inline-flex; }
.thallo-block-navigation__icon svg { width: 1.1em; height: 1.1em; }
.thallo-block-navigation__chevron { display: inline-flex; transition: transform .2s ease; }
.thallo-block-navigation__chevron svg { width: 0.9em; height: 0.9em; }
.thallo-block-navigation__label { min-width: 0; overflow: hidden; text-overflow: ellipsis; }

/* ── variant: pill (filled hover/active chip) ────────────────────────────── */
.thallo-block-navigation--pill .thallo-block-navigation__link:hover { background: var(--surface); }
.thallo-block-navigation--pill .thallo-block-navigation__item--active > .thallo-block-navigation__link {
  background: var(--nav-accent); color: var(--nav-accent-ink);
}
/* ── variant: link (plain text, accent on active) ────────────────────────── */
.thallo-block-navigation--link .thallo-block-navigation__item--active > .thallo-block-navigation__link {
  color: var(--nav-accent);
}

/* ── highlight indicator (::after) ───────────────────────────────────────────
   Present on every link (under the highlight-* variants only), hidden by default
   and revealed under the ACTIVE item AND on hover/focus — so the indicator is
   visible on interaction even where no item is "active" (e.g. the admin chrome
   preview, which has no current_path). Geometry is set per orientation; opacity
   is the on/off switch, giving a soft fade. */
.thallo-block-navigation--highlight-underline .thallo-block-navigation__link::after,
.thallo-block-navigation--highlight-bar .thallo-block-navigation__link::after {
  content: ""; position: absolute; background: var(--nav-accent);
  border-radius: 999px; opacity: 0; transition: opacity .2s ease;
}
/* horizontal → bottom line (bar is thicker) */
.thallo-block-navigation--horizontal.thallo-block-navigation--highlight-underline .thallo-block-navigation__link::after {
  inset-inline: 0.7em; bottom: -2px; height: 2px;
}
.thallo-block-navigation--horizontal.thallo-block-navigation--highlight-bar .thallo-block-navigation__link::after {
  inset-inline: 0.5em; bottom: -3px; height: 3px;
}
/* vertical → start-side bar */
.thallo-block-navigation--vertical.thallo-block-navigation--highlight-underline .thallo-block-navigation__link::after,
.thallo-block-navigation--vertical.thallo-block-navigation--highlight-bar .thallo-block-navigation__link::after {
  top: 0.3em; bottom: 0.3em; inset-inline-start: -3px; width: 3px;
}
/* reveal under the active item, and on hover/focus of any top-level item */
.thallo-block-navigation--highlight-underline .thallo-block-navigation__item--active > .thallo-block-navigation__link::after,
.thallo-block-navigation--highlight-underline .thallo-block-navigation__item:hover > .thallo-block-navigation__link::after,
.thallo-block-navigation--highlight-underline .thallo-block-navigation__item:focus-within > .thallo-block-navigation__link::after,
.thallo-block-navigation--highlight-bar .thallo-block-navigation__item--active > .thallo-block-navigation__link::after,
.thallo-block-navigation--highlight-bar .thallo-block-navigation__item:hover > .thallo-block-navigation__link::after,
.thallo-block-navigation--highlight-bar .thallo-block-navigation__item:focus-within > .thallo-block-navigation__link::after {
  opacity: 1;
}

/* ── Submenu panel ───────────────────────────────────────────────────────── */
.thallo-block-navigation__item--parent { position: relative; }
.thallo-block-navigation__submenu {
  list-style: none; margin: 0; padding: var(--space-2);
  min-width: 12rem; display: none; z-index: 30;
  background: var(--bg); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow-lg);
}
/* Floating dropdown panels are desktop-only — under the breakpoint panels
   expand in flow (mobile pinned rules, theme-runtime spec §3.2).
   48rem: the navigation component's named v1 breakpoint (theme-runtime spec §3.2) */
@media (min-width: 48.01rem) {
  .thallo-block-navigation--horizontal .thallo-block-navigation__details > .thallo-block-navigation__submenu {
    position: absolute; top: 100%; inset-inline-start: 0; margin-top: var(--space-1);
  }
}

/* Floor reveals ---------------------------------------------------------- */
.thallo-block-navigation__details > summary { list-style: none; }
.thallo-block-navigation__details > summary::-webkit-details-marker { display: none; }
.thallo-block-navigation__details[open] > [data-nav-panel] { display: block; }
/* …but a megamenu panel opens as the grid it lays out with, not a block. */
.thallo-block-navigation__details[open] > .thallo-block-navigation__submenu--columns { display: grid; }
/* Visible focus on the disclosure controls (theme-runtime spec §3.2). */
.thallo-block-navigation__hamburger:focus-visible,
.thallo-block-navigation__details > summary:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px;
}

/* Enhanced state: script drives .is-open (both modes) ------------------- */
.thallo-block-navigation__item--parent.is-open > .thallo-block-navigation__details > [data-nav-panel] { display: block; }
.thallo-block-navigation__item--parent.is-open > .thallo-block-navigation__details > .thallo-block-navigation__submenu--columns { display: grid; }
/* With JS active, suppress the raw closed-details hover reveal so hover-intent
   (delay) wins; a natively [open] details always keeps its panel visible. */
.thallo-block-navigation--js.thallo-block-navigation--reveal-hover .thallo-block-navigation__item--parent:hover > .thallo-block-navigation__details:not([open]) > [data-nav-panel],
.thallo-block-navigation--js.thallo-block-navigation--reveal-hover .thallo-block-navigation__item--parent:focus-within > .thallo-block-navigation__details:not([open]) > [data-nav-panel] { display: none; }

/* chevron rotates when the panel is open (floor + enhanced) */
.thallo-block-navigation--reveal-hover .thallo-block-navigation__item--parent:hover > .thallo-block-navigation__details > summary .thallo-block-navigation__chevron,
.thallo-block-navigation--reveal-hover .thallo-block-navigation__item--parent:focus-within > .thallo-block-navigation__details > summary .thallo-block-navigation__chevron,
.thallo-block-navigation__details[open] > summary .thallo-block-navigation__chevron,
.thallo-block-navigation__item--parent.is-open > .thallo-block-navigation__details > summary .thallo-block-navigation__chevron { transform: rotate(180deg); }

/* ── Mobile disclosure stack ─────────────────────────────────────────────────
   48rem: the navigation component's named v1 breakpoint (theme-runtime spec §3.2) */
.thallo-block-navigation__hamburger {
  display: none; cursor: pointer; list-style: none;
  min-height: 44px; min-width: 44px; align-items: center; justify-content: center;
  gap: var(--space-2); padding: var(--space-2) var(--space-3);
  border: 1px solid var(--line); border-radius: 0.5rem; color: var(--ink);
}
.thallo-block-navigation__hamburger:hover { border-color: var(--muted); }
.thallo-block-navigation__hamburger::-webkit-details-marker { display: none; }
/* The hamburger glyph: three CSS bars morphing to an X while open. Accessible
   name comes from the visually hidden "Menu" label beside it. */
.thallo-block-navigation__hamburger-icon {
  position: relative; display: inline-block;
  width: 1.125rem; height: 2px; border-radius: 1px; background: currentColor;
}
.thallo-block-navigation__hamburger-icon::before,
.thallo-block-navigation__hamburger-icon::after {
  content: ""; position: absolute; left: 0; width: 100%; height: 2px;
  border-radius: 1px; background: currentColor;
}
.thallo-block-navigation__hamburger-icon::before { top: -5px; }
.thallo-block-navigation__hamburger-icon::after { top: 5px; }
details[open] > .thallo-block-navigation__hamburger .thallo-block-navigation__hamburger-icon { background: transparent; }
details[open] > .thallo-block-navigation__hamburger .thallo-block-navigation__hamburger-icon::before { top: 0; transform: rotate(45deg); }
details[open] > .thallo-block-navigation__hamburger .thallo-block-navigation__hamburger-icon::after { top: 0; transform: rotate(-45deg); }
@media (prefers-reduced-motion: no-preference) {
  /* Micro-feedback on the glyph only — menu expansion animation stays runtime-owned. */
  .thallo-block-navigation__hamburger-icon,
  .thallo-block-navigation__hamburger-icon::before,
  .thallo-block-navigation__hamburger-icon::after {
    transition: transform 0.15s ease, top 0.15s ease, background-color 0.15s ease;
  }
}
/* Visually hidden label: keeps the summary's accessible name "Menu" with an
   icon-only visual (theme-runtime spec §7). */
.thallo-block-navigation__hamburger-label {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
  white-space: nowrap; border: 0;
}
@media (max-width: 48rem) {
  .thallo-block-navigation__hamburger { display: flex; }
  .thallo-block-navigation__mobile:not([open]) > .thallo-block-navigation__list,
  .site-nav__mobile:not([open]) > .site-nav__list { display: none; }
  /* Header placement: the hamburger sits at the far right of the header row;
     while open, the nav container claims the full row so the list stacks
     beneath the header line (in flow — content is pushed, never overlaid).
     Browsers without :has() keep the in-row expansion — degraded, not broken. */
  .site-header__inner { flex-wrap: wrap; }
  .site-header__inner :where(.thallo-block-navigation, thallo-navigation),
  .site-header__inner > .site-nav { margin-left: auto; }
  .site-header__inner :where(.thallo-block-navigation, thallo-navigation):has(.thallo-block-navigation__mobile[open]),
  .site-header__inner > .site-nav:has(.site-nav__mobile[open]) { flex-basis: 100%; }
  .thallo-block-navigation__hamburger { margin-left: auto; width: max-content; }
  /* Open list: a full-width stacked menu with touch-sized, separated rows. */
  .thallo-block-navigation__list { flex-direction: column; align-items: stretch; gap: 0; }
  .site-nav__mobile > .site-nav__list {
    flex-direction: column; align-items: stretch; gap: 0;
    padding: var(--space-2) 0 var(--space-3);
  }
  .site-nav__mobile > .site-nav__list a {
    display: flex; min-height: 44px; align-items: center;
    padding: var(--space-2) var(--space-3); border-radius: 0.375rem;
  }
  .site-nav__mobile > .site-nav__list li + li { border-top: 1px solid var(--line); }
  .thallo-block-navigation__mobile > .thallo-block-navigation__list {
    padding: var(--space-2) 0 var(--space-3);
  }
  .thallo-block-navigation__mobile .thallo-block-navigation__item + .thallo-block-navigation__item {
    border-top: 1px solid var(--line);
  }
  .thallo-block-navigation__mobile .thallo-block-navigation__link {
    width: 100%; min-height: 44px;
  }
  .site-nav__mobile > .site-nav__list a[aria-current="page"],
  .thallo-block-navigation__mobile .thallo-block-navigation__link[aria-current="page"] {
    color: var(--accent); font-weight: 600;
  }
  .thallo-block-navigation__submenu,
  .thallo-block-navigation__submenu--columns {
    position: static; min-width: 0; box-shadow: none; border: 0;
  }
  .thallo-block-navigation__details > summary { min-height: 44px; }
}
@media (min-width: 48.01rem) {
  /* Desktop: the outer mobile details is chrome-less — list always visible. */
  .thallo-block-navigation__mobile > .thallo-block-navigation__list,
  .site-nav__mobile > .site-nav__list { display: flex; }
  /* A closed <details> hides its slotted content through the ::details-content
     pseudo (content-visibility) — display rules on the light-DOM children
     alone cannot reveal it. Surface the content so the always-visible desktop
     list and the closed-details hover reveal below actually show; browsers
     without ::details-content ignore these rules (the runtime opens the
     details there). Kept as standalone rules: an unknown pseudo-element would
     invalidate any selector list it is grouped into. */
  .thallo-block-navigation__mobile::details-content { content-visibility: visible; }
  .site-nav__mobile::details-content { content-visibility: visible; }
  .thallo-block-navigation--reveal-hover .thallo-block-navigation__item--parent:hover > .thallo-block-navigation__details::details-content { content-visibility: visible; }
  .thallo-block-navigation--reveal-hover .thallo-block-navigation__item--parent:focus-within > .thallo-block-navigation__details::details-content { content-visibility: visible; }
  /* Hover mode: reveal on hover/focus-within even while the details is closed. */
  .thallo-block-navigation--reveal-hover
    .thallo-block-navigation__item--parent:hover > .thallo-block-navigation__details > [data-nav-panel],
  .thallo-block-navigation--reveal-hover
    .thallo-block-navigation__item--parent:focus-within > .thallo-block-navigation__details > [data-nav-panel] {
    display: block;
  }
  .thallo-block-navigation--reveal-hover
    .thallo-block-navigation__item--parent:hover > .thallo-block-navigation__details > .thallo-block-navigation__submenu--columns,
  .thallo-block-navigation--reveal-hover
    .thallo-block-navigation__item--parent:focus-within > .thallo-block-navigation__details > .thallo-block-navigation__submenu--columns {
    display: grid;
  }
}

/* Vertical submenu = inline disclosure (no floating panel) */
.thallo-block-navigation--vertical .thallo-block-navigation__submenu {
  position: static; box-shadow: none; border: 0; min-width: 0;
  padding-block: var(--space-1); padding-inline-start: var(--space-4);
}

/* ── Sub-links ───────────────────────────────────────────────────────────── */
.thallo-block-navigation__subitem { list-style: none; }
.thallo-block-navigation__sublink {
  display: flex; align-items: flex-start; gap: 0.4em;
  padding: 0.4em 0.6em; border-radius: var(--radius);
  color: var(--muted); text-decoration: none;
  transition: color .15s ease, background-color .15s ease;
}
.thallo-block-navigation__sublink:hover,
.thallo-block-navigation__sublink:focus-visible { color: var(--ink); background: var(--surface); }
.thallo-block-navigation__subitem--active > .thallo-block-navigation__sublink { color: var(--nav-accent); }
/* icon aligns to the first text line (label) when a description stacks below */
.thallo-block-navigation__sublink .thallo-block-navigation__icon { margin-top: 0.1em; }
.thallo-block-navigation__subtext { display: flex; flex-direction: column; gap: 0.1em; min-width: 0; }
.thallo-block-navigation__sublabel { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
/* per-item description (nav-v2 megamenu): a muted supporting line under the label */
.thallo-block-navigation__subdesc {
  font-size: 0.85em; font-weight: 400; color: var(--muted); line-height: 1.35;
}

/* ── Megamenu columns ────────────────────────────────────────────────────── */
.thallo-block-navigation__submenu--columns {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: var(--space-3); padding: var(--space-3);
  /* Clamp the megamenu to the viewport (theme-runtime spec §3.2). */
  min-width: min(28rem, calc(100vw - 2 * var(--space-4)));
}
.thallo-block-navigation--vertical .thallo-block-navigation__submenu--columns {
  min-width: 0; grid-template-columns: 1fr; gap: var(--space-2);
}
.thallo-block-navigation__col-title {
  display: block; font-weight: 600; color: var(--ink); text-decoration: none;
  padding: 0.3em 0.6em; margin-bottom: var(--space-1);
}
a.thallo-block-navigation__col-title:hover { color: var(--nav-accent); }
.thallo-block-navigation__col-desc {
  display: block; font-size: 0.85em; color: var(--muted); line-height: 1.35;
  padding-inline: 0.6em; margin: -0.15em 0 var(--space-1);
}
.thallo-block-navigation__col-list { list-style: none; margin: 0; padding: 0; }

/* ── In a chrome region the nav takes the free space between logo + actions ── */
.thallo-region :where(.thallo-block-navigation, thallo-navigation) { flex: 1; min-width: 0; }

/* ── Reduced motion ──────────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .thallo-block-navigation__chevron,
  .thallo-block-navigation__link,
  .thallo-block-navigation__sublink { transition: none; }
}

/* Custom-element floor (web-components spec §5). */
thallo-navigation { display: block; }

/* stepper.css */
/* ─────────────────────────────────────────────────────────────────────────
   stepper block — a numbered, NON-interactive display sequence (replaces the
   legacy steps/step). Concepts lifted from Nuxt UI's `stepper` (docs/refs.md),
   re-expressed in this theme's tokens and stripped of all interactive/stateful
   variants: every marker is a resting, filled circle (no active/completed
   state, no JS).

   Two orientations:
     horizontal → markers in a ROW, body stacked beneath each, connectors are
                  horizontal segments spanning the gap between adjacent markers.
     vertical   → markers in a COLUMN, body beside each, connectors are vertical
                  segments dropping from one marker to the next.

   Sizing is funnelled through per-size custom properties set on the
   --size-* modifier (marker diameter, number font, body gap, type scale), so
   every rule below reads the same handful of variables.

   COLOUR: this theme has no semantic palette yet, so `color` is funnelled
   through --step-accent / --step-accent-ink:
     primary → brand --accent
     neutral → monochrome --ink
     secondary / success / info / warning / error → all FALL BACK to --accent
       (no semantic tokens exist in the theme; revisit if they are added).
   The marker is a filled circle: background = the mapped colour, number text =
   the mapped ink. Connectors use the subtle --line rule colour.
   ───────────────────────────────────────────────────────────────────────── */
.thallo-block-stepper {
  /* colour funnel (primary + all non-neutral fallbacks) */
  --step-accent: var(--accent);
  --step-accent-ink: var(--accent-ink);
  /* geometry (md defaults; overridden per --size-* below) */
  --step-marker: 2.5rem;   /* circle diameter */
  --step-num: 1rem;        /* number font-size */
  --step-type: 0.9rem;     /* title/description font-size */
  --step-gap: 0.625rem;    /* marker↔body gap */
  --step-conn: 2px;        /* connector thickness */
  --step-conn-inset: var(--space-1);  /* connector clearance from marker edge */
  --step-row-gap: var(--space-4);     /* vertical: space between stacked items */
}

/* neutral → monochrome; secondary/success/info/warning/error inherit the
   primary --accent fallback declared above (no semantic tokens in this theme). */
.thallo-block-stepper--color-neutral {
  --step-accent: var(--ink);
  --step-accent-ink: var(--bg);
}

/* ── Per-size geometry ───────────────────────────────────────────────────── */
.thallo-block-stepper--size-xs { --step-marker: 1.5rem; --step-num: 0.7rem;  --step-type: 0.75rem; --step-gap: 0.375rem; }
.thallo-block-stepper--size-sm { --step-marker: 2rem;   --step-num: 0.8rem;  --step-type: 0.8rem;  --step-gap: 0.5rem; }
.thallo-block-stepper--size-md { --step-marker: 2.5rem; --step-num: 1rem;    --step-type: 0.9rem;  --step-gap: 0.625rem; }
.thallo-block-stepper--size-lg { --step-marker: 3rem;   --step-num: 1.15rem; --step-type: 1rem;    --step-gap: 0.75rem; }
.thallo-block-stepper--size-xl { --step-marker: 3.5rem; --step-num: 1.3rem;  --step-type: 1.1rem;  --step-gap: 0.875rem; }

/* ── Heading ─────────────────────────────────────────────────────────────── */
.thallo-block-stepper__title {
  font-size: 1.25rem; font-weight: 600; color: var(--ink);
  margin: 0 0 var(--space-4);
}

/* ── List ────────────────────────────────────────────────────────────────── */
.thallo-block-stepper__list {
  display: flex; list-style: none; margin: 0; padding: 0;
}

/* ── Marker (filled numbered circle) ─────────────────────────────────────── */
.thallo-block-stepper__marker {
  flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  width: var(--step-marker); height: var(--step-marker);
  border-radius: 999px;
  background: var(--step-accent); color: var(--step-accent-ink);
  font-size: var(--step-num); font-weight: 600; line-height: 1;
}

/* ── Body (title + description) ──────────────────────────────────────────── */
.thallo-block-stepper__body { min-width: 0; }
.thallo-block-stepper__step-title {
  margin: 0; font-size: var(--step-type); font-weight: 500; color: var(--ink);
  line-height: 1.3;
}
.thallo-block-stepper__description {
  margin: 0.15em 0 0; font-size: var(--step-type); color: var(--muted);
  line-height: 1.4; overflow-wrap: break-word;
}

/* ── Connector (subtle rule between adjacent markers) ────────────────────── */
.thallo-block-stepper__connector {
  position: absolute; background: var(--line); border-radius: 999px;
}

/* ═══ Horizontal ══════════════════════════════════════════════════════════ */
.thallo-block-stepper--orientation-horizontal .thallo-block-stepper__list {
  flex-direction: row; align-items: flex-start; gap: var(--space-2);
}
.thallo-block-stepper--orientation-horizontal .thallo-block-stepper__item {
  position: relative; flex: 1 1 0; min-width: 0;
  display: flex; flex-direction: column; align-items: center; text-align: center;
  gap: var(--step-gap);
}
/* horizontal connector: a bar at the marker's vertical mid-line, spanning from
   this marker's trailing edge to the next marker's leading edge (items are
   equal-width, markers centred, so the next centre sits one item-width over). */
.thallo-block-stepper--orientation-horizontal .thallo-block-stepper__connector {
  top: calc(var(--step-marker) / 2);
  height: var(--step-conn);
  transform: translateY(-50%);
  inset-inline-start: calc(50% + var(--step-marker) / 2 + var(--step-conn-inset));
  inset-inline-end: calc(-50% + var(--step-marker) / 2 + var(--step-conn-inset));
}

/* ═══ Vertical ════════════════════════════════════════════════════════════ */
.thallo-block-stepper--orientation-vertical .thallo-block-stepper__list {
  flex-direction: column; gap: var(--step-row-gap);
}
.thallo-block-stepper--orientation-vertical .thallo-block-stepper__item {
  position: relative;
  display: flex; flex-direction: row; align-items: flex-start; text-align: start;
  gap: var(--step-gap);
}
.thallo-block-stepper--orientation-vertical .thallo-block-stepper__body {
  padding-top: calc((var(--step-marker) - 1em) / 2);  /* optically centre the title against the marker */
}
/* vertical connector: a line down the marker's horizontal centre, from just
   below this marker to the top of the next marker (bridging the row gap). */
.thallo-block-stepper--orientation-vertical .thallo-block-stepper__connector {
  inset-inline-start: calc(var(--step-marker) / 2);
  width: var(--step-conn);
  transform: translateX(-50%);
  top: calc(var(--step-marker) + var(--step-conn-inset));
  bottom: calc(-1 * var(--step-row-gap) + var(--step-conn-inset));
}

/* ── Reduced motion ──────────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .thallo-block-stepper * { transition: none; }
}

/* docs.css */
/* docs.css — a documentation section (entry/docs.twig, listing/docs.twig).

   One column on a narrow screen: the page, then the sidebar, with a link at the top that jumps
   to it. From 64rem the sidebar stands beside the page; from 80rem "On this page" joins them.
   Both side columns stick under the site header and scroll on their own, so a long sidebar
   never makes a short page long. No script anywhere.

   .prose is the rendered Markdown. It styles ELEMENTS, because that is all generated Markdown
   is — and nothing here targets a block, so none of it meets the managed settings. */

.docs {
  --docs-top: 5rem; /* clear of the sticky site header */
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-5);
  max-width: 90rem;
  margin-inline: auto;
  padding-inline: var(--space-4);
}
.docs__jump {
  justify-self: start;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--accent);
  text-decoration: none;
}
.docs__jump::after { content: " ↓"; }
.docs__page { min-width: 0; }

@media (min-width: 64rem) {
  .docs {
    grid-template-columns: 16rem minmax(0, 1fr);
    grid-template-areas: "nav page";
    gap: var(--space-6);
    align-items: start;
  }
  .docs__jump { display: none; }
  .docs__sidebar { grid-area: nav; }
  .docs__page { grid-area: page; max-width: var(--content); }
  .docs__sidebar,
  .docs__toc {
    position: sticky;
    top: var(--docs-top);
    /* Sized from where the panel STARTS, not from where it will stick: main's top padding sits
       above it until the page has scrolled past, and a box taller than the room left runs under
       the fold — its last rows unreachable, so its own scrolling looks broken until the whole
       page is scrolled to the bottom. */
    max-height: calc(100vh - var(--docs-top) - var(--space-5) - var(--space-4));
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-width: thin;
  }
  /* A signed-in editor also gets the preview banner above the header, which pushes the panels
     down again until it scrolls away. */
  body:has(.preview-banner) :where(.docs__sidebar, .docs__toc) {
    max-height: calc(100vh - var(--docs-top) - var(--space-6) - var(--space-5) - var(--space-4));
  }
}
.docs__toc { display: none; }
@media (min-width: 80rem) {
  .docs--with-toc {
    grid-template-columns: 16rem minmax(0, 1fr) 14rem;
    grid-template-areas: "nav page toc";
  }
  .docs--with-toc .docs__toc { display: block; grid-area: toc; }
}

/* ── The page ─────────────────────────────────────────────────────────────── */
.docs__header { margin-bottom: var(--space-5); }
.docs__eyebrow {
  margin: 0 0 var(--space-2);
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--accent);
}
.docs__title { margin: 0; font-size: clamp(2rem, 1.6rem + 1.6vw, 2.75rem); }
.docs__summary { margin: var(--space-3) 0 0; font-size: 1.15rem; color: var(--muted); }

.docs__footer {
  margin-top: var(--space-6);
  padding-top: var(--space-4);
  border-top: 1px solid var(--line);
}
.docs__edit { font-size: 0.9rem; color: var(--muted); }
.docs__edit:hover { color: var(--accent); }
.docs__pager {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-3);
  margin-top: var(--space-4);
}
.docs__pager-link {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  text-decoration: none;
  color: var(--ink);
  transition: border-color 0.15s ease;
}
.docs__pager-link:hover { border-color: var(--accent); }
.docs__pager-link--next { grid-column: 2; text-align: end; }
.docs__pager-label { font-size: 0.8rem; color: var(--muted); }
.docs__pager-title { font-weight: 600; }

/* ── The sidebar ──────────────────────────────────────────────────────────── */
.docs__sidebar { scroll-margin-top: var(--docs-top); }
.docs__group + .docs__group { margin-top: var(--space-4); }
.docs__group-title {
  margin: 0 0 var(--space-2);
  font-family: var(--font-body);
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink);
}
.docs__list,
.docs__toc-list { list-style: none; margin: 0; padding: 0; }
.docs__list { border-inline-start: 1px solid var(--line); }
.docs__link {
  display: block;
  margin-inline-start: -1px;
  padding: 0.3rem var(--space-3);
  border-inline-start: 1px solid transparent;
  font-size: 0.95rem;
  color: var(--muted);
  text-decoration: none;
}
.docs__link:hover { color: var(--ink); border-inline-start-color: var(--muted); }
.docs__link[aria-current="page"] {
  color: var(--accent);
  font-weight: 600;
  border-inline-start-color: var(--accent);
}

/* ── On this page ─────────────────────────────────────────────────────────── */
.docs__toc-title {
  margin: 0 0 var(--space-2);
  font-family: var(--font-body);
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.docs__toc-item a {
  display: block;
  padding-block: 0.25rem;
  font-size: 0.875rem;
  color: var(--muted);
  text-decoration: none;
}
.docs__toc-item a:hover { color: var(--accent); }
.docs__toc-item--3 a { padding-inline-start: var(--space-3); }

/* ── The index ────────────────────────────────────────────────────────────── */
.docs-index {
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--space-4);
}
.docs-index__title { margin: 0 0 var(--space-5); }
.docs-index__group + .docs-index__group { margin-top: var(--space-5); }
.docs-index__group-title { margin: 0 0 var(--space-3); font-size: 1.35rem; }
.docs-index__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr));
  gap: var(--space-3);
}
.docs-index__link {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  height: 100%;
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  text-decoration: none;
  color: var(--ink);
  transition: border-color 0.15s ease;
}
.docs-index__link:hover { border-color: var(--accent); }
.docs-index__item-title { font-weight: 600; }
.docs-index__summary { font-size: 0.9rem; color: var(--muted); }
.docs-index__empty { color: var(--muted); }

/* ── Rendered Markdown ────────────────────────────────────────────────────── */
.prose { line-height: 1.7; overflow-wrap: break-word; }
.prose > :first-child { margin-top: 0; }
.prose > :last-child { margin-bottom: 0; }
.prose :is(h2, h3, h4) { position: relative; scroll-margin-top: var(--docs-top, 5rem); }
.prose h2 { margin: var(--space-5) 0 var(--space-3); font-size: 1.6rem; }
.prose h3 { margin: var(--space-4) 0 var(--space-2); font-size: 1.25rem; }
.prose h4 { margin: var(--space-4) 0 var(--space-2); font-size: 1.05rem; }
.prose :is(p, ul, ol, blockquote, table, hr) { margin-block: 0 var(--space-3); }
.prose :is(ul, ol) { padding-inline-start: 1.4rem; }
.prose li + li { margin-top: 0.3rem; }
.prose li > :is(ul, ol) { margin-block: 0.3rem 0; }
.prose a:not(.heading-anchor) { color: var(--accent); text-underline-offset: 0.18em; }
.prose strong { font-weight: 650; }
.prose hr { border: 0; border-top: 1px solid var(--line); margin-block: var(--space-5); }
.prose img { max-width: 100%; height: auto; border-radius: var(--radius); }
.prose blockquote {
  margin-inline: 0;
  padding: var(--space-2) var(--space-4);
  border-inline-start: 3px solid var(--accent);
  background: var(--surface);
  border-radius: 0 var(--radius) var(--radius) 0;
  color: var(--ink);
}
.prose blockquote > :last-child { margin-bottom: 0; }
/* Inline code only: a listing is the theme's code block, which styles itself. */
.prose :not(pre) > code {
  padding: 0.12em 0.4em;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--surface);
  font-size: 0.875em;
}
/* A wide table scrolls inside itself; the page never scrolls sideways. */
.prose table {
  display: block;
  max-width: 100%;
  overflow-x: auto;
  border-collapse: collapse;
  font-size: 0.95rem;
}
.prose :is(th, td) {
  padding: 0.55rem 0.85rem;
  border: 1px solid var(--line);
  text-align: start;
  vertical-align: top;
}
.prose th { background: var(--surface); font-weight: 650; white-space: nowrap; }
.prose li:has(> input[type="checkbox"]) { list-style: none; margin-inline-start: -1.4rem; }
.prose input[type="checkbox"] { margin-inline-end: 0.4rem; accent-color: var(--accent); }
/* The heading's own link: there for a reader who hovers or tabs to it, out of the way otherwise. */
.prose .heading-anchor {
  margin-inline-start: 0.4rem;
  color: var(--muted);
  text-decoration: none;
  opacity: 0;
  transition: opacity 0.15s ease;
}
.prose :is(h2, h3, h4):hover .heading-anchor,
.prose .heading-anchor:focus-visible { opacity: 1; }
/* A code listing fills the prose column rather than centring in a column of its own. */
.prose .thallo-block-code { max-width: none; margin-block: 0 var(--space-3); padding-inline: 0; }

/* ── Search (block-docs-search.js shows the form; without the script there is none) ───── */
.docs-search { position: relative; margin-bottom: var(--space-4); }
.docs-index .docs-search { max-width: 32rem; }
.docs-search__label {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
.docs-search__input {
  width: 100%;
  padding: 0.55rem 2.2rem 0.55rem 0.85rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--bg);
  color: var(--ink);
  font: inherit;
  font-size: 0.95rem;
}
.docs-search__input:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.docs-search__key {
  position: absolute;
  inset-inline-end: 0.6rem;
  top: 0.55rem;
  padding: 0 0.4rem;
  border: 1px solid var(--line);
  border-radius: 6px;
  font-size: 0.75rem;
  color: var(--muted);
  pointer-events: none;
}
.docs-search__input:focus ~ .docs-search__key { display: none; }
.docs-search__results,
.docs-search__status {
  position: absolute;
  z-index: 20;
  inset-inline: 0;
  top: calc(100% + 0.35rem);
  margin: 0;
  padding: 0.35rem;
  list-style: none;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--bg);
  box-shadow: var(--shadow-lg);
}
.docs-search__results { min-width: min(24rem, 90vw); max-height: 24rem; overflow-y: auto; }
.docs-search__status { padding: 0.7rem 0.85rem; font-size: 0.9rem; color: var(--muted); }
.docs-search__hit {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  padding: 0.5rem 0.65rem;
  border-radius: calc(var(--radius) - 4px);
  text-decoration: none;
  color: var(--ink);
}
.docs-search__results [aria-selected="true"] .docs-search__hit,
.docs-search__hit:hover { background: var(--surface); }
.docs-search__title { font-weight: 600; font-size: 0.95rem; }
.docs-search__snippet { font-size: 0.82rem; color: var(--muted); overflow-wrap: anywhere; }
.docs-search__snippet mark { background: color-mix(in srgb, var(--accent) 22%, transparent); color: inherit; border-radius: 3px; }
}
