/**
 * VidraSec theme for reveal.js, based on the "white" theme.
 * Fonts are static instances of the vidrasec-theme submodule's variable fonts,
 * in static/fonts (see the @font-face comment below).
 * Colors and typography follow themes/vidrasec-theme/design.html (the brand reference).
 *
 * Light is the default look; the DARK VARIANT block below re-points the same
 * custom properties for a near-black projector-friendly look, activated via
 * `[data-theme-version="dark"]` on <html> (baked from front matter
 * `themeVersion`, overridable at runtime with the `?theme-version=` URL query
 * param and the on-slide toggle link — see layouts/_default/single.html).
 */

/* Static (single-weight) instances of the vidrasec-theme variable fonts, cut with
   fontTools' instancer (Inter pinned at opsz=32, which is what the variable font
   auto-selected anyway at the 32px base font size). Why not the variable fonts
   directly: Chromium's PDF backend can't embed a variable font as a real font, so
   every glyph became a Type 3 drawing, about 1 MB of a 3 MB export. Static faces
   embed as subset TrueType instead. Declare one face per weight actually used, so
   the browser picks a real SemiBold/Bold instead of synthesizing bold. */
@font-face {
  font-family: 'Inter';
  src: url('/presentations/fonts/Inter-400.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
}

@font-face {
  font-family: 'Inter';
  src: url('/presentations/fonts/Inter-500.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
}

@font-face {
  font-family: 'Inter';
  src: url('/presentations/fonts/Inter-600.woff2') format('woff2');
  font-weight: 600;
  font-style: normal;
}

@font-face {
  font-family: 'Inter';
  src: url('/presentations/fonts/Inter-700.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
}

@font-face {
  font-family: 'Inter';
  src: url('/presentations/fonts/Inter-Italic-400.woff2') format('woff2');
  font-weight: 400;
  font-style: italic;
}

@font-face {
  font-family: 'Inter';
  src: url('/presentations/fonts/Inter-Italic-600.woff2') format('woff2');
  font-weight: 600;
  font-style: italic;
}

@font-face {
  font-family: 'Inter';
  src: url('/presentations/fonts/Inter-Italic-700.woff2') format('woff2');
  font-weight: 700;
  font-style: italic;
}

/* Exception: the corner footer's size floats between 13 and 22px with the
   viewport, and a single static cut can't match Inter's automatic optical size
   across that whole range. It keeps the original variable font; being ~10 glyphs,
   its Type 3 cost in the PDF is negligible. */
@font-face {
  font-family: 'Inter Variable';
  src: url('/presentations/fonts/Inter.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
}

@font-face {
  font-family: 'SourceCodePro';
  src: url('/presentations/fonts/SourceCodePro-400.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
}

@font-face {
  font-family: 'SourceCodePro';
  src: url('/presentations/fonts/SourceCodePro-700.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
}

@font-face {
  font-family: 'SourceCodePro';
  src: url('/presentations/fonts/SourceCodePro-Italic-400.woff2') format('woff2');
  font-weight: 400;
  font-style: italic;
}

section.has-dark-background, section.has-dark-background h1, section.has-dark-background h2, section.has-dark-background h3, section.has-dark-background h4, section.has-dark-background h5, section.has-dark-background h6 {
  color: #fff;
}

/* Preserve gradient/background colors when exporting to PDF */
* {
  -webkit-print-color-adjust: exact;
  print-color-adjust: exact;
}

/*********************************************
 * GLOBAL STYLES
 *********************************************/
:root {
  --r-background-color: #fff;
  --r-main-font: Inter, Courier, sans-serif;
  --r-main-font-size: 32px;
  --r-main-color: #333;
  --r-block-margin: 20px;
  --r-heading-margin: 0 0 20px 0;
  --r-heading-font: Inter, Courier, sans-serif;
  --r-heading-color: #333;
  --r-heading-line-height: 1.2;
  --r-heading-letter-spacing: normal;
  --r-heading-text-shadow: none;
  --r-heading-font-weight: 700;
  --r-heading1-text-shadow: none;
  /* Content-slide title size. Big display type is reserved for the cover
     and for `divider` slides (see SLIDE VARIANTS below) — a bullet slide's
     title is an anchor, not the message. */
  --r-heading1-size: 1.6em;
  --r-heading2-size: 1.3em;
  --r-heading3-size: 1.15em;
  --r-heading4-size: 1em;
  --r-code-font: SourceCodePro, Courier, monospace;
  --r-link-color: #1a56a0;
  --r-link-color-dark: #123f78;
  --r-link-color-hover: #2f6fc4;
  --r-selection-background-color: rgb(95.25, 152.25, 229.5);
  --r-selection-color: #fff;
  --r-overlay-element-bg-color: 0, 0, 0;
  --r-overlay-element-fg-color: 240, 240, 240;

  /* VidraSec brand palette — see themes/vidrasec-theme/design.html.
     --vidrasec-critical/high/medium/low/info and --vidrasec-gradient come
     from the theme's severity-colors.css (linked in single.html before this
     file), the shared source of truth also used by vidrasec-business-cards
     and vidrasec-report-template. */
  --vidrasec-resolved: #A8E6CF;
  --vidrasec-ink: #333;
  --vidrasec-muted: #555;
  --vidrasec-surface: #F4F4F4;
  --vidrasec-border: #CCC;
}

/*********************************************
 * DARK VARIANT
 * Same structural rules as the light styles above (everything is driven off
 * the custom properties in :root), so this block only re-points those
 * variables plus the handful of assets that aren't variable-driven (the
 * brand logo mark is solid-black artwork; on a dark background it's drawn
 * through a CSS mask and tinted with --r-link-color instead of inverting
 * straight to white, so it reads as an accent color already used elsewhere
 * on the dark theme rather than a stark white blob). Meant for projector use: a white slide
 * background projects as glare in a dark room, while a black background
 * reads much better (projector lamp bleed already lightens true black, so
 * there's no need to hedge with an off-black like most on-screen dark
 * themes do).
 *********************************************/
:root[data-theme-version="dark"] {
  --r-background-color: #000;
  --r-main-color: #e8e8e8;
  --r-heading-color: #f5f5f5;
  --r-link-color: #6fd0ff;
  --r-link-color-dark: #2f9fd6;
  --r-link-color-hover: #a6e6ff;
  --r-selection-background-color: rgb(47, 111, 173);
  --r-selection-color: #fff;
  --r-overlay-element-bg-color: 240, 240, 240;
  --r-overlay-element-fg-color: 0, 0, 0;

  /* Severity palette (--vidrasec-critical/high/medium/low/info/resolved)
     stays identical — those pastels already read fine on black. Only the
     document/UI colors need a dark counterpart. */
  --vidrasec-ink: #e8e8e8;
  --vidrasec-muted: #9a9a9a;
  --vidrasec-surface: #1c1c1c;
  --vidrasec-border: #3a3a3a;

  /* Classification badge colors: the badge component itself (pill shape,
     per-level colors) is owned by vidrasec-theme and shared across repos
     (see themes/vidrasec-theme/assets/css/classification-badge.css and its
     classification-badge-dark.css). These RGB triples are copied from that
     dark variant rather than loading the file itself — its `:root` scoping
     is meant for consumers that swap the whole stylesheet in/out, not this
     repo's single-stylesheet runtime toggle, and an attribute-scoped
     override here beats classification-badge.css's own `:root` light
     values on specificity without touching a file shared by other repos. */
  --classification-restricted-rgb: 232, 86, 74;
  --classification-confidential-rgb: 226, 149, 74;
  --classification-internal-rgb: 111, 196, 238;
  --classification-public-rgb: 111, 217, 168;
}

[data-theme-version="dark"] .reveal .slides section.cover::before,
[data-theme-version="dark"] .reveal .vidrasec-corner-brand-icon {
  background-image: none;
  background-color: var(--r-link-color);
}

/*********************************************
 * BRAND CHROME
 * Persistent brand elements, siblings of .slides inside .reveal. Positioned
 * `fixed` (not `absolute`) so they repeat on every page of a PDF export too:
 * reveal.js's print view (js/controllers/printview.js) makes `.reveal` grow
 * to the height of the whole multi-page document, so an `absolute` overlay
 * only appears once for the whole doc, while genuine `fixed` positioning is
 * honored per-printed-page by Chromium — the same trick the report theme
 * uses for its running header/footer (see vidrasec-report-theme main.css).
 *********************************************/
.reveal .vidrasec-brand-bar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 6px;
  background: var(--vidrasec-gradient);
  z-index: 20;
}

.reveal .vidrasec-corner-brand {
  position: fixed;
  bottom: 10px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 0.4em;
  opacity: 0.65;
  z-index: 20;
  pointer-events: none;
  /* Fixed positioning also means the footer sits outside reveal's scaled
     slide canvas, so a px size would render the same 13px whether in a small
     browser window or fullscreen on a 4K wall — scale with the viewport
     instead (~13px windowed, ~19px fullscreen at 1080p) so the footer keeps
     a constant visual weight relative to the slide content. */
  font-size: clamp(13px, 1vw, 22px);
}

.reveal .vidrasec-corner-brand-icon {
  display: inline-block;
  height: 1.25em;
  width: 1.25em;
  margin: 0;
  background: var(--vidrasec-corner-logo) center / contain no-repeat;
  -webkit-mask: var(--vidrasec-corner-logo) center / contain no-repeat;
  mask: var(--vidrasec-corner-logo) center / contain no-repeat;
}

.reveal .vidrasec-corner-brand a {
  font-family: 'Inter Variable', var(--r-main-font);
  font-size: 1em;
  color: var(--vidrasec-muted);
  letter-spacing: 0.02em;
  text-decoration: none;
  pointer-events: auto;
}

/* Light/dark switcher: a small round icon button (top-right, clear of the
   brand bar and corner brand) that reloads the page with `?theme-version=`
   flipped to the other value — see layouts/_default/single.html for the
   href/title logic. Both icons are always in the DOM; only one is ever
   visible, chosen by the [data-theme-version] attribute below rather than by
   JS, so the right icon is there on first paint. Hidden from PDF export
   since it's a live-viewing control with nothing to do on a printed page.

   Hidden (opacity 0) until single.html's script adds
   .vidrasec-theme-toggle-shown on mouse movement — a permanent on-screen
   button would be a distraction on every slide, not just the one the
   presenter glances at right before going on stage. :focus-visible bypasses
   that for keyboard users, who don't have a mouse to move.

   Deliberately NOT paired with `pointer-events: none` while hidden: that
   would make the button unclickable for any input that activates a point
   without a preceding hover/move event first (a touchscreen tap, a stylus,
   Playwright-style automation that hit-tests before moving the pointer) —
   there's no "reveal" event those ever fire, so the button would never
   become clickable for them at all. Left clickable-but-invisible in that
   small top-right corner instead; the tiny risk of an accidental click on
   an unseen pixel there is worth trading for the control always working. */
.reveal .vidrasec-theme-toggle {
  position: fixed;
  top: 14px;
  right: 20px;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: center;
  width: clamp(28px, 2.2vw, 38px);
  height: clamp(28px, 2.2vw, 38px);
  border-radius: 50%;
  background: var(--vidrasec-surface);
  border: 1px solid var(--vidrasec-border);
  color: var(--vidrasec-muted);
  text-decoration: none;
  opacity: 0;
  transition: opacity 0.25s ease, color 0.15s ease, border-color 0.15s ease;
}

.reveal .vidrasec-theme-toggle.vidrasec-theme-toggle-shown,
.reveal .vidrasec-theme-toggle:focus-visible {
  opacity: 0.85;
}

.reveal .vidrasec-theme-toggle svg {
  width: 55%;
  height: 55%;
}

.reveal .vidrasec-theme-toggle-sun {
  display: none;
}

[data-theme-version="dark"] .reveal .vidrasec-theme-toggle-sun {
  display: block;
}

[data-theme-version="dark"] .reveal .vidrasec-theme-toggle-moon {
  display: none;
}

.reveal .vidrasec-theme-toggle:hover {
  opacity: 1;
  color: var(--r-link-color);
  border-color: var(--r-link-color);
}

@media print {
  .vidrasec-theme-toggle {
    display: none !important;
  }
}

/*********************************************
 * SLIDE LAYOUT
 * Content slides are top-aligned and left-aligned: the title sits at a
 * fixed position on every slide (and doesn't jump when fragments appear),
 * content flows below it, and the padding reserves safe areas for the
 * brand bar (top) and the corner brand (bottom) so content can never
 * collide with the chrome.
 *
 * Three selectors share each rule:
 *  - `.slides > section:not(.stack)`: top-level slides in the live view.
 *    Vertical-stack *parents* are excluded — they're pure containers whose
 *    children reveal.js positions itself.
 *  - `.slides > section.stack > section`: the vertical slides inside a stack.
 *  - `html.reveal-print ... > .pdf-page > section`: the same slides after
 *    reveal's print pass (js/controllers/printview.js) wraps each one in a
 *    `.pdf-page` div. The `html.reveal-print` prefix keeps the selector's
 *    specificity above reveal's own compiled `html.reveal-print .reveal
 *    .slides section` print rule (dist/reveal.css), which also sets
 *    `display`/`position` with `!important` — otherwise-identical
 *    `!important` rules are decided by specificity.
 *
 * The `!important` on `display` is needed because reveal.js sets an inline
 * `display` style per-slide via JS (js/controllers/slidecontent.js).
 *********************************************/
.reveal .slides > section:not(.stack),
.reveal .slides > section.stack > section,
html.reveal-print .reveal .slides > .pdf-page > section {
  display: flex !important;
  flex-direction: column;
  justify-content: flex-start;
  box-sizing: border-box;
  padding: 48px 64px 58px !important;
  text-align: left;
}

.reveal .slides > section:not(.stack),
.reveal .slides > section.stack > section {
  height: 100% !important;
}

/* In print, each section is absolutely positioned with only an inline
   `top`/`left`/`width` (no `height`), so a percentage `height` has nothing
   to resolve against and the box collapses to its content's natural size —
   stretching from the existing inline `top` down to the page bottom
   (`bottom: 0`) sidesteps that instead. */
html.reveal-print .reveal .slides > .pdf-page > section {
  bottom: 0 !important;
}

/* printview.js skips vertical-stack parents when wrapping slides into
   `.pdf-page` elements (their children each get their own page), leaving
   the now-empty stack shell behind in `.slides` — where it would otherwise
   produce a blank printed page and, being the first `section` child, break
   any structural pseudo-class selectors. Hide it. */
html.reveal-print .reveal .slides > section.stack {
  display: none !important;
}

/*********************************************
 * SLIDE VARIANTS: cover & divider
 * Opt-in via reveal's Markdown slide attributes:
 *   <!-- .slide: class="cover" -->    deck title slide (logo + big title)
 *   <!-- .slide: class="divider" --> section break / statement slide
 * A class travels with its <section> into the print DOM, so — unlike the
 * `:first-child`/`:first-of-type` chains this replaces — these selectors
 * work identically live and in PDF export (where leftover stack shells
 * would otherwise shift the structural positions, see above).
 *
 * The `> section.stack > section` variants matter for a cover/divider slide
 * that's a *vertical* slide (nested under a top-level one via `--`): there,
 * the plain descendant selector above ties in specificity with the SLIDE
 * LAYOUT base rule's `.slides > section.stack > section` (same class count,
 * fewer elements), so the base rule's left/top alignment silently won —
 * live only, since printview.js flattens stacks away before PDF export, so
 * the PDF never hit this tie and rendered centered as intended.
 *********************************************/
.reveal .slides section.cover,
.reveal .slides section.divider,
.reveal .slides > section.stack > section.cover,
.reveal .slides > section.stack > section.divider,
html.reveal-print .reveal .slides > .pdf-page > section.cover,
html.reveal-print .reveal .slides > .pdf-page > section.divider {
  justify-content: center;
  align-items: center;
  text-align: center;
}

.reveal .slides section.cover h1 {
  font-size: 2.4em;
}

.reveal .slides section.divider h1 {
  font-size: 2em;
}

/* Cover slide gets the brand mark above the title... */
.reveal .slides section.cover::before {
  content: "";
  display: block;
  width: 84px;
  height: 84px;
  margin-bottom: 0.6em;
  background: url("/presentations/vidrasec-logo.png") center / contain no-repeat;
  -webkit-mask: url("/presentations/vidrasec-logo.png") center / contain no-repeat;
  mask: url("/presentations/vidrasec-logo.png") center / contain no-repeat;
  opacity: 0.9;
  flex-shrink: 0;
}

/* ...and a muted subtitle (design.html: secondary text = Muted #555). */
.reveal .slides section.cover p {
  color: var(--vidrasec-muted);
}

/*********************************************
 * DATA CLASSIFICATION BADGE — placement + size
 * The badge's own look (pill shape, per-level colors) is a shared component
 * owned by vidrasec-theme (see assets/css/classification-badge.css, pulled
 * in by layouts/_default/single.html) so it stays identical to the
 * equivalent badge on vidrasec-report-template's cover page. Its dark-theme
 * colors are re-pointed locally instead, by this file's DARK VARIANT block
 * above (see the comment there for why). What's
 * genuinely host-specific stays here instead: *where* the badge sits (cover
 * slide only, not repeated on every slide — see
 * layouts/partials/reveal-chapter.html — with breathing room below the
 * cover subtitle it typically follows) and its font-size, since that's
 * relative to this host's ambient font-size (a reveal.js cover slide's is
 * huge/title-sized) rather than a report's normal document body text — see
 * the theme's classification-badge.css for why it deliberately leaves
 * font-size unset.
 *********************************************/
.reveal .slides .classification-badge {
  margin-top: 0.7em;
  font-size: 0.35em;
}

/*********************************************
 * SLIDE-TITLE ACCENT
 * Every slide title gets a short brand rule underneath (design.html:
 * "Brand bar · cover rule" = Non Photo Blue). Left-aligned like the
 * title on content slides, centered on cover/divider slides.
 *********************************************/
.reveal .slides section > h1:first-child::after {
  content: "";
  display: block;
  width: 70px;
  height: 4px;
  margin-top: 0.35em;
  background: var(--vidrasec-info);
  border-radius: 2px;
}

.reveal .slides section.cover > h1:first-child::after,
.reveal .slides section.divider > h1:first-child::after {
  width: 100px;
  height: 5px;
  margin-left: auto;
  margin-right: auto;
}

.reveal-viewport {
  background: #fff;
  background-color: var(--r-background-color);
}

.reveal {
  font-family: var(--r-main-font);
  font-size: var(--r-main-font-size);
  font-weight: normal;
  color: var(--r-main-color);
}

.reveal ::selection {
  color: var(--r-selection-color);
  background: var(--r-selection-background-color);
  text-shadow: none;
}

.reveal ::-moz-selection {
  color: var(--r-selection-color);
  background: var(--r-selection-background-color);
  text-shadow: none;
}

.reveal .slides section,
.reveal .slides section > section {
  line-height: 1.4;
  font-weight: inherit;
}

/*********************************************
 * HEADERS
 *********************************************/
.reveal h1,
.reveal h2,
.reveal h3,
.reveal h4,
.reveal h5,
.reveal h6 {
  margin: var(--r-heading-margin);
  color: var(--r-heading-color);
  font-family: var(--r-heading-font);
  font-weight: var(--r-heading-font-weight);
  line-height: var(--r-heading-line-height);
  letter-spacing: var(--r-heading-letter-spacing);
  text-transform: var(--r-heading-text-transform);
  text-shadow: var(--r-heading-text-shadow);
  word-wrap: break-word;
}

.reveal h1 {
  font-size: var(--r-heading1-size);
}

.reveal h2 {
  font-size: var(--r-heading2-size);
}

.reveal h3 {
  font-size: var(--r-heading3-size);
}

.reveal h4 {
  font-size: var(--r-heading4-size);
}

.reveal h1 {
  text-shadow: var(--r-heading1-text-shadow);
}

/*********************************************
 * OTHER
 *********************************************/
.reveal p {
  margin: var(--r-block-margin) 0;
  line-height: 1.4;
}

/* Remove trailing margins after titles */
.reveal h1:last-child,
.reveal h2:last-child,
.reveal h3:last-child,
.reveal h4:last-child,
.reveal h5:last-child,
.reveal h6:last-child {
  margin-bottom: 0;
}

/* Ensure certain elements are never larger than the slide itself */
.reveal img,
.reveal video,
.reveal iframe {
  max-width: 95%;
  max-height: 95%;
}

.reveal strong,
.reveal b {
  font-weight: bold;
}

.reveal em {
  font-style: italic;
}

.reveal ol,
.reveal dl,
.reveal ul {
  display: block;
  text-align: left;
  margin: var(--r-block-margin) 0 var(--r-block-margin) 1.1em;
}

.reveal li {
  margin-bottom: 0.3em;
}

.reveal ol {
  list-style-type: decimal;
}

.reveal ul {
  list-style-type: disc;
}

/* Muted markers keep the text as the loudest element on the line
   (link blue is reserved for hyperlinks, see design.html usage map). */
.reveal ul > li::marker,
.reveal ol > li::marker {
  color: var(--vidrasec-muted);
}

.reveal ul ul {
  list-style-type: square;
}

.reveal ul ul ul {
  list-style-type: circle;
}

/* Nested items are supporting detail (venues, dates, sub-points) —
   size them like secondary text so the top level carries the slide. */
.reveal ul ul,
.reveal ul ol,
.reveal ol ol,
.reveal ol ul {
  display: block;
  margin: 0.3em 0 0.3em 1.2em;
  font-size: 0.85em;
}

.reveal dt {
  font-weight: bold;
}

.reveal dd {
  margin-left: 40px;
}

/* Matches the report theme's quote box: surface background, info-blue
   left border, muted italic text (design.html "Callout Boxes"). */
.reveal blockquote {
  display: block;
  position: relative;
  width: auto;
  margin: var(--r-block-margin) 0;
  padding: 0.4em 0.8em;
  font-style: italic;
  color: var(--vidrasec-muted);
  background: var(--vidrasec-surface);
  border-left: 4px solid var(--vidrasec-info);
  border-radius: 0 4px 4px 0;
  box-shadow: none;
}

.reveal blockquote p:first-child,
.reveal blockquote p:last-child {
  display: inline-block;
}

/* A quote standing alone on a centered divider slide shrink-wraps
   instead of stretching into a full-width bar. */
.reveal .slides section.divider blockquote {
  width: fit-content;
  max-width: 80%;
  margin-left: auto;
  margin-right: auto;
  text-align: left;
}

.reveal q {
  font-style: italic;
}

.reveal pre {
  display: block;
  position: relative;
  width: 100%;
  margin: var(--r-block-margin) 0;
  text-align: left;
  font-size: 0.55em;
  font-family: var(--r-code-font);
  line-height: 1.4;
  word-wrap: break-word;
  border: 1px solid var(--vidrasec-border);
  border-left: 4px solid var(--vidrasec-info);
  border-radius: 6px;
  overflow: hidden;
  box-shadow: none;
}

.reveal code {
  font-family: var(--r-code-font);
  text-transform: none;
  tab-size: 2;
}

.reveal pre code {
  display: block;
  padding: 10px 12px;
  overflow: auto;
  max-height: 400px;
  word-wrap: normal;
}

.reveal .code-wrapper {
  white-space: normal;
}

.reveal .code-wrapper code {
  white-space: pre;
}

.reveal table {
  margin: var(--r-block-margin) 0;
  border-collapse: collapse;
  border-spacing: 0;
}

.reveal table th {
  font-weight: bold;
}

.reveal table th,
.reveal table td {
  text-align: left;
  padding: 0.3em 0.6em;
  border-bottom: 1px solid var(--vidrasec-border);
}

.reveal table th {
  background: var(--vidrasec-surface);
}

.reveal table th[align=center],
.reveal table td[align=center] {
  text-align: center;
}

.reveal table th[align=right],
.reveal table td[align=right] {
  text-align: right;
}

.reveal table tbody tr:last-child th,
.reveal table tbody tr:last-child td {
  border-bottom: none;
}

.reveal sup {
  vertical-align: super;
  font-size: smaller;
}

.reveal sub {
  vertical-align: sub;
  font-size: smaller;
}

.reveal small {
  display: inline-block;
  font-size: 0.6em;
  line-height: 1.2em;
  vertical-align: top;
}

.reveal small * {
  vertical-align: top;
}

.reveal img {
  margin: var(--r-block-margin) 0;
}

/* A diagram that sits on its own line gets centred. Slide bodies are left-aligned
   by default (see the SLIDE VARIANTS block), so anything narrower than the slide
   otherwise hugs the left edge while its title stays pinned above it. Scoped to an
   image that is the only thing in its paragraph, so an image used inline inside a
   bullet keeps flowing with its text instead of being broken onto its own line.
   The shared about-me/contact slides pin their own `margin:0` inline, which wins
   over this rule and keeps their portrait and QR code where they are.
   Both selectors are needed: marked passes a line that starts with a raw `<img>`
   through as an HTML block without wrapping it, so a diagram authored that way is
   a top-level child of the slide body, while an image written as Markdown ends up
   inside a paragraph of its own. Either can also sit one level deeper, inside the
   `.vidrasec-autofit` wrapper the autofit plugin inserts around the whole body. */
.reveal section > img,
.reveal section > .vidrasec-autofit > img,
.reveal section > p > img:only-child,
.reveal section > .vidrasec-autofit > p > img:only-child {
  display: block;
  margin-inline: auto;
}

.reveal hr {
  display: block;
  height: 1px;
  border: 0;
  border-top: 1px solid var(--vidrasec-border);
  margin: var(--r-block-margin) 0;
}

/*********************************************
 * LINKS
 *********************************************/
.reveal a {
  color: var(--r-link-color);
  text-decoration: none;
  transition: color 0.15s ease;
}

.reveal a:hover {
  color: var(--r-link-color-hover);
  text-shadow: none;
  border: none;
}

.reveal .roll span:after {
  color: #fff;
  background: var(--r-link-color-dark);
}

/*********************************************
 * Frame helper
 *********************************************/
.reveal .r-frame {
  border: 4px solid var(--r-main-color);
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
}

.reveal a .r-frame {
  transition: all 0.15s linear;
}

.reveal a:hover .r-frame {
  border-color: var(--r-link-color);
  box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
}

/*********************************************
 * YOUTUBE PREVIEW COMPONENT
 * Markup built by static/js/vidrasec-youtube-preview.js from a one-line
 * placeholder - see that file for the authoring syntax. Styled to read as
 * unmistakably "YouTube" (brand red ring + badge, play button) rather than
 * a generic linked image, since a slide can't autoplay/embed a video and
 * needs the still to read as clickable at a glance.
 *********************************************/
.reveal a.vidrasec-youtube-preview {
  position: relative;
  display: inline-block;
  width: 420px;
  max-width: 100%;
  border-radius: 10px;
  overflow: hidden;
  box-shadow: 0 0 0 3px #ff0000;
  transition: box-shadow 0.15s ease;
}

.reveal a.vidrasec-youtube-preview:hover {
  box-shadow: 0 0 0 3px #ff0000, 0 4px 16px rgba(0, 0, 0, 0.35);
}

.reveal .vidrasec-youtube-preview__thumb {
  display: block;
  width: 100%;
  max-width: 100%;
  max-height: none;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  margin: 0;
}

.reveal .vidrasec-youtube-preview__play {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 68px;
  height: 48px;
  background: #ff0000;
  border-radius: 14px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.reveal .vidrasec-youtube-preview__play::after {
  content: "";
  border-style: solid;
  border-width: 12px 0 12px 20px;
  border-color: transparent transparent transparent #fff;
  margin-left: 4px;
}

.reveal .vidrasec-youtube-preview__badge {
  position: absolute;
  top: 10px;
  right: 10px;
  background: #ff0000;
  color: #fff;
  font-family: var(--r-main-font);
  font-weight: 700;
  font-size: 0.7em;
  line-height: 1.4;
  letter-spacing: 0.02em;
  padding: 3px 8px;
  border-radius: 4px;
}

/*********************************************
 * NAVIGATION CONTROLS
 *********************************************/
.reveal .controls {
  color: var(--r-link-color);
}

/*********************************************
 * PROGRESS BAR
 *********************************************/
.reveal .progress {
  background: rgba(0, 0, 0, 0.2);
  color: var(--r-link-color);
}

/*********************************************
 * PRINT BACKGROUND
 *********************************************/
@media print {
  .backgrounds {
    background-color: var(--r-background-color);
  }
}
