/**
 * @file
 * reveal-zaira.css — Think Insights brand theme for reveal.js decks.
 *
 * Loaded after reveal.js's own reset.css/reveal.css (structural only, no
 * color) — see the `presentation` library in zaira.libraries.yml. Unlike
 * most reveal.js themes this doesn't follow the site's light/dark toggle:
 * a presentation is a self-contained artifact (embedded on the page today,
 * possibly opened standalone, exported to PDF, or projected tomorrow), so
 * it commits to one deliberate look — dark navy with a gold accent, the
 * same "foil" pairing already established for --btn/--playbook-final-cta
 * elsewhere in the theme — rather than reacting to data-bs-theme.
 *
 * Values are read from the site's --tg-* custom properties where the deck
 * is embedded in a normal page (inherits them from style.css's :root), with
 * literal fallbacks so the deck still looks correct in an isolated context
 * (e.g. a future standalone /presentation/{id}/embed route) where those
 * tokens might not be in scope.
 *
 * Slide titles deliberately use Noto Serif directly rather than the site's
 * own --tg-heading-font-family: that token drives many non-heading UI bits
 * too (nav, tags, breadcrumbs) so it stays "Inter", while real h1-h6
 * elsewhere get Noto Serif via a dedicated rule in style.css. Slide
 * "titles" here (e.g. .section-number) aren't heading tags, so they
 * declare the serif font directly instead.
 */
@import url("https://fonts.googleapis.com/css2?family=Noto+Serif:wght@500&display=swap");

