/*
 * VoiceFirst deck — presentation chrome and readability overrides.
 * Sits on top of reveal.js 6.0.2 + the vendored `black` theme.
 *
 * Priorities, in order: readable from the back row, obvious when a demo fails,
 * and nothing that breaks reveal's own scaling model.
 */

:root {
  --vf-accent: #6ee7ff;
  --vf-accent-dim: #2b6a78;
  --vf-fallback: #ffb454;
  --vf-chrome-bg: rgba(0, 0, 0, 0.45);
  --vf-chrome-fg: rgba(255, 255, 255, 0.72);
}

.reveal-viewport {
  background: #000;
}

/* Fallback for browsers that refuse the Fullscreen API (notably iOS Safari).
   reveal still scales and centers; we just paint the viewport edge-to-edge. */
body.pseudo-fullscreen .reveal-viewport {
  position: fixed;
  inset: 0;
  z-index: 50;
}

/* --- Typography: sized for the back row of a conference room. ------------- */

.reveal h1 {
  font-size: 2.6em;
  letter-spacing: -0.02em;
  text-transform: none;
}

.reveal h2 {
  font-size: 1.9em;
  letter-spacing: -0.01em;
  text-transform: none;
  margin-bottom: 0.5em;
}

.reveal p,
.reveal li {
  font-size: 1.05em;
  line-height: 1.45;
}

/* The title slide carries the least text, so it can afford to be large. */
.reveal .slides section:first-child h1 {
  font-size: 3.2em;
  color: var(--vf-accent);
}

.reveal .subtitle {
  color: rgba(255, 255, 255, 0.78);
  font-size: 1.1em;
  font-style: normal;
}

/* --- Content conventions ------------------------------------------------- */

/* FALLBACK lines are presenter-only. They stay in the markup (the smoke test
   requires one per demo slide and the speaker notes repeat them) but are off the
   projector. Add ?fallback to the URL to show them while rehearsing. */
.reveal p.fallback {
  display: none;
}

html.show-fallback .reveal p.fallback {
  display: block;
}

/* Every PLACEHOLDER is a to-do, not a style choice. Make it impossible to
   ship one without noticing. */
.reveal .notes-hint,
.reveal p[class*="fallback"] {
  font-size: 0.62em;
  line-height: 1.4;
  color: var(--vf-fallback);
  border-left: 3px solid var(--vf-fallback);
  padding: 0.35em 0 0.35em 0.7em;
  margin-top: 1.1em;
  text-align: left;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}

.reveal .notes-hint {
  border-left-color: var(--vf-accent-dim);
  color: rgba(255, 255, 255, 0.55);
}

.reveal .demo-cue {
  font-size: 1.35em;
  color: var(--vf-accent);
  border: 2px solid var(--vf-accent);
  border-radius: 10px;
  padding: 0.6em 0.8em;
  margin-top: 0.6em;
}

.reveal .fragment.highlight-current-visible {
  color: var(--vf-accent);
}

/* --- Join QR ---------------------------------------------------------------
   One fixed element. Slide 1 (body.at-start): fills the slide, centred below
   the title. Any other slide: small, top-right, persistent. Size/position
   animate; prefers-reduced-motion snaps instead. */

.join-qr {
  position: fixed;
  z-index: 90;
  /* left/top/width are set by deck.js (hero = over slide 1's spacer, corner =
     top-right); these are the pre-JS defaults. */
  top: 10px;
  right: 10px;
  width: 90px;
  aspect-ratio: 1;
  padding: 0.35em;
  box-sizing: border-box;
  background: #fff;
  border-radius: 10px;
  line-height: 0;
  transition:
    top 650ms cubic-bezier(0.22, 1, 0.36, 1),
    left 650ms cubic-bezier(0.22, 1, 0.36, 1),
    width 650ms cubic-bezier(0.22, 1, 0.36, 1);
}

.join-qr svg {
  width: 100%;
  height: 100%;
  display: block;
}

.reveal .join-slide h1 {
  margin-bottom: 0.1em;
}

.reveal .join-qr-spacer {
  height: 330px; /* slide px: the QR is laid over this box by deck.js */
}

.reveal .join-caption {
  font-size: 0.95em;
  color: rgba(255, 255, 255, 0.78);
}

.reveal .join-caption strong {
  color: var(--vf-accent);
}

.join-qr-print {
  display: none;
}

@media (prefers-reduced-motion: reduce) {
  .join-qr,
  html[data-layout="vertical"] .reveal .slides > section.present {
    transition: none;
    animation: none;
  }
}

/* --- Vertical pane transition ------------------------------------------------
   The deck is flat (linear), so "vertical" is cosmetic: the incoming slide
   rises into place. Uses the individual `translate` property so it never fights
   reveal's own transforms. */

@keyframes vf-rise {
  from {
    opacity: 0;
    translate: 0 36px;
  }
  to {
    opacity: 1;
    translate: 0 0;
  }
}

html[data-layout="vertical"] .reveal .slides > section.present {
  animation: vf-rise 380ms cubic-bezier(0.22, 1, 0.36, 1);
}

/* --- Chrome: fullscreen button + speaker clock ---------------------------- */

.deck-chrome {
  position: fixed;
  top: 0;
  left: 0; /* top-right belongs to the join QR */
  z-index: 100;
  display: flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.5rem 0.6rem;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  /* Auto-hide: visible on hover, invisible while the deck is on screen. */
  opacity: 0.25;
  transition: opacity 160ms ease;
}

.deck-chrome:hover,
.deck-chrome:focus-within {
  opacity: 1;
}

#fs-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  padding: 0;
  border: 1px solid rgba(255, 255, 255, 0.25);
  border-radius: 6px;
  background: var(--vf-chrome-bg);
  color: var(--vf-chrome-fg);
  cursor: pointer;
}

#fs-btn:hover,
#fs-btn:focus-visible {
  color: #fff;
  border-color: var(--vf-accent);
  background: rgba(0, 0, 0, 0.7);
}

#clock {
  color: var(--vf-chrome-fg);
  font-size: 0.85rem;
  font-variant-numeric: tabular-nums;
  min-width: 3.2rem;
  text-align: right;
}

#clock.over {
  color: var(--vf-fallback);
}

/* --- Print: the offline fallback, rendered by reveal's print-pdf mode ------ */
/* Two cases, and both must hide the screen chrome:
     1. opening index.html?print-pdf on screen — reveal puts `print-pdf` and
        `reveal-print` on <html>, but the page is still laid out on screen, so
        @media print does NOT apply. Without these rules the fullscreen button
        and the speaker clock print onto every page.
     2. Chrome's own print pipeline, where @media print does apply. */

html.print-pdf .join-qr,
html.reveal-print .join-qr,
html.print-pdf .deck-chrome,
html.reveal-print .deck-chrome,
html.print-pdf .reveal .controls,
html.reveal-print .reveal .controls,
html.print-pdf .progress,
html.reveal-print .progress {
  display: none !important;
}

/* The fixed overlay does not print; slide 1 carries its own QR copy instead. */
html.print-pdf .join-qr-print,
html.reveal-print .join-qr-print {
  display: block;
  width: 300px;
  margin: 0 auto 20px;
  padding: 10px;
  background: #fff;
  border-radius: 10px;
  line-height: 0;
}

html.print-pdf .join-qr-spacer,
html.reveal-print .join-qr-spacer {
  display: none;
}

@media print {
  .join-qr,
  .deck-chrome,
  .reveal .controls,
  .progress {
    display: none !important;
  }

  .reveal .notes-hint,
  .reveal p[class*="fallback"] {
    color: #333;
    border-left-color: #333;
  }
}