/* CloudBridge slideshow theme — replaces reveal.js stock themes.
   Loaded only on /courses/{slug}/{session}/slides, alongside reveal.min.css. */

@font-face {
  font-family: "Montserrat";
  src: url("/static/montserrat.ttf") format("truetype");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

:root {
  --cb-ink: #2d2926;
  --cb-blue: #5dc8f0;
  --cb-teal: #5fc8be;
  --cb-link: #0a7ea4;
  --cb-link-strong: #075f7d;
  /* Brand teal darkened enough to carry meaning on the light slide variant. */
  --cb-teal-deep: #1f7a70;
  --r-background-color: #2d2926;
  --r-main-font: "Montserrat", system-ui, sans-serif;
  --r-main-font-size: 38px;
  --r-main-color: #ffffff;
  --r-heading-font: "Montserrat", system-ui, sans-serif;
  --r-heading-color: #ffffff;
  --r-heading-text-transform: none;
  --r-link-color: #5dc8f0;
  --r-link-color-hover: #8ddaf5;
  --r-selection-background-color: #5fc8be;
  --r-selection-color: #2d2926;
}

.reveal-viewport {
  background: var(--cb-ink);
}

.reveal {
  font-family: "Montserrat", system-ui, sans-serif;
  font-size: 38px;
  /* reveal's core stylesheet sets no body line-height (the stock themes this
     file replaces did), leaving `normal` — too tight for wrapped prose, and
     tight enough that an inline-code chip clips the descenders above it. */
  line-height: 1.4;
  color: #ffffff;
}

.reveal h1,
.reveal h2,
.reveal h3,
.reveal h4 {
  font-family: "Montserrat", system-ui, sans-serif;
  color: #ffffff;
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1.15;
  text-transform: none;
}

.reveal h2 {
  padding-bottom: 0.25em;
  border-bottom: 3px solid var(--cb-teal);
  display: inline-block;
}

/* The four heading levels are distinct visual tools: h1 carries a concept,
   h2 starts a major section, h3 introduces a subsection, and h4 works as a
   compact label. Title-only slides retain their dedicated hero treatment. */

.reveal .slides > section > h1:not(.cb-title-slide) {
  margin: 0 0 0.55em;
  padding-bottom: 0.28em;
  letter-spacing: -0.035em;
  border-bottom: 0.1em solid var(--cb-teal);
  border-image: linear-gradient(90deg, var(--cb-teal), var(--cb-blue), transparent) 1;
}

.reveal .slides > section > h2 {
  position: relative;
  padding-bottom: 0.35em;
  border-bottom: 0;
}

.reveal .slides > section > h2::after {
  content: "";
  position: absolute;
  right: 0;
  bottom: 0;
  left: 0;
  height: 0.09em;
  border-radius: 1em;
  background: linear-gradient(90deg, var(--cb-teal), var(--cb-blue), transparent);
}

/* A third-level title introduces a smaller idea within a slide. Give it its
   own branded treatment, instead of letting it read like a reduced h1: a teal
   marker and a short gradient rule echo the site's section dividers. */

.reveal .slides > section > h3 {
  display: flex;
  align-items: center;
  gap: 0.35em;
  margin: 0 0 0.85em;
  letter-spacing: 0;
}

.reveal .slides > section > h3::before {
  content: "";
  width: 0.22em;
  height: 0.9em;
  flex: 0 0 auto;
  border-radius: 0.12em;
  background: var(--cb-teal);
}

.reveal .slides > section > h3::after {
  content: "";
  width: 2.8em;
  height: 0.08em;
  flex: 0 0 auto;
  border-radius: 1em;
  background: linear-gradient(90deg, var(--cb-teal), transparent);
}

.reveal .slides > section > h4 {
  display: inline-flex;
  align-items: center;
  margin: 0 0 0.9em;
  padding: 0.28em 0.55em;
  color: var(--cb-teal);
  font-size: 0.45em;
  font-weight: 700;
  letter-spacing: 0.12em;
  line-height: 1.2;
  text-transform: uppercase;
  background: rgba(95, 200, 190, 0.12);
  border-left: 0.32em solid var(--cb-teal);
  border-radius: 0 0.25em 0.25em 0;
}

/* Regular slide content starts at the deck's left edge and may consume the
   available content width. Title slides override this locally below. */

.reveal .slides > section {
  /* Reveal positions top-level slides absolutely but does not give them a
     height. Without this, `overflow-y: auto` expands with the content instead
     of becoming a scroll container. */
  height: 100%;
  box-sizing: border-box;
  text-align: left;
  /* Keep a dense slide readable when it exceeds the fixed Reveal canvas. The
     scrollbar appears only when needed; arrow controls still change slides. */
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  /* Keep overflow available for long slides without adding a visual rail to the
     presentation. Wheel, trackpad, touch, Page Down, and arrow-key scrolling
     continue to work normally. */
  -ms-overflow-style: none;
  scrollbar-width: none;
  touch-action: pan-y;
}

.reveal .slides > section::-webkit-scrollbar {
  display: none;
}

.reveal ol,
.reveal ul {
  display: block;
  text-align: left;
  box-sizing: border-box;
  width: 100%;
  max-width: 100%;
  margin: 0;
}

.reveal ol {
  list-style: decimal;
}

.reveal ul {
  list-style: disc;
}

.reveal li {
  margin: 0.35em 0;
  padding-left: 0.25em;
}

/* List markers carry the brand accent instead of the body colour. */

.reveal li::marker {
  color: var(--cb-teal);
  font-weight: 700;
}

.reveal section.cb-light li::marker {
  color: var(--cb-teal-deep);
}

/* Links. reveal's core stylesheet leaves anchors unstyled — link colour lives in
   the stock themes this file replaces — so without these they fall back to the
   browser's default blue. `.cb-hlink` is excluded: heading self-links inherit
   the heading colour, and the light-slide rules would otherwise outrank them. */

.reveal a:not(.cb-hlink) {
  color: var(--cb-blue);
  text-decoration: underline;
  text-decoration-color: rgba(93, 200, 240, 0.45);
  text-decoration-thickness: 0.05em;
  text-underline-offset: 0.18em;
  overflow-wrap: break-word;
  transition: color 0.15s ease, text-decoration-color 0.15s ease;
}

.reveal a:not(.cb-hlink):hover,
.reveal a:not(.cb-hlink):focus-visible {
  color: var(--cb-teal);
  text-decoration-color: var(--cb-teal);
}

/* Brand blue is unreadable on the light variant's near-white background. */

.reveal section.cb-light a:not(.cb-hlink) {
  color: var(--cb-link);
  text-decoration-color: rgba(10, 126, 164, 0.4);
}

.reveal section.cb-light a:not(.cb-hlink):hover,
.reveal section.cb-light a:not(.cb-hlink):focus-visible {
  color: var(--cb-link-strong);
  text-decoration-color: var(--cb-link-strong);
}

.reveal pre,
.reveal code {
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
}

.reveal pre {
  background: #221f1d;
  color: #e8e8e8;
  border-left: 4px solid var(--cb-teal);
  border-radius: 4px;
  padding: 0.6em 0.9em;
  font-size: 0.6em;
  line-height: 1.5;
  box-shadow: none;
  /* Slides centre their text; code must stay flush left to keep indentation
     and multi-line commands readable. */
  text-align: left;
}

/* Code keeps the light pre color even on light slides, where the cb-light
   rules would otherwise darken inherited text to ink. */
.reveal pre,
.reveal pre code,
.reveal section.cb-light pre,
.reveal section.cb-light pre code {
  color: #e8e8e8;
}

/* Inline code reads as a tinted chip, as it does in the guide. */

.reveal code {
  font-size: 0.9em;
  /* Vertical padding stays small: the chip must fit inside the line box, or it
     paints over the descenders of the line above. */
  padding: 0.04em 0.34em;
  background: rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(95, 200, 190, 0.35);
  border-radius: 5px;
}

.reveal section.cb-light code {
  background: #e7ebea;
  border-color: rgba(31, 122, 112, 0.3);
}

/* …but code inside a block keeps the block's own chrome. The light-slide reset
   has to be spelled out: `.reveal section.cb-light code` outranks
   `.reveal pre code`, so a one-selector reset would lose inside a light slide. */

.reveal pre code,
.reveal section.cb-light pre code {
  font-size: 1em;
  padding: 0;
  background: none;
  border: 0;
}

.reveal table {
  margin: 0 auto;
  border-collapse: collapse;
  font-size: 0.75em;
}

.reveal th {
  color: var(--cb-teal);
  border-bottom: 2px solid var(--cb-teal);
  padding: 0.3em 0.8em;
  text-align: left;
}

.reveal td {
  border-bottom: 1px solid #4a4542;
  padding: 0.3em 0.8em;
  text-align: left;
}

.reveal .controls,
.reveal .progress {
  color: var(--cb-teal);
}

/* Light slide variant: :::slide light → <section class="cb-light">. */

.reveal section.cb-light h1,
.reveal section.cb-light h2,
.reveal section.cb-light h3,
.reveal section.cb-light h4 {
  color: var(--cb-ink);
}

.reveal section.cb-light h2 {
  border-bottom-color: var(--cb-teal);
}

.reveal section.cb-light p,
.reveal section.cb-light li,
.reveal section.cb-light td,
.reveal section.cb-light th {
  color: var(--cb-ink);
}

.reveal section.cb-light th {
  border-bottom-color: var(--cb-teal);
}

.reveal section.cb-light td {
  border-bottom-color: #ccc9c6;
}

/* Thematic breaks: same tapered gradient rule as the guide, sized in `em` so it
   tracks the scaled deck. Reads on both the dark and the light slide variants. */

.reveal hr {
  width: 8em;
  height: 3px;
  margin: 0.8em auto;
  border: 0;
  border-radius: 2px;
  background: linear-gradient(
    90deg,
    transparent,
    var(--cb-teal),
    var(--cb-blue),
    transparent
  );
}

/* Exercise hero card: kicker + title + statement + solution toggle. */

.reveal .cb-ejercicio {
  text-align: left;
  max-width: 90%;
  margin: 0 auto;
  padding: 0.9em 1.1em;
  background: #3a3531;
  border-left: 6px solid var(--cb-teal);
  border-radius: 10px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.25);
}

.reveal .cb-ejercicio-kicker {
  margin: 0;
  color: var(--cb-teal);
  font-size: 0.45em;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.reveal .cb-ejercicio h3 {
  margin: 0.1em 0 0.4em;
  font-size: 1em;
}

.reveal .cb-ejercicio-cuerpo {
  font-size: 0.7em;
  line-height: 1.5;
}

.reveal .cb-ejercicio ol,
.reveal .cb-ejercicio ul {
  margin: 0.4em 0 0.4em 1.2em;
  width: auto;
  max-width: none;
}

.reveal .cb-ejercicio .solucion {
  margin-top: 0.6em;
}

.reveal .solucion-toggle {
  font-family: inherit;
  font-size: 0.5em;
  font-weight: 700;
  color: var(--cb-ink);
  background: var(--cb-teal);
  border: none;
  border-radius: 999px;
  padding: 0.5em 1.4em;
  cursor: pointer;
}

.reveal .solucion-toggle:hover {
  background: var(--cb-blue);
}

.reveal .solucion-cuerpo {
  margin-top: 0.6em;
  font-size: 0.55em;
  line-height: 1.5;
  max-height: 11em;
  overflow-y: auto;
  border-top: 1px solid #4a4542;
  padding-top: 0.6em;
}

.reveal section.cb-light .cb-ejercicio {
  background: #ffffff;
  box-shadow: 0 12px 32px rgba(45, 41, 38, 0.12);
}

.reveal section.cb-light .solucion-cuerpo {
  border-top-color: #e3e0dd;
}

/* Title-only slide (:::title-slide): the section heading as a centered hero. */

.reveal .cb-title-slide {
  display: table;
  margin-left: auto;
  margin-right: auto;
  font-size: 2em;
  font-weight: 700;
  line-height: 1.1;
  padding-bottom: 0.3em;
  border-bottom: 4px solid var(--cb-teal);
  text-align: center;
}

.reveal section.cb-light .cb-title-slide {
  color: var(--cb-ink);
}

/* Heading self-links come from the shared Markdown renderer; inert on slides
   (a hash click would fight reveal.js's #/n navigation). */

.reveal .cb-hlink {
  color: inherit;
  text-decoration: none;
  pointer-events: none;
}

/* Close button: top-right, circular ghost, back to the session guide. */

.cb-slides-close {
  position: fixed;
  top: 1rem;
  right: 1rem;
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.2rem;
  height: 2.2rem;
  border-radius: 50%;
  color: #fff;
  background: rgba(0, 0, 0, 0.25);
  opacity: 0.6;
  text-decoration: none;
  transition: opacity 0.15s ease, background 0.15s ease;
}

.cb-slides-close svg {
  display: block;
  width: 1.1rem;
  height: 1.1rem;
}

.cb-slides-close:hover {
  opacity: 1;
  background: rgba(0, 0, 0, 0.5);
}

/* Admonitions nested in slide content. */

.reveal .cb-warning {
  position: relative;
  background: #fdf6e3;
  border-left: 4px solid #d97706;
  border-radius: 8px;
  color: var(--cb-ink);
  padding: 0.5em 0.8em 0.5em 2em;
  font-size: 0.6em;
  text-align: left;
}

.reveal .cb-warning::before {
  content: "⚠";
  position: absolute;
  left: 0.7em;
  top: 0.5em;
  color: #d97706;
}

.reveal .cb-info {
  position: relative;
  background: #eff6ff;
  border-left: 4px solid #2563eb;
  border-radius: 8px;
  color: var(--cb-ink);
  padding: 0.5em 0.8em 0.5em 2em;
  font-size: 0.6em;
  text-align: left;
}

.reveal .cb-info::before {
  content: "ℹ";
  position: absolute;
  left: 0.7em;
  top: 0.5em;
  color: #2563eb;
}

/* Code-copy buttons on slides (markup injected by toggle.js) */

.reveal .cb-code {
  position: relative;
}

.reveal .cb-copy {
  position: absolute;
  top: 0.3em;
  right: 0.3em;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.25em;
  color: #e8e8e8;
  background: rgba(255, 255, 255, 0.14);
  border: 1px solid rgba(255, 255, 255, 0.3);
  border-radius: 0.4em;
  cursor: pointer;
}

.reveal .cb-copy.cb-copied {
  color: var(--cb-ink);
  background: var(--cb-teal);
  border-color: var(--cb-teal);
}

/* Mermaid measures HTML labels in helper elements attached to <body>, which
   inherit the body font. Reveal only styles .reveal, so without this the
   labels measure in the browser's serif default and render clipped. */
body {
  font-family: "Montserrat", system-ui, sans-serif;
}

/* While mermaid renders, the deck must sit at scale 1: mermaid sizes labels
   with getBoundingClientRect, and reveal's scale transform shrinks those
   measurements, clipping the text. The !important guard holds even if
   something (e.g. an image load) triggers Reveal.layout() mid-render;
   mermaid-init.js toggles the class and re-runs layout afterwards. */
.reveal.cb-mermaid-measure .slides {
  transform: none !important;
}

/* Mermaid diagrams on slides: centered, no code-block chrome, bounded to the
   slide box. Authored on light slides (`:::slide light`) for contrast. */
.reveal pre.mermaid {
  position: relative;
  background: none;
  border: none;
  box-shadow: none;
  padding: 0;
  margin: 0 auto;
  text-align: center;
  font-size: 1em;
  visibility: hidden;
}
.reveal pre.mermaid[data-processed="true"] {
  visibility: visible;
}
.reveal pre.mermaid svg {
  max-width: 100%;
  max-height: 600px;
  height: auto;
}

/* Maximize button on slide diagrams. */
.reveal .cb-diagram-zoom {
  position: absolute;
  top: 0.2em;
  right: 0.2em;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.4em;
  height: 1.4em;
  font-size: 0.5em;
  line-height: 1;
  color: var(--cb-ink);
  background: rgba(255, 255, 255, 0.85);
  border: 1px solid rgba(0, 0, 0, 0.15);
  border-radius: 0.3em;
  cursor: pointer;
}

/* Full-viewport overlay (mermaid-init.js appends it to <body>, outside .reveal). */
.cb-diagram-overlay {
  position: fixed;
  inset: 0;
  z-index: 10000;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 3vmin;
  background: rgba(20, 18, 16, 0.94);
  cursor: zoom-out;
}
.cb-diagram-overlay.cb-open {
  display: flex;
}
.cb-diagram-stage {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}
.cb-diagram-stage svg {
  max-width: 100%;
  max-height: 100%;
}

/* Live toasts on slide decks (same client as the guide). Sized in px since the
   deck font-size is the scaled reveal context, not the document. */
.cb-toasts {
  position: fixed;
  right: 1rem;
  bottom: 1rem;
  z-index: 11000;
  display: flex;
  flex-direction: column-reverse;
  gap: 8px;
  max-width: 360px;
  pointer-events: none;
}
.cb-toast {
  pointer-events: auto;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 10px 13px;
  border-radius: 8px;
  border-left: 4px solid #888;
  background: #2d2926;
  color: #fff;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
  font-family: "Montserrat", system-ui, sans-serif;
  font-size: 15px;
  line-height: 1.3;
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 0.25s ease, transform 0.25s ease;
}
.cb-toast.cb-toast-in {
  opacity: 1;
  transform: translateY(0);
}
.cb-toast-pod {
  font-weight: 700;
}
.cb-toast-body {
  opacity: 0.9;
}
.cb-toast-ok {
  border-left-color: #3fb950;
}
.cb-toast-fail {
  border-left-color: #f85149;
}
.cb-toast-info {
  border-left-color: var(--cb-teal);
}

/* ---------------------------------------------------------------------------
   App widget theme overrides for slides (dark theme).
   Structural rules are in cb-widgets.css (loaded before this file).
   --------------------------------------------------------------------------- */

/* Slides are rendered in the reveal.js context; tighten spacing slightly. */
.cb-app {
  margin: 0.75rem 0;
}

.cb-app-btn {
  font-size: 0.9rem;
  padding: 0.4em 1em;
}

.cb-app-status,
.cb-app-value {
  margin-left: 0.6em;
  font-size: 0.85rem;
  color: rgba(255,255,255,0.7);
}

/* Unlock toggle: dark-surface style */
#cb-unlock-toggle {
  border: 1px solid rgba(255,255,255,0.2);
  background: rgba(255,255,255,0.1);
  color: #fff;
  box-shadow: none;
}

/* Unlock form: dark panel */
#cb-unlock-form {
  background: #1e1e1e;
  border-color: rgba(255,255,255,0.15);
  box-shadow: 0 4px 14px rgba(0,0,0,0.3);
}
#cb-unlock-form label {
  color: #fff;
}
#cb-unlock-input {
  border-color: rgba(255,255,255,0.2);
  background: rgba(255,255,255,0.08);
  color: #fff;
}
#cb-unlock-status {
  color: rgba(255,255,255,0.6);
}
