/* === REAGLE'S CSS CUSTOM PROPERTIES === */
/* Design tokens for consistent theming across components.
   Uses color-mix() for transparency to maintain design flexibility. */
:root {
    --border-color: #666;
    --callout-bg: white;
    /* Cream background at 80% opacity for readable overlays */
    --frame-bg: color-mix(in srgb, #fcfaeb 80%, transparent);
    --highlight-bg: #d3d8f7;
    --img-spacing: 25px;
    --indent-spacing: 20px;
    --list-margin: 50px;
    /* Semi-transparent shadows for depth without overwhelming visuals */
    --shadow-dark: color-mix(in srgb, black 60%, transparent);
    --shadow-gray: gray;
}

/* === BASE === */
/* Inherit background color from parent to avoid white flashes during transitions.
   Addresses reveal.js issue #668 where slides briefly show default background. */
html { background-color: inherit; }

/* === BASE TYPOGRAPHY AND SIZING === */
/* Base font size for all slide content. Reveal.js scales from this value. */
.reveal { font-size: 36px; }

/* Title slides (level1 sections) use larger text for emphasis */
section.level1 { font-size: 125%; }

/* Highlight class adds background color to draw attention to key content */
section.highlight h2,
span.highlight { background-color: var(--highlight-bg); }

/* Reset fit-text sections to default styles.
   Reveal.js's r-fit-text can interfere with custom styling,
   so we revert all properties to their initial values. */
section.r-fit-text { all: revert; }

/* Use lowercase letters (a, b, c) instead of uppercase for alphabetic lists */
ol[type="a"] { list-style-type: lower-alpha; }

/* === BLOCK QUOTES === */
/* Simple border styling for quotes with subtle background tint */
:root {
    --quote-border-color: #2a76dd;
    --quote-bg: color-mix(in srgb, var(--quote-border-color) 5%, transparent);
}

.reveal blockquote {
  position: relative;
  font-style: normal; /* Override reveal.js italic default */
  font-size: 95%;
  background: var(--quote-bg);
  padding: 0.2em 0.6em;
  border-left: 4px solid var(--quote-border-color); /* Default: left border */
  padding-left: 1em;
}

/* === CODE === */
/* Subtle green-tinted background distinguishes code from body text */
:root {
  --code-bg: color-mix(in srgb, hsl(120, 72%, 52%) 5%, transparent);
  /* Menlo on macOS, Consolas on Windows, generic monospace elsewhere. Both beat
     the theme's bare `monospace`, which resolves to Courier on macOS and reads
     far smaller than its nominal size (0.423em x-height vs Menlo's 0.547em).
     "SF Mono" used to lead this list but was never reachable --- Apple ships it
     inside Terminal.app's bundle rather than registering it, so a browser asked
     for it falls straight through to the proportional default. The 92% on inline
     code below is tuned to Menlo's x-height. */
  --r-code-font: Menlo, Consolas, monospace;
}

/* One font for every monospace context, inline and block alike. The theme also
   sets this on `.reveal pre` and `.reveal code`, but declaring it here keeps the
   two from drifting apart if the theme changes underneath us. */
.reveal pre,
.reveal :not(pre) > code {
  font-family: var(--r-code-font);
}

/* Inline code only; `:not(pre) >` keeps the size and tint off code blocks, which
   would otherwise inherit this size and stack a second tint on the block's own.
   Menlo's x-height (0.547em) runs 8% above Lato's (0.506em), so 92% is where the
   two match optically (0.503em vs 0.506em); at 95% the mono visibly rode above
   the prose. No box-shadow here on purpose: the theme's block shadow
   (0 5px 15px) is calibrated for a full-width slab, reads as a smudge under a
   one-line inline box, and would repeat on each fragment of a wrapped span.
   `overflow-wrap: anywhere` lets a spaceless token (a long URL in 064) break
   mid-word only when it would otherwise run off the slide; short code is
   untouched. */
.reveal :not(pre) > code {
  font-size: 92%;
  background: var(--code-bg);
  padding: 0.1em;
  overflow-wrap: anywhere;
}

/* Preformatted blocks span the full slide rather than the theme's 90%. At 0.6em
   the 0.602em advance yields ~75 columns of the 938px content box, which clears
   the widest line in these decks (70 columns, in 040-internet-101). The tint
   sits here rather than on the inner `code` so that a bare <pre> (010-intro)
   matches a <pre><code> block. */
.reveal pre {
  width: 100%;
  box-sizing: border-box;
  padding: 0.3em 0.5em;
  font-size: 0.6em;
  background: var(--code-bg);
}

/* The beige theme caps `pre code` at 400px and silently scrolls the overflow,
   which truncated the 20-line HTTP response in 020-markup-101. Lift the cap and
   size tall blocks per-slide instead. Padding and background already come from
   the `pre` above, so drop the theme's duplicates. */
.reveal pre code {
  max-height: none;
  background: none;
  padding: 0;
}

/* === TABLES === */
/* Center tables horizontally and add border for visual separation */
.reveal table {
    margin-left: auto;
    margin-right: auto;
    border: 1px solid var(--border-color);
}

/* Cell borders and padding create clear grid structure.
   Top alignment prevents content from jumping when cells have different heights. */
.reveal table td,
.reveal table th {
    border: 1px solid var(--border-color);
    padding: 0px 4px 0px 16px;
    vertical-align: top;
}

/* === FRAGMENT ANIMATIONS === */
/* Custom fragment behavior without reveal.js's default transform scaling.
   Addresses issue #2126 where transforms cause layout shifts.
   We control size changes purely through font-size for smoother inline growth. */

/* Grow fragments: emphasize with bold and size increase */
.reveal .slides section span.fragment.grow.visible {
    font-weight: bold;
    font-size: 130%;
    transform: none; /* Disable reveal.js transform to prevent layout jumps */
}

/* Shrink fragments: de-emphasize with lighter weight and smaller size */
.reveal .slides section span.fragment.shrink.visible {
    font-weight: lighter;
    font-size: 70%;
    transform: none; /* Disable reveal.js transform to prevent layout jumps */
}

/* Blank fragments: a cloze blank. The underline shows from the start and the
   word fades in on reveal. The text stays in the layout (transparent) so the
   sentence doesn't reflow when the word appears. */
.reveal .slides section span.fragment.blank {
    opacity: 1;
    visibility: inherit;
    color: transparent;
    border-bottom: 2px solid var(--r-main-color);
    transition: color 0.3s ease;
}

.reveal .slides section span.fragment.blank.visible {
    color: inherit;
}

/* === DEFINITION LISTS === */
/* Left-align definition lists for better readability of term-definition pairs */
.reveal dl { text-align: left; }
.reveal dd { margin-left: 2em; }

/* === LIST FORMATTING === */
/* Pandoc generates <p> tags inside <li> elements for "loose" lists.
   We display them inline to create visually "tight" lists without extra spacing. */
.reveal ul li p,
.reveal ol li p {
    margin: 0;
    display: inline;
}

/* Blockquotes within lists are indented for visual hierarchy.
   Box-sizing prevents padding from expanding beyond the calculated width. */
.reveal ul li blockquote,
.reveal ol li blockquote {
    margin: 0.5em 0 0 1.5em;
    padding: 0 1em 0 0;
    width: calc(100% - 1.5em);
    box-sizing: border-box;
}

.reveal ul li blockquote p {
    margin: 0;
    display: inline;
}

/* Fix for reveal.js issue #2892: column layout breaks list rendering.
   Force "display: block" to restore proper list column distribution. */
div[style*="column-count"] ul,
div[style*="column-count"] ol {
    display: block;
}

/* Line blocks (poetry/verse formatted with pandoc) should be left-aligned,
   not center-aligned like normal slide content. */
div.line-block { text-align: left; }

/* === HEADINGS === */
/* Render headings as authored (sentence case) instead of the beige theme's
   default uppercase. Overrides --r-heading-text-transform from beige.css,
   which loads before this file. */
:root { --r-heading-text-transform: none; }

/* Remove text shadow from main headings for cleaner appearance.
   Line-height of 1 prevents extra spacing above/below. */
.reveal h1 {
    text-shadow: none;
    line-height: 1;
}

/* Add consistent spacing around h3 subheadings */
.reveal h3 {
    margin: 35px 0 10px 0;
}

/* === IMAGES === */
/* Responsive image sizing with reveal.js default styling removed.
   Addresses Stack Overflow #23082660 for cleaner image presentation. */
.reveal section img {
    max-height: calc(480px + 1vh);
    width: auto;
    background: none;
    border: none;
    box-shadow: none;
}

/* Images with captions need reduced height to accommodate caption below */
.reveal section figure img {
    max-height: calc(420px + 1vh);
}

/* === BACKGROUNDS === */
/* ISSUE: Text legibility on busy backgrounds remains an unsolved problem.
   blur_on_bg makes text too dark/fuzzy; frame_on_bg can be ugly with dense text.
   No single CSS solution handles all cases (gradients, solid colors, varied brightness,
   text overlays, busy images). May require light/dark background variations.
   Last reviewed: 2025-04-02 */

/* Text shadow provides contrast against busy backgrounds.
   Double shadow (light + dark) works across more background types. */
.reveal .blur_on_bg {
    text-shadow: 2px 1px 6px silver,
                 2px 1px 8px black;
}

/* Special formatting for lists on framed backgrounds.
   Inside positioning with manual indentation keeps bullets within frame. */
.reveal section.frame_on_bg :is(ul, ol) > li {
    list-style-position: inside;
    margin-left: 70px;
    text-indent: -50px; /* Outdent bullets/numbers from text */
}

/* Display inline prevents heading/paragraph backgrounds from spanning full width.
   Without this, the cream background would extend edge-to-edge. */
.reveal section.frame_on_bg > :is(h2, p) {
    display: inline;
}

/* Apply semi-transparent cream background to all direct children.
   Creates readable "frame" over busy background images. */
.reveal section.frame_on_bg > * {
    background: var(--frame-bg);
}

/* Global slide background dimming when HTML element has dim_background class.
   !important overrides reveal.js inline styles. */
html.dim_background .slide-background {
    opacity: 0.7 !important;
}

/* === LEFT- AND RIGHT-FLOATED IMAGE LAYOUT SECTIONS === */
/* Shared styles for img_left and img_right sections.
   These sections float images and flow text around them. */

/* z-index: -1 pushes blockquotes behind floated images to prevent overlap issues.
   Negative z-index is safe here because content remains interactive. */
section:is(.img_left, .img_right) blockquote {
    z-index: -1;
}

/* Left-floated images: override to use right border (away from image) */
section.img_left blockquote {
    border-left: none;
    border-right: 4px solid var(--quote-border-color);
    padding-left: 0.6em; /* Reset to base padding */
    padding-right: 1em;
}

/* Right-floated images keep the base blockquote's left border (away from the
   image), so no override is needed here. */

section:is(.img_left, .img_right) blockquote p {
    display: inline !important;
}

/* Remove default list markers and position them manually with ::before pseudo-elements.
   Default markers don't participate in the box model, so manual ::before markers
   give us precise control over bullet/number placement alongside floated images. */
section:is(.img_left, .img_right) ul,
section:is(.img_left, .img_right) ol {
    display: inline !important;
    list-style-position: inside;
    list-style: none; /* Disable default markers; we create custom ones below */
}

/* Negative text-indent + margin creates hanging indent for list items.
   This keeps markers aligned while allowing text to wrap properly. */
section:is(.img_left, .img_right) ul li,
section:is(.img_left, .img_right) ol li {
    text-indent: calc(var(--indent-spacing) * -1);
    margin-left: var(--list-margin);
}

/* Figures containing both image and caption, constrained to 50% width
   to leave room for surrounding text. */
section:is(.img_left, .img_right) figure {
    width: fit-content;
    max-width: 50%;
}

section:is(.img_left, .img_right) figure img {
    display: block;
    width: 100%;
    height: auto; /* Maintain aspect ratio */
}

/* Caption appears below image, centered, with small top margin */
section:is(.img_left, .img_right) figure figcaption {
    display: block;
    width: 100%;
    clear: both; /* Ensure caption doesn't flow beside image */
    text-align: center;
    margin-top: 0.5em;
}

/* === LEFT-FLOATED IMAGE SECTIONS === */
/* Float images left with right margin to create space for text flow.
   The margin calculation adds a 20px buffer to the standard --img-spacing
   specifically to prevent list counters (like "1.") from crowding the image edge. */
section.img_left :is(img, figure, a:has(img)) {
    float: left;
    margin-right: calc(var(--img-spacing) + 20px);
    position: relative;
    z-index: 1;
}

/* Reset float/margin on nested images to prevent doubling */
section.img_left :is(a, figure) img {
    float: none;
    margin-right: 0;
}

/* Shadow on left side suggests depth and visual weight */
section.img_left img {
    box-shadow: -5px 5px 10px 2px var(--shadow-gray);
}

/* Right-align blockquote text for visual balance with left-floated image */
section.img_left blockquote p {
    text-align: right;
}

/* Custom list markers using CSS counters and ::before pseudo-elements.
   Counter reset initializes counter for this section. */
section.img_left ul,
section.img_left ol {
    counter-reset: imgleft;
}

/* Bullet marker with precise spacing */
section.img_left ul li::before {
    content: "•";
    padding-right: 7px;
    margin-left: -5px; /* Fine-tune alignment */
}

/* Numbered list increments counter and displays number */
section.img_left ol li {
    counter-increment: imgleft;
}

section.img_left ol li::before {
    content: counter(imgleft, decimal) ". ";
    /* Make the marker a rigid box so it doesn't shrink/grow */
    display: inline-block; 
    /* The width must exactly fill the negative indent gap.
       (Indent Spacing 20px - Padding 5px = 15px Width) */
    width: calc(var(--indent-spacing) - 5px);
    /* Right-align pushes the number toward the text and AWAY from the image */
    text-align: right; 
    /* Keeps breathing room between number and text */
    padding-right: 5px; 
    /* Reset manual tweaks so the math works */
    margin-left: 0px; 
}

/* === RIGHT-FLOATED IMAGE SECTIONS === */
/* Float images right with left margin to create space for text flow */
section.img_right :is(img, figure, a:has(img)) {
    float: right;
    margin-left: var(--img-spacing);
    position: relative;
    z-index: 1;
}

/* Reset float/margin on nested images to prevent doubling */
section.img_right :is(a, figure) img {
    float: none;
    margin-left: 0;
}

/* Shadow on right side suggests depth and visual weight */
section.img_right img {
    box-shadow: 5px 5px 10px 2px var(--shadow-gray);
}

/* Custom list markers for right-floated sections.
   Separate counter from img_left to prevent conflicts. */
section.img_right ul,
section.img_right ol {
    counter-reset: imgright;
}

section.img_right ul li::before {
    content: "•";
    padding-right: 10px;
    margin-left: -5px; /* Fine-tune alignment */
}

section.img_right ol li {
    counter-increment: imgright;
}

section.img_right ol li::before {
    content: counter(imgright, decimal) ". ";
    /* Rigid box so multi-digit numbers don't shift the text (mirrors img_left).
       Width fills the negative indent gap: indent-spacing 20px - padding 5px = 15px. */
    display: inline-block;
    width: calc(var(--indent-spacing) - 5px);
    text-align: right; /* Push the number toward the text, away from the image */
    padding-right: 5px;
    margin-left: 0px;
}

/* === FIGURE CAPTIONS === */
.reveal figure {
    margin-bottom: 0.1em;
}

/* Captions are smaller than body text for visual hierarchy */
.reveal figcaption {
    font-size: 75%;
}

/* Pandoc doesn't wrap images in <figure> elements; it uses <a title="caption">.
   Emulate figure/figcaption behavior by displaying the title attribute as caption.
   Uses ::after pseudo-element to display caption without modifying markup. */
a[title]:has(img)::after {
    content: attr(title);
    display: block;
    text-align: center;
    font-size: 75%;
}

/* === TOOLTIP HOVER === */
/* Spans with title attributes are styled as interactive help text.
   Dotted underline indicates hoverability; cursor changes to help icon. */
span[title] {
  border-bottom: 1px dotted #666;
  cursor: help;
  position: relative; /* Positions tooltip pseudo-elements */
  background-color: color-mix(in srgb, yellow 20%, transparent);
  padding: 0.1em 0.2em;
  border-radius: 3px;
}

/* Nested tooltips compound background colors to indicate depth.
   Each level becomes progressively darker to show hierarchy. */
span[title] span[title] {
  background-color: color-mix(in srgb, orange 25%, transparent);
}

span[title] span[title] span[title] {
  background-color: color-mix(in srgb, darkorange 30%, transparent);
}

/* Custom tooltip appears above element on hover.
   Uses pseudo-elements to avoid JavaScript and maintain accessibility. */
span[title]:hover::after {
  content: attr(title); /* Display title attribute content */
  position: absolute;
  bottom: 100%; /* Position above element */
  left: 50%;
  transform: translateX(-50%); /* Center horizontally */
  padding: 0.5em 0.75em;
  background: #333;
  color: white;
  font-size: 0.7em;
  white-space: nowrap; /* Prevent line breaks in tooltip */
  border-radius: 4px;
  margin-bottom: 0.5em; /* Space between element and tooltip */
  z-index: 1000; /* Appear above other content */
  box-shadow: 0 2px 8px color-mix(in srgb, black 30%, transparent);
}

/* Downward-pointing triangle arrow connects tooltip to element.
   Creates visual relationship between tooltip and trigger. */
span[title]:hover::before {
  content: "";
  position: absolute;
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%);
  border: 6px solid transparent;
  border-top-color: #333; /* Only top border visible, forming triangle */
  z-index: 1000;
}

