/* =============================================================
   preso.css — Progressive-reveal presentation framework

   Markup API:
     .preso-viewport     Wrap everything in this
     .slide              Each top-level content section
     .reveal-group       Expandable section: contains .seed + .layer
       .seed             Visible heading (click to toggle)
       .layer            Hidden content (revealed when group is .open)
     .expand             Inline trigger word (click to reveal adjacent)
     .expand-content     Inline hidden text (after .expand)
     .note               Presenter note (hidden in preso mode)
     .intro              Optional: centered intro section styling
     .hint               Optional: centered muted hint text
   ============================================================= */

/* --- Global safety nets --- */

img {
  max-width: 100%;
  height: auto;
}


/* --- Base layout (normal / reading mode) --- */

body {
  max-width: var(--measure);
  margin-inline: auto;
  padding: var(--space-xl) var(--space-lg);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

main {
  flex: 1;
}

/* --- 16:9 preso viewport --- */

body.preso-mode {
  max-width: none;
  padding: 0;
  margin: 0;
  min-height: 0;
  overflow: hidden;
  background: #111;
}

.preso-viewport {
  display: contents;
}

body.preso-mode .preso-viewport {
  display: flex;
  flex-direction: column;
  position: fixed;
  --vp-w: min(100vw, calc(100vh * 16 / 9));
  --vp-h: min(100vh, calc(100vw * 9 / 16));
  width: var(--vp-w);
  height: var(--vp-h);
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background: var(--color-bg);
  overflow-y: auto;
  overflow-x: hidden;
  scrollbar-width: thin;
  scrollbar-color: var(--color-border) transparent;
  font-size: calc(var(--vp-w) / 62);
  padding: 2.5em 4em;
  box-sizing: border-box;
}

/* Override theme's clamp() sizes with em-relative values
   so everything scales with the viewport font-size */
body.preso-mode .preso-viewport {
  --text-sm:  0.833em;
  --text-base: 1em;
  --text-lg:   1.2em;
  --text-xl:   1.44em;
  --text-2xl:  1.728em;
  --text-3xl:  2.074em;
  --space-xs:  0.25em;
  --space-sm:  0.5em;
  --space-md:  1em;
  --space-lg:  1.5em;
  --space-xl:  2em;
  --space-2xl: 3em;
  --space-3xl: 4em;
  --measure: 55em;
}

body.preso-mode .site-header {
  flex-shrink: 0;
  margin-block-end: 1em;
}

body.preso-mode .site-footer {
  flex-shrink: 0;
  margin-block-start: auto;
}

body.preso-mode main {
  flex: 1;
  min-height: 0;
  max-width: 65ch;
  margin-inline: auto;
}


/* --- Slide sections (scroll-reveal targets) --- */

.slide {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 0.6s ease, transform 0.6s ease;
}

.slide.visible {
  opacity: 1;
  transform: translateY(0);
}

/* In preso mode, static slides (no .reveal-group inside) are hidden
   until their step is reached. The .preso-visited class is toggled by JS. */
body.preso-mode .slide:not(:has(.reveal-group)):not(:has(.step)):not(.intro):not(.hint) {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 0.5s ease, transform 0.5s ease;
  pointer-events: none;
}

body.preso-mode .slide:not(:has(.reveal-group)):not(:has(.step)):not(.intro):not(.hint).preso-visited {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}


/* --- Progressive steps (.step) --- */
/* Always visible in normal mode. Hidden until visited in preso mode. */

body.preso-mode .step {
  opacity: 0;
  transition: opacity 0.4s ease;
}

body.preso-mode .step.preso-visited {
  opacity: 1;
}

/* Content visible only in presentation mode */
.preso-only { display: none; }
body.preso-mode .preso-only { display: block; }


/* --- Title change elements (invisible, step-only) --- */

/* --- Title change (inline chapter banner) --- */

.title-change {
  font-family: var(--font-ui);
  text-align: center;
  padding-block: var(--space-xl);
  margin-block: var(--space-xl);
  border-block-start: 1px solid var(--color-border);
  border-block-end: 1px solid var(--color-border);
}

.title-change .title-change-heading {
  font-size: var(--text-2xl);
  font-weight: 700;
  line-height: var(--leading-tight);
  margin: 0;
}

.title-change .title-change-sub {
  font-size: var(--text-base);
  color: var(--color-muted);
  margin-block-start: var(--space-xs);
}

/* In preso mode, title-change is hidden until visited (like static slides) */
body.preso-mode .title-change {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 0.5s ease, transform 0.5s ease;
  pointer-events: none;
}

body.preso-mode .title-change.preso-visited {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}


/* --- Mood color themes --- */
/* Applied to .preso-viewport via data-mood attribute.
   Four moods that shift --color-accent. */

.preso-viewport[data-mood="default"],
.preso-viewport:not([data-mood]) {
  --mood-accent: var(--color-accent);  /* theme default: saddle brown */
  --mood-stripe: var(--color-accent);
}

.preso-viewport[data-mood="cool"] {
  --mood-accent: #4a7c8a;
  --mood-stripe: #4a7c8a;
}

.preso-viewport[data-mood="warm"] {
  --mood-accent: #b35a2a;
  --mood-stripe: #b35a2a;
}

.preso-viewport[data-mood="deep"] {
  --mood-accent: #6b4c8a;
  --mood-stripe: #6b4c8a;
}

/* Dark mode mood variants */
@media (prefers-color-scheme: dark) {
  .preso-viewport[data-mood="cool"]:not([data-theme="light"]) {
    --mood-accent: #6aafbf;
    --mood-stripe: #6aafbf;
  }
  .preso-viewport[data-mood="warm"]:not([data-theme="light"]) {
    --mood-accent: #d4854a;
    --mood-stripe: #d4854a;
  }
  .preso-viewport[data-mood="deep"]:not([data-theme="light"]) {
    --mood-accent: #a080c0;
    --mood-stripe: #a080c0;
  }
}

[data-theme="dark"] .preso-viewport[data-mood="cool"],
.preso-viewport[data-mood="cool"][data-theme="dark"] {
  --mood-accent: #6aafbf;
  --mood-stripe: #6aafbf;
}

[data-theme="dark"] .preso-viewport[data-mood="warm"],
.preso-viewport[data-mood="warm"][data-theme="dark"] {
  --mood-accent: #d4854a;
  --mood-stripe: #d4854a;
}

[data-theme="dark"] .preso-viewport[data-mood="deep"],
.preso-viewport[data-mood="deep"][data-theme="dark"] {
  --mood-accent: #a080c0;
  --mood-stripe: #a080c0;
}

/* Apply mood accent to the standard accent property */
.preso-viewport[data-mood] {
  --color-accent: var(--mood-accent);
  transition: --color-accent 0.5s ease;
}


/* --- Side stripe (preso mode only) --- */

body.preso-mode .preso-viewport::before {
  content: "";
  position: fixed;
  top: 0;
  left: 0;
  width: 4px;
  height: 100vh;
  background: var(--mood-stripe, var(--color-accent));
  z-index: 50;
  transition: background 0.5s ease;
}


/* --- Progressive reveal mechanics --- */

.reveal-group {
  margin-block: var(--space-lg);
}

.seed {
  font-size: var(--text-xl);
  font-weight: 650;
  font-family: var(--font-ui);
  line-height: var(--leading-tight);
  cursor: pointer;
  user-select: none;
  position: relative;
  padding-block: var(--space-sm);
}

.seed::after {
  content: " +";
  font-weight: 300;
  color: var(--color-muted);
  font-size: 0.7em;
  transition: transform 0.3s ease, opacity 0.3s ease;
  display: inline-block;
}

.reveal-group.open > .seed::after {
  content: " \2212";  /* minus sign */
}

/* Nested seeds scale down per level */
.layer .seed {
  font-size: var(--text-lg);
}

.layer .layer .seed {
  font-size: var(--text-base);
  font-weight: 600;
}

.layer {
  overflow: hidden;
  max-height: 0;
  opacity: 0;
  transition: max-height 0.5s cubic-bezier(0.4, 0, 0.2, 1),
              opacity 0.4s ease 0.1s,
              margin 0.4s ease;
  margin-block: 0;
}

.reveal-group.open > .layer {
  max-height: 9999px;
  opacity: 1;
  margin-block: var(--space-md);
}

/* Nested layers get subtle left margin only — no border
   (seed size scaling already communicates hierarchy,
   and borders clash with blockquote callouts) */
.layer .layer {
  margin-inline-start: var(--space-md);
}

.layer .layer .layer {
  margin-inline-start: var(--space-sm);
}


/* --- Inline expanders --- */

.expand {
  color: var(--color-accent);
  cursor: pointer;
  text-decoration: underline;
  text-decoration-style: dotted;
  text-underline-offset: 0.15em;
}

.expand-content {
  display: inline;
  max-width: 0;
  max-height: 0;
  overflow: hidden;
  opacity: 0;
  transition: opacity 0.3s ease;
}

.expand.open + .expand-content,
.expand-content.open {
  max-width: none;
  max-height: none;
  opacity: 1;
}


/* --- Staggered children animation --- */

.reveal-group.open > .layer > * {
  animation: preso-fadeUp 0.4s ease both;
}

.reveal-group.open > .layer > *:nth-child(1) { animation-delay: 0.05s; }
.reveal-group.open > .layer > *:nth-child(2) { animation-delay: 0.12s; }
.reveal-group.open > .layer > *:nth-child(3) { animation-delay: 0.19s; }
.reveal-group.open > .layer > *:nth-child(4) { animation-delay: 0.26s; }
.reveal-group.open > .layer > *:nth-child(5) { animation-delay: 0.33s; }

@keyframes preso-fadeUp {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}


/* --- Content styling helpers --- */

.intro {
  padding-block: var(--space-3xl);
  text-align: center;
}

.intro h1 {
  font-size: var(--text-3xl);
  margin-block-end: var(--space-md);
}

.intro p {
  color: var(--color-muted);
  font-size: var(--text-lg);
}

.hint {
  font-family: var(--font-ui);
  font-size: var(--text-sm);
  color: var(--color-muted);
  text-align: center;
  margin-block: var(--space-xl);
  opacity: 0.7;
}


/* --- Callout slide (big takeaway) --- */

/* Only apply flex wrapper styles when .callout is a slide (section).
   When used inline as blockquote.callout, the blockquote must remain
   a block formatting context for normal text layout. */
.slide.callout {
  display: flex;
  align-items: center;
  justify-content: center;
  padding-block: var(--space-2xl);
  min-height: 30vh;
}

/* Works both as .callout blockquote (standalone slide) and
   blockquote.callout (inline inside a layer) */
.callout blockquote,
blockquote.callout {
  font-family: var(--font-ui);
  font-size: var(--text-lg);
  font-weight: 500;
  line-height: var(--leading-body);
  max-width: 50ch;
  margin: 0 auto;
  padding: var(--space-lg) var(--space-xl);
  border-inline-start: 4px solid var(--color-accent);
  font-style: normal;
  color: var(--color-text);
}

.callout blockquote em,
blockquote.callout em {
  font-style: normal;
  font-weight: 700;
  color: var(--color-accent);
}

.callout blockquote footer,
blockquote.callout footer {
  display: block;
  margin-block-start: var(--space-md);
  font-family: var(--font-ui);
  font-size: var(--text-sm);
  font-weight: 400;
  font-style: normal;
  color: var(--color-muted);
}

/* Inline callout spacing */
blockquote.callout {
  margin-block: var(--space-lg);
}

/* In preso mode, callout slide fills more of the viewport */
body.preso-mode .slide.callout {
  min-height: 50%;
}

body.preso-mode .callout blockquote {
  font-size: var(--text-xl);
}


/* --- Figure slide (image with title + citation) --- */

.figure {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding-block: var(--space-xl);
  gap: var(--space-md);
}

.figure figcaption {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.figure figcaption strong {
  font-family: var(--font-ui);
  font-size: var(--text-lg);
  font-weight: 650;
  color: var(--color-text);
}

.figure figcaption cite,
.figure figcaption small {
  font-family: var(--font-ui);
  font-size: var(--text-sm);
  font-style: normal;
  color: var(--color-muted);
  line-height: var(--leading-body);
}

.figure figcaption cite a {
  color: var(--color-muted);
}

.figure img {
  max-width: 100%;
  max-height: 55vh;
  height: auto;
  object-fit: contain;
  border-radius: 0.25rem;
}

body.preso-mode .figure img {
  max-height: 65%;
}


/* --- Figure sequence (crossfading image series) --- */
/* Normal mode: figures stack vertically */

.figure-sequence figure {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding-block: var(--space-lg);
  gap: var(--space-md);
}

.figure-sequence figure + figure {
  border-block-start: 1px solid var(--color-border);
}

.figure-sequence figure img {
  max-width: 100%;
  max-height: 55vh;
  height: auto;
  object-fit: contain;
  border-radius: 0.25rem;
}

.figure-sequence figcaption {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.figure-sequence figcaption strong {
  font-family: var(--font-ui);
  font-size: var(--text-lg);
  font-weight: 650;
  color: var(--color-text);
}

.figure-sequence figcaption cite,
.figure-sequence figcaption small {
  font-family: var(--font-ui);
  font-size: var(--text-sm);
  font-style: normal;
  color: var(--color-muted);
  line-height: var(--leading-body);
}

/* Preso mode: stack figures on top of each other, crossfade */

body.preso-mode .figure-sequence {
  display: grid;
  align-items: center;
  justify-items: center;
  min-height: 50%;
}

body.preso-mode .figure-sequence figure {
  grid-area: 1 / 1;
  padding-block: var(--space-md);
}

body.preso-mode .figure-sequence figure + figure {
  border-block-start: none;
}

body.preso-mode .figure-sequence figure img {
  max-height: 50vh;
}

/* Hide all steps, then show only the latest visited one.
   A visited step that has a LATER visited sibling is not the latest. */
body.preso-mode .figure-sequence > .step.preso-visited:has(~ .step.preso-visited) {
  opacity: 0;
}


/* --- Full-width modifier for figure / figure-sequence --- */

.full-width img {
  max-width: 100%;
  width: 100%;
  object-fit: contain;
}


/* --- Profile slide (text with side image) --- */

.profile {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--space-xl);
  align-items: start;
  padding-block: var(--space-xl);
}

.profile-body {
  min-width: 0;
}

/* h2 is auto-converted to a .seed by preso.js */
.profile-body h2,
.profile-body .seed {
  font-family: var(--font-ui);
  font-size: var(--text-2xl);
  font-weight: 700;
  margin: 0 0 var(--space-xs);
}

.profile-body .reveal-group {
  margin-block: 0;
}

.profile-body .profile-meta {
  font-family: var(--font-ui);
  font-size: var(--text-sm);
  color: var(--color-muted);
  margin-block-end: var(--space-md);
}

.profile-image {
  width: clamp(6rem, 12vw, 10rem);
  flex-shrink: 0;
}

.profile-image img {
  width: 100%;
  height: auto;
  border-radius: 0.375rem;
  object-fit: cover;
  aspect-ratio: 3 / 4;
}

.profile-image figcaption {
  font-family: var(--font-ui);
  font-size: calc(var(--text-sm) * 0.85);
  color: var(--color-muted);
  margin-block-start: var(--space-xs);
  text-align: center;
  line-height: var(--leading-body);
}

/* Stack on narrow viewports */
@media (max-width: 35rem) {
  .profile {
    grid-template-columns: 1fr;
  }
  .profile-image {
    order: -1;
    width: clamp(5rem, 30vw, 8rem);
    justify-self: center;
  }
}


/* --- Tables --- */

table {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--font-ui);
  font-size: var(--text-sm);
  line-height: var(--leading-body);
  display: block;
  overflow-x: auto;
  margin-block: var(--space-lg);
}

thead {
  border-block-end: 2px solid var(--color-text);
}

th {
  font-weight: 650;
  text-align: start;
  padding: var(--space-sm) var(--space-sm);
  white-space: nowrap;
}

td {
  padding: var(--space-xs) var(--space-sm);
  border-block-end: 1px solid var(--color-border);
  vertical-align: top;
}

/* Last column can wrap */
td:last-child, th:last-child {
  white-space: normal;
}

/* In preso mode, make table text scale */
body.preso-mode table {
  font-size: calc(var(--text-sm) * 0.9);
}


/* --- Presenter notes --- */

.note {
  font-family: var(--font-ui);
  font-size: var(--text-sm);
  color: var(--color-muted);
  border-inline-start: 2px solid var(--color-border);
  padding-inline-start: var(--space-md);
  margin-block: var(--space-md);
  font-style: italic;
  line-height: var(--leading-body);
}

body.preso-mode .note {
  font-size: calc(var(--text-sm) * 0.85);
  opacity: 0.5 !important;
  border-inline-start: 1px solid var(--color-border);
  margin-block: var(--space-xs);
  animation: none !important;
}


/* --- Preso mode toggle (auto-injected by preso.js) --- */

.preso-toggle {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  font-family: var(--font-ui);
  font-size: var(--text-sm);
  color: var(--color-muted);
  cursor: pointer;
  user-select: none;
}

.preso-toggle input { display: none; }

.preso-switch {
  position: relative;
  width: 2.4rem;
  height: 1.35rem;
  background: var(--color-border);
  border-radius: 1rem;
  transition: background 0.2s ease;
  flex-shrink: 0;
}

.preso-switch::after {
  content: "";
  position: absolute;
  top: 0.175rem;
  left: 0.175rem;
  width: 1rem;
  height: 1rem;
  background: var(--color-bg);
  border-radius: 50%;
  transition: transform 0.2s ease;
}

.preso-toggle input:checked + .preso-switch {
  background: var(--color-accent);
}

.preso-toggle input:checked + .preso-switch::after {
  transform: translateX(1.05rem);
}

.preso-toggle:focus-within .preso-switch {
  outline: 0.125rem solid var(--color-accent);
  outline-offset: 0.125rem;
}


/* --- Preso restart button (auto-injected) --- */

.preso-restart,
.preso-expand-all {
  background: none;
  border: none;
  font-size: var(--text-lg);
  color: var(--color-muted);
  cursor: pointer;
  padding: 0.2em 0.3em;
  line-height: 1;
  border-radius: 0.25rem;
  min-width: 2.2rem;
  min-height: 2.2rem;
  display: flex;
  align-items: center;
  justify-content: center;
}

.preso-restart:hover,
.preso-expand-all:hover {
  color: var(--color-text);
  background: var(--color-code-bg);
}


/* --- Preso mode progress bar (auto-injected) --- */

.preso-progress {
  position: fixed;
  bottom: 0;
  left: 0;
  height: 3px;
  background: var(--color-accent);
  transition: width 0.3s ease;
  z-index: 100;
  opacity: 0;
  pointer-events: none;
}

body.preso-mode .preso-progress {
  opacity: 1;
}


/* --- Preso mode nav hint (auto-injected) --- */

.preso-nav-hint {
  position: fixed;
  bottom: var(--space-md);
  right: var(--space-md);
  font-family: var(--font-ui);
  font-size: var(--text-sm);
  color: var(--color-muted);
  opacity: 0;
  transition: opacity 0.3s ease;
  pointer-events: none;
  display: flex;
  gap: var(--space-sm);
}

body.preso-mode .preso-nav-hint {
  opacity: 0.6;
}

.preso-nav-hint kbd {
  display: inline-block;
  padding: 0.1em 0.45em;
  font-family: var(--font-ui);
  font-size: 0.85em;
  border: 1px solid var(--color-border);
  border-radius: 0.2rem;
  background: var(--color-code-bg);
}


/* --- Preso mode highlights --- */

body.preso-mode .seed.preso-current {
  background: var(--color-highlight);
  border-radius: 0.2rem;
  padding-inline: var(--space-sm);
  margin-inline: calc(-1 * var(--space-sm));
}

body.preso-mode .expand.preso-current {
  background: var(--color-highlight);
  border-radius: 0.2rem;
  padding: 0.05em 0.2em;
}


/* --- Reduced motion --- */

@media (prefers-reduced-motion: reduce) {
  .layer, .slide, .expand-content {
    transition: none !important;
    animation: none !important;
  }
  .slide { opacity: 1; transform: none; }
}