.reveal {
  --r-gold: var(--tg-primary-color, #c09a52);
  --r-gold-bright: color-mix(in srgb, var(--tg-primary-color, #c09a52) 80%, #fff 20%);
  --r-navy: var(--tg-secondary-color, #0d1b2a);
  --r-navy-deep: #0a141f;
  --r-ink: #e7ecf2;
  --r-ink-muted: rgba(231, 236, 242, 0.68);
  --r-border: rgba(192, 154, 82, 0.25);
  --r-font-heading: "Noto Serif", Georgia, serif;
  --r-font-body: var(--tg-body-font-family, "Inter", sans-serif);

  font-family: var(--r-font-body);
  font-size: 30px;
  font-weight: 400;
  color: var(--r-ink);
}

.reveal-viewport {
  background: radial-gradient(circle at 15% 10%, var(--r-navy) 0%, var(--r-navy-deep) 65%);
}

.reveal .slides section {
  text-align: left;
}
/* reveal.js's own default is 60px/20px (see dist/reveal.css, scoped
   `html:not(.print-pdf) .reveal .slides section` with !important, hence
   the !important here too) — content sat noticeably close to the stage
   edges at that margin, especially on the sides. Both measured in the
   1280×720 virtual canvas, so they scale down together with everything
   else regardless of the stage's actual on-screen size. */
.reveal .slides section {
  padding: 90px 72px !important;
}

/* ── Headings (slide titles) ─────────────────────────────────────────── */
.reveal h1,
.reveal h2,
.reveal h3,
.reveal h4,
.reveal h5,
.reveal h6 {
  font-family: var(--r-font-heading);
  font-weight: 500;
  text-transform: none;
  letter-spacing: -0.01em;
  color: var(--r-gold);
  text-shadow: none;
  margin-bottom: 0.5em;
}
.reveal h1 {
  font-size: 2.1em;
}
.reveal h2 {
  font-size: 1.5em;
}
.reveal h3 {
  font-size: 1.15em;
}

/* The divider line under a slide's header area closes out the title
   *and* subtitle together — so it sits after the subtitle when one is
   present, and directly after the title when it isn't, rather than
   always being glued to the title itself (which would land it between
   the title and subtitle). */
.reveal .slides section > h2:not(:has(+ p)) {
  border-bottom: 2px solid var(--r-border);
  padding-bottom: 0.28em;
}
.reveal .slides section > h2 + p {
  border-bottom: 2px solid var(--r-border);
  padding-bottom: 0.5em;
}

/* Title slide: a slide whose only heading is an <h1> reads as the deck's
   cover — center it instead of the left-aligned, top-anchored body
   convention above. Deliberately the deck's own first/last-slide
   bookends only, not a general-purpose "centered slide" utility — every
   other slide stays top-anchored (see the padding rule above) so
   content never jumps around depending on how much text a slide has.
   flex + !important: reveal.js's own base CSS sets display:block
   !important on every section (confirmed earlier fighting the same
   rule for slide padding), so a plain override here loses. */
.reveal .slides section:has(> h1:only-child),
.reveal .slides section.title-slide,
.reveal .slides section.zaira-logo-slide,
.reveal .slides section.zaira-section-divider,
.reveal .slides section.zaira-image-slide,
.reveal .slides section.zaira-quote,
.reveal .slides section.zaira-big-idea,
.reveal .slides section.zaira-case-study,
.reveal .slides section.zaira-recap {
  display: flex !important;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  height: 100%;
  text-align: center;
}
.reveal .slides section:has(> h1:only-child) h1,
.reveal .slides section.title-slide h1 {
  font-size: 2.6em;
}

/* Statement family — zaira-quote/zaira-big-idea/zaira-case-study/
   zaira-recap. One shared block, not four near-duplicates: all four are
   visually identical (large centered statement, no bullets/columns),
   differentiated only by an author-supplied `eyebrow:` (e.g.
   "CASE STUDY", "KEY TAKEAWAY") rather than a hardcoded per-layout
   label — see SlideDirectiveTransformer's class doc. Headings pick up
   the deck's normal h2 styling from the rule above; only the size and
   max-width are bumped here for a "billboard" statement read. */
.reveal .slides section.zaira-quote h2,
.reveal .slides section.zaira-big-idea h2,
.reveal .slides section.zaira-case-study h2,
.reveal .slides section.zaira-recap h2 {
  font-size: 1.9em;
  max-width: 900px;
  border-bottom: none;
}
/* zaira-quote alone reuses the deck's existing blockquote treatment
   (gold left border, italic, translucent gold background — see the
   .reveal blockquote rule below), scaled up to carry a whole slide by
   itself rather than sitting inline in a column of other content. An
   optional attribution line (a plain paragraph after the heading, same
   "heading + p" position the generic subtitle rule already styles)
   reads as the muted credit line beneath the quote. */
.reveal .slides section.zaira-quote h2 {
  border-left: 3px solid var(--r-gold);
  background: rgba(192, 154, 82, 0.08);
  padding: 0.5em 0.9em;
  font-style: italic;
  text-align: left;
}

/* Kicker label — eyebrow: {text}. Flat, not a pill (matches the site's
   .citation-panel__eyebrow convention, not the pill-shaped .lp-eyebrow
   one — a badge would look busy sitting alone on a slide). Always
   directly above the title, on any layout. */
.reveal .zaira-eyebrow {
  font-family: var(--r-font-body);
  font-weight: 700;
  font-size: 0.55em;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--r-gold);
  margin: 0 0 0.6em;
}

/* zaira-image-left / zaira-image-right / zaira-picture-left — a
   full-bleed image (or, for picture-left, a decorative panel needing no
   author-supplied image) filling one half of the slide, with title/
   subtitle/body content confined to the other half. Whole-slide, not a
   `::: column` split: routing these through the column system would
   either strand a title:-synthesized heading full-width above both
   halves, or (if patched to stop that) drop it inside the image column
   itself — seePresentationTransformer's plan doc. Content stays
   top-anchored like an ordinary slide (not vertically centered like the
   statement family above), since these are expected to carry real body
   content, not a one-line statement. */
.reveal .slides section.zaira-image-left,
.reveal .slides section.zaira-image-right,
.reveal .slides section.zaira-picture-left {
  display: flex !important;
  flex-direction: column;
  justify-content: center;
  height: 100%;
  text-align: left;
}
.reveal .slides section.zaira-image-left,
.reveal .slides section.zaira-picture-left {
  padding-left: calc(50% + 36px) !important;
}
.reveal .slides section.zaira-image-right {
  padding-right: calc(50% + 36px) !important;
}
/* reveal.js copies the section's class onto its own generated
   .slide-background element (same mechanism already used for
   .slide-background.zaira-image-slide below) — clip-path restricts that
   native background layer to one half of the slide instead of the
   whole thing. */
.reveal .slide-background.zaira-image-left {
  clip-path: inset(0 50% 0 0);
}
.reveal .slide-background.zaira-image-right {
  clip-path: inset(0 0 0 50%);
}
/* picture-left has no author-supplied image (no `image:` directive
   expected on this layout) — a CSS-only decorative gradient panel fills
   the same visual role a fixed template graphic would in a PPTX deck. */
.reveal .slides section.zaira-picture-left::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 50%;
  height: 100%;
  background: linear-gradient(160deg, var(--r-navy-deep) 0%, var(--r-gold) 140%);
  border-right: 1px solid var(--r-border);
}
@media (max-width: 900px) {
  .reveal .slides section.zaira-image-left,
  .reveal .slides section.zaira-image-right,
  .reveal .slides section.zaira-picture-left {
    padding-left: 72px !important;
    padding-right: 72px !important;
    padding-top: calc(40% + 36px) !important;
  }
  .reveal .slide-background.zaira-image-left,
  .reveal .slide-background.zaira-image-right {
    clip-path: inset(0 0 60% 0);
  }
  .reveal .slides section.zaira-picture-left::before {
    width: 100%;
    height: 40%;
    border-right: none;
    border-bottom: 1px solid var(--r-border);
  }
}

/* Byline directly under the title slide's subtitle. The title slide
   itself — heading, subtitle, and this byline — is synthesized by
   SlideDirectiveTransformer from the node's own title/summary/author,
   never authored in the Markdown source; `<p class="deck-author">` is
   simply the HTML that PHP class emits, since there's no Markdown syntax
   for "this paragraph is a byline". Small and letter-spaced like a
   credit line, not another body-text paragraph. */
.reveal .deck-author {
  font-size: 0.55em;
  color: var(--r-ink-muted);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin-top: 1.2em;
}

/* Closing logo slide — `<!-- .slide: class="zaira-logo-slide" -->`,
   always the same image, always the deck's last slide. Like the title
   slide above, synthesized by SlideDirectiveTransformer and appended
   automatically — never authored per-deck. Centered like the cover above
   (folded into the same rule); the image is capped well under the
   deck's full width so it reads as a sign-off mark, not a full-bleed
   banner.

   display: block is load-bearing, not decorative: the markdown plugin
   wraps a standalone image in a <p>, and an <img> is an inline element
   by default — `margin: 0 auto` only centers block-level boxes, so
   without this the image just sat at its default inline position
   (flush left within its paragraph) instead of centered, confirmed live
   by comparing the image's own center against its (correctly flex-
   centered) parent <p>'s center — the two didn't match. */
.reveal .slides section.zaira-logo-slide img {
  display: block;
  width: 340px;
  max-width: 50%;
  height: auto;
  margin: 0 auto;
}

/* Section divider — auto-detected by SlideDirectiveTransformer from a
   slide whose entire content is one `# Heading` (H1; regular in-slide
   headings are `##`/`###`, so H1 is reserved for this). The class and
   the `<p class="section-number">` (auto-numbered — also never authored)
   are both added by that same PHP step. Centered like the cover/closing
   slides (folded into the same rule above). The number takes the
   *title's* styling (gold, Noto Serif, large) precisely because it's
   meant to read as the "headline" of the divider; the section title
   deliberately uses the body font at a size between the number and
   regular body text, not the deck's heading font — it's naming what
   comes next, not itself a title. */
.reveal .slides section.zaira-section-divider .section-number {
  font-family: var(--r-font-heading);
  font-weight: 500;
  font-size: 2.6em;
  color: var(--r-gold);
  line-height: 1;
  margin: 0 0 0.2em;
}
.reveal .slides section.zaira-section-divider h1 {
  font-family: var(--r-font-body);
  font-weight: 400;
  font-size: 1.3em;
  color: var(--r-ink);
  letter-spacing: normal;
  border-bottom: none;
  margin: 0;
}

/* Full-image slide — `<!-- .slide: class="zaira-image-slide"
   data-background-image="/sites/default/files/images/presentations/
   {file}" data-background-size="cover" -->`. reveal.js's own
   data-background-image renders on a dedicated layer behind the slide
   (sized independently of this section's content box, including its
   padding — see the padding rule above), so the image is genuinely
   full-bleed regardless; this section only needs to style the *title*,
   which is optional and, unlike every other slide, floats centered
   over the photo rather than anchored top-left.

   Two legibility layers, not one — deliberately: source images for this
   slide type can be anything an author drops in (a bright illustration
   was the first one actually tried here), so a single scrim sized to
   the text isn't reliable on its own. The gradient tint below darkens
   the *whole* image a little, tying it into the deck's own dark
   palette regardless of the image's own brightness; the box behind the
   title is the second, stronger layer specifically for text contrast.
   reveal.js copies the section's class onto its own `.slide-background`
   element (confirmed live), so it's targetable directly by that class. */
.reveal .slide-background.zaira-image-slide::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(rgba(10, 20, 31, 0.25), rgba(10, 20, 31, 0.6));
  pointer-events: none;
}
.reveal .slides section.zaira-image-slide h2 {
  display: inline-block;
  color: #ffffff;
  background: rgba(10, 20, 31, 0.6);
  border-bottom: none;
  padding: 0.35em 0.9em;
  border-radius: 6px;
  margin: 0;
}

/* ── Body text ────────────────────────────────────────────────────────── */
.reveal p {
  line-height: 1.5;
  color: var(--r-ink);
  margin-bottom: 0.65em;
}
/* Subtitle: the paragraph immediately after a slide's title, on any
   slide — including multi-column ones, where presentation-layouts.js
   keeps it (like the heading itself) outside the column grid so it
   still spans the full slide width. `.subtitle` is kept as an explicit
   opt-in for a paragraph that isn't in that position but should still
   read as one. Deliberately Inter at the same size as regular body text
   (not smaller, the usual subtitle convention) — only the muted color
   and the tight spacing to the title separate it visually. */
.reveal .subtitle,
.reveal .slides section > :is(h1, h2, h3) + p {
  font-family: var(--r-font-body);
  font-size: 1em;
  color: var(--r-ink-muted);
  margin-top: -0.3em;
}

.reveal ul,
.reveal ol {
  display: block;
  margin-left: 1em;
}
.reveal li {
  line-height: 1.5;
  margin-bottom: 0.35em;
}
.reveal ul > li::marker {
  color: var(--r-gold);
}
.reveal ol > li::marker {
  color: var(--r-gold);
  font-weight: 700;
}

.reveal a {
  color: var(--r-gold-bright);
  text-decoration: underline;
  text-decoration-color: rgba(192, 154, 82, 0.4);
  text-underline-offset: 0.15em;
  transition: color 0.2s ease, text-decoration-color 0.2s ease;
}
.reveal a:hover {
  color: #ffffff;
  text-decoration-color: currentColor;
}

.reveal strong {
  color: #ffffff;
  font-weight: 700;
}

.reveal blockquote {
  border-left: 3px solid var(--r-gold);
  background: rgba(192, 154, 82, 0.08);
  padding: 0.6em 1em;
  font-style: italic;
  color: var(--r-ink-muted);
  box-shadow: none;
  width: auto;
}

.reveal code {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  background: rgba(255, 255, 255, 0.08);
  color: var(--r-gold-bright);
  border-radius: 4px;
  padding: 0.1em 0.35em;
  font-size: 0.85em;
}
.reveal pre {
  box-shadow: 0 8px 28px rgba(0, 0, 0, 0.35);
  border: 1px solid var(--r-border);
  border-radius: 8px;
  width: 100%;
}
.reveal pre code {
  background: transparent;
  color: inherit;
  padding: 0.8em 1em;
}

.reveal table {
  border-collapse: collapse;
}
.reveal table th {
  color: var(--r-gold);
  font-family: var(--r-font-heading);
  font-size: 0.75em;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  border-bottom: 2px solid var(--r-border);
  padding: 0.4em 0.7em;
}
.reveal table td {
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  padding: 0.4em 0.7em;
}

.reveal hr {
  border: none;
  border-top: 1px solid var(--r-border);
  margin: 1em 0;
}

/* ── Controls / progress / slide number ──────────────────────────────── */
/* Moved from reveal.js's default bottom-right to bottom-left, alongside
   the notes-toggle / Fullscreen buttons (see .zaira-presentation__controls
   in style.css) — the container's own anchor edge is flipped first, then
   each button's individual offset is mirrored (originally measured from
   the container's *right* edge) so the left/right reading order among
   the arrows themselves is preserved. Slide-number is left at reveal's
   own default bottom-right position — unaffected by this.
   Positioning is in flat pixels, not reveal's own em-based values —
   .zaira-presentation__controls (the PDF/fullscreen buttons) sits in a
   completely separate stacking context in style.css with its own px
   values, and mixing the two unit systems left them a few pixels off
   vertically. Both now share the same --r-controls-spacing bottom offset
   and the same 40px button height, so their centers land on one line.
   !important throughout this block: reveal.js recalculates and inlines
   its own bottom/height values for these elements based on the deck's
   current scale factor (confirmed by inspecting computed styles at a
   non-100% scale — a plain override here was silently beaten by that
   inline recalculation), so a plain assignment isn't reliable enough.
   A literal 12px, not var(--r-controls-spacing, 12px): reveal.js also
   redefines that variable itself to a scale-dependent value on `.reveal`
   — since only its own descendants inherit that override, referencing
   the variable here would silently pick up reveal's value instead of
   the 12px fallback, while .zaira-presentation__controls in style.css
   (a sibling of .reveal, so outside that inheritance chain) would still
   get 12px — the two ending up on different baselines is exactly the
   misalignment this rule exists to fix. */
.reveal .controls {
  color: var(--r-gold);
  right: auto !important;
  left: 12px !important;
  bottom: 12px !important;
  height: 40px !important;
  /* Above the speaker-notes panel below (z-index: 15), which overlaps
     this same bottom-left corner when open — same reasoning as
     .zaira-presentation__controls in style.css. */
  z-index: 20 !important;
}
.reveal .controls .navigate-left,
.reveal .controls .navigate-right,
.reveal .controls .navigate-up,
.reveal .controls .navigate-down {
  width: 40px !important;
  height: 40px !important;
  bottom: 0 !important;
}
.reveal .controls .navigate-left {
  right: auto !important;
  left: 0 !important;
}
.reveal .controls .navigate-right {
  right: auto !important;
  left: 48px !important;
}
.reveal .controls .navigate-up,
.reveal .controls .navigate-down {
  right: auto !important;
  left: 96px !important;
}

/* Material Symbols Sharp chevrons in place of reveal's default CSS-drawn
   arrow triangles (\e5cb / \e5cc — the same codepoints already used for
   the site's flippy pager arrows in style.css, for consistency). Bare
   icons only — no button background, matching reveal's own unadorned
   arrow convention; only the glyph's color shifts on hover. */
.reveal .controls .navigate-left .controls-arrow,
.reveal .controls .navigate-right .controls-arrow {
  display: none;
}
.reveal .controls .navigate-left::before,
.reveal .controls .navigate-right::before {
  font-family: "Material Symbols Sharp";
  font-size: 22px;
  display: block;
  width: 40px;
  height: 40px;
  line-height: 40px;
  text-align: center;
}
.reveal .controls .navigate-left::before {
  content: "\e5cb";
}
.reveal .controls .navigate-right::before {
  content: "\e5cc";
}
/* No hover state at all — reveal's own base CSS both transitions and
   dims/brightens these buttons on hover (`.enabled` sits at opacity:.9,
   `.enabled:hover` at 1, animated via a `transition: ... opacity .2s
   ... transform .2s` on the button itself); pinning opacity at a fixed
   1 for both states and killing the transition keeps the arrows
   visually identical whether hovered or not. */
.reveal .controls button {
  transition: none !important;
}
.reveal .controls .navigate-left.enabled,
.reveal .controls .navigate-right.enabled,
.reveal .controls .navigate-left.enabled:hover,
.reveal .controls .navigate-right.enabled:hover {
  opacity: 1 !important;
}

.reveal .progress {
  color: var(--r-gold);
  height: 4px;
}
/* Vertically centered on the same 32px-from-stage-bottom line as the
   arrow + PDF/fullscreen cluster on the opposite corner (bottom:12px +
   half of their 40px height) — 32px height here centers the same way
   (bottom:16px + half of 32px). Literal px and !important for the same
   reason as the controls cluster above: reveal.js recalculates bottom/
   right on this element at non-100% scale, beating a plain override. */
.reveal .slide-number {
  background: rgba(13, 27, 42, 0.55);
  color: var(--r-ink-muted);
  font-family: var(--r-font-body);
  font-size: 0.55em;
  border-radius: 4px;
  padding: 0 0.6em;
  display: flex !important;
  align-items: center;
  height: 32px;
  bottom: 16px !important;
  right: 12px !important;
}
/* reveal.js always wraps the number in a self-referencing <a href="#/...">
   (its own SlideNumber plugin, not ours) — strip the link styling and
   behavior so it reads as plain text. */
.reveal .slide-number a {
  color: inherit;
  text-decoration: none;
  cursor: default;
  pointer-events: none;
}
/* Cover and closing slides don't have anything to count against — see
   wireSlideNumberVisibility() in presentation-init.js, which toggles
   this class on every navigation. */
.zaira-presentation--hide-slide-number .reveal .slide-number {
  display: none !important;
}

/* ── Speaker notes ────────────────────────────────────────────────────── */
/* reveal.js core (`showNotes: true`, set in presentation-init.js) keeps
   this populated with the current slide's notes and toggles reveal's
   own `.reveal.show-notes` class automatically — but its default look
   is a light, PowerPoint-gray panel (#f5f5f5 background, #222 text) and
   its default `.show-notes` position pushes it *below* `.reveal`'s own
   box (top:100%), which would render outside — and get clipped by —
   this deck's fixed-aspect-ratio, overflow:hidden stage. Both are
   overridden here rather than used as-is: recolored to match the deck,
   and repositioned as a bottom overlay *within* the stage instead.
   Visibility is deliberately NOT tied to reveal's own `.show-notes`
   class — that only reflects whether the *current slide* has notes,
   not whether the visitor asked to see them — so this keys off our own
   toggle class (zaira-presentation--notes-visible, set in
   wireNotesToggle()) with !important, overriding reveal's class
   regardless of its state either way.

   `.reveal.show-notes` *also* triggers a completely separate reveal.js
   default: `max-width: 75%`, reveal's own space-making for a side-by-
   side notes layout (a different showNotes mode than the one used
   here). Since our `showNotes: true` is set at init time to keep notes
   content fresh regardless of whether the visitor has ever opened the
   panel, `.reveal` picked up `show-notes` — and shrank to 75% width —
   on every deck with any notes at all, whether the panel was open or
   not. Confirmed live: `.reveal`'s computed max-width was 75% even with
   the notes panel closed, on a deck whose stage had full width to give
   it. Not something a re-layout call fixes — it's a stylesheet rule
   keyed off a class that's simply always present here, not a stale
   measurement. */
.reveal.show-notes {
  max-width: 100% !important;
}

.reveal .speaker-notes {
  display: none !important;
}
.zaira-presentation--notes-visible .reveal .speaker-notes {
  display: block !important;
  position: absolute !important;
  top: auto !important;
  bottom: 0 !important;
  left: 0 !important;
  width: 100% !important;
  height: 34% !important;
  box-sizing: border-box !important;
  background: rgba(10, 20, 31, 0.97);
  color: var(--r-ink);
  border: none;
  border-top: 1px solid var(--r-border);
  font-family: var(--r-font-body);
  font-size: 16px;
  line-height: 1.5;
  padding: 16px 20px;
  z-index: 15;
}
.zaira-presentation--notes-visible .reveal .speaker-notes:before {
  content: "Speaker notes";
  color: var(--r-gold);
  font-family: var(--r-font-heading);
  font-size: 0.8em;
  opacity: 1;
  margin-bottom: 8px;
}
.zaira-presentation--notes-visible .reveal .speaker-notes .notes-placeholder {
  color: var(--r-ink-muted);
}

/* ── Mermaid diagrams ─────────────────────────────────────────────────── */
.reveal .mermaid {
  display: flex;
  justify-content: center;
  margin: 0.6em 0;
}
/* Sizing itself is handled in JS (see fitMermaidDiagrams() in
   presentation-init.js), not here: mermaid sets its own inline
   `style="max-width: {natural diagram width}px"` on the svg root (its
   own useMaxWidth behavior), and a CSS width/max-width override — even
   with !important, confirmed beating that inline style — still didn't
   stop the rightmost node's label from painting past the stage edge.
   That label sits in a <foreignObject> (real HTML layout, not SVG
   vector paths), and doesn't reliably scale down proportionally just
   because the outer <svg>'s CSS width shrinks — a browser-level quirk
   for that specific combination, not something CSS alone controls.
   transform: scale(), applied in JS after measuring the diagram's
   actual rendered size against the slide's available width, scales the
   whole rendered element uniformly — including foreignObject content —
   the way width/viewBox scaling doesn't reliably do here. */
.reveal .mermaid svg {
  height: auto;
}
/* Mermaid 11's flowchart renderer sizes each node label's <foreignObject>
   narrower than the label text actually needs (confirmed by comparing
   the foreignObject's own width attribute against its label span's
   rendered width — consistently short, clipping longer labels mid-word)
   — a rendering quirk in that specific mermaid version, not something
   its config options control. foreignObject clips overflowing content
   by default in SVG, same as overflow:hidden; forcing it to size to its
   content (and re-allowing overflow) fixes the clip without touching
   mermaid's own JS. */
.reveal .mermaid foreignObject {
  width: max-content !important;
  height: max-content !important;
  overflow: visible;
}

/* Transparent node fills — reads as line art against the deck's own
   navy background instead of a solid box sitting on top of it, letting
   the gold borders and connecting lines carry the diagram's structure.
   Applied here, after rendering, rather than via mermaid's own
   themeVariables (primaryColor etc. in presentation-init.js): mermaid
   derives several *other* theme colors from those via its own internal
   lighten/darken color math, which can't parse a non-numeric keyword
   like "transparent" as an input color — tried first, and confirmed
   live to fall back to an ugly flat dark gray instead of honoring it.
   !important: mermaid sets each shape's fill via inline style. Scoped
   to `.node` specifically (not a bare `path` selector) so the actual
   connector lines between nodes — also <path> elements, just outside
   any `.node` group — keep their gold stroke color, unaffected. */
.reveal .mermaid .node rect,
.reveal .mermaid .node polygon,
.reveal .mermaid .node circle,
.reveal .mermaid .node path {
  fill: transparent !important;
}

@media (prefers-reduced-motion: reduce) {
  .reveal .slides section {
    transition: none !important;
  }
}