/* === CALLOUT/TOOLTIP BOXES === */
/* Expandable "thinking" callout in top-right corner.
   Collapsed state shows only emoji; expands on hover to reveal full content. */
div.call {
    position: absolute;
    z-index: 2; /* Above most content but below modals */
    top: 50px;
    right: 10px;
    height: 1.5em;
    width: 4em;
    overflow: hidden; /* Clips content in collapsed state */
    transition: transform 1.2s; /* Smooth expansion animation */
}

/* Thinking emoji (🤔) indicates expandable content.
   Grayscale reduces visual prominence until hover. */
div.call::before {
    content: "🤔";
    filter: grayscale(80%);
}

/* Compact text formatting for callout content */
div.call p,
div.call ul {
    list-style: inside;
    font-size: 90%;
}

/* Expanded state on hover: reveals full content with scroll if needed.
   Transform scale creates subtle zoom effect for attention. */
div.call:hover {
    overflow: auto; /* Enable scrolling for long content */
    transform: scale(1.1);
    width: auto;
    height: auto;
    max-width: 600px;
    max-height: 300px;
    background-color: var(--callout-bg);
    padding: 10px;
    padding-right: 25px; /* Extra padding for scrollbar */
    border: solid 1px #555;
    box-shadow: 10px 10px 5px var(--shadow-dark);
    border-radius: 25px;
}

/* === Pandoc alerts === */
/* > [!NOTE], [!TIP], [!IMPORTANT], [!WARNING], [!CAUTION]; GitHub style,
   icons are Primer Octicons (MIT), colors/icons shared with 2003/papers.css */
.reveal div.note,
.reveal div.tip,
.reveal div.important,
.reveal div.warning,
.reveal div.caution {
    margin: 0.4em 0;
    padding: 0 0.8em;
    border-left: 0.25em solid var(--alert-color);
    text-align: left;
    font-size: 80%;
}

.reveal div.note > div.title p,
.reveal div.tip > div.title p,
.reveal div.important > div.title p,
.reveal div.warning > div.title p,
.reveal div.caution > div.title p {
    display: flex;
    align-items: center;
    gap: 0.4em;
    margin: 0;
    font-weight: 600;
    color: var(--alert-color);
}

.reveal div.note > div.title p::before,
.reveal div.tip > div.title p::before,
.reveal div.important > div.title p::before,
.reveal div.warning > div.title p::before,
.reveal div.caution > div.title p::before {
    content: "";
    flex: none;
    width: 0.9em;
    height: 0.9em;
    background-color: currentColor;
    mask: var(--alert-icon) center / contain no-repeat;
}

.reveal div.note > p,
.reveal div.tip > p,
.reveal div.important > p,
.reveal div.warning > p,
.reveal div.caution > p {
    margin: 0;
}

div.note {
    --alert-color: #0969da;
    --alert-icon: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"%3E%3Cpath d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z"/%3E%3C/svg%3E');
}
div.tip {
    --alert-color: #1a7f37;
    --alert-icon: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"%3E%3Cpath d="M8 1.5c-2.363 0-4 1.69-4 3.75 0 .984.424 1.625.984 2.304l.214.253c.223.264.47.556.673.848.284.411.537.896.621 1.49a.75.75 0 0 1-1.484.211c-.04-.282-.163-.547-.37-.847a8.456 8.456 0 0 0-.542-.68c-.084-.1-.173-.205-.268-.32C3.201 7.75 2.5 6.766 2.5 5.25 2.5 2.31 4.863 0 8 0s5.5 2.31 5.5 5.25c0 1.516-.701 2.5-1.328 3.259-.095.115-.184.22-.268.319-.207.245-.383.453-.541.681-.208.3-.33.565-.37.847a.751.751 0 0 1-1.485-.212c.084-.593.337-1.078.621-1.489.203-.292.45-.584.673-.848.075-.088.147-.173.213-.253.561-.679.985-1.32.985-2.304 0-2.06-1.637-3.75-4-3.75ZM5.75 12h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1 0-1.5ZM6 15.25a.75.75 0 0 1 .75-.75h2.5a.75.75 0 0 1 0 1.5h-2.5a.75.75 0 0 1-.75-.75Z"/%3E%3C/svg%3E');
}
div.important {
    --alert-color: #8250df;
    --alert-icon: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"%3E%3Cpath d="M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v9.5A1.75 1.75 0 0 1 14.25 13H8.06l-2.573 2.573A1.458 1.458 0 0 1 3 14.543V13H1.75A1.75 1.75 0 0 1 0 11.25Zm1.75-.25a.25.25 0 0 0-.25.25v9.5c0 .138.112.25.25.25h2a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h6.5a.25.25 0 0 0 .25-.25v-9.5a.25.25 0 0 0-.25-.25Zm7 2.25v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 9a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"/%3E%3C/svg%3E');
}
div.warning {
    --alert-color: #9a6700;
    --alert-icon: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"%3E%3Cpath d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"/%3E%3C/svg%3E');
}
div.caution {
    --alert-color: #cf222e;
    --alert-icon: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"%3E%3Cpath d="M4.47.22A.749.749 0 0 1 5 0h6c.199 0 .389.079.53.22l4.25 4.25c.141.14.22.331.22.53v6a.749.749 0 0 1-.22.53l-4.25 4.25A.749.749 0 0 1 11 16H5a.749.749 0 0 1-.53-.22L.22 11.53A.749.749 0 0 1 0 11V5c0-.199.079-.389.22-.53Zm.84 1.28L1.5 5.31v5.38l3.81 3.81h5.38l3.81-3.81V5.31L10.69 1.5ZM8 4a.75.75 0 0 1 .75.75v3.5a.75.75 0 0 1-1.5 0v-3.5A.75.75 0 0 1 8 4Zm0 8a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z"/%3E%3C/svg%3E');
}

/* === Photo Album === */

/* 1. The Container */
.photo-album {
  display: grid;
  /* Auto-fill tiles: roughly 150px wide, fitting as many as possible */
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 1rem;
  align-items: end; /* Aligns images to the bottom if aspect ratios differ */
}

/* Handle if Markdown parser wraps the HTML in a <p> tag inside the div */
.photo-album p {
  display: contents; /* Removes the <p> from the layout calculation */
}

/* 2. The Items (The Links) */
.photo-album a {
  display: flex;
  flex-direction: column; /* Stack image on top, text on bottom */
  align-items: center;
  text-decoration: none;
  border: none !important; /* Remove reveal.js link borders */
}

.photo-album img {
  margin: 0 !important;
  max-width: 100%;
  max-height: 120px; /* Keep images from getting too tall */
  object-fit: contain;
}

/* 3. The Caption Extraction */
.photo-album a::after {
  content: attr(title); /* <--- The magic part */
  display: block;
  font-size: 0.4em;
  line-height: 1.2;
  margin-top: 5px;
  text-align: center;
  color: #666; /* Muted color for credits */
  
  /* Truncate long credits (like the CC BY-SA one) */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}

/* === ACCESSIBILITY === */
/* Respect user preference for reduced motion.
   Disables animations for users with vestibular disorders or motion sensitivity. */
@media (prefers-reduced-motion: reduce) {
    * {
        animation-duration: 0.01ms !important; /* Near-instant */
        animation-iteration-count: 1 !important; /* Single iteration only */
        transition-duration: 0.01ms !important; /* Near-instant */
    }
}