/* stagekit: layout and typography. Reads every colour, font and size from
 * the theme tokens (themes/default.css or the project's theme.css). */

/* Die Codeschrift kommt aus dem Framework selbst, nicht aus dem Netz. Die
   theme.css importiert sie zwar auch von Google Fonts, aber diese Regel steht
   spaeter und gewinnt deshalb; so setzt der Export jede Folie mit derselben
   Schrift, auch wenn acht Chrome-Instanzen gleichzeitig laden. */
@font-face { font-family: "Roboto Mono"; font-style: normal; font-weight: 400; src: url("fonts/RobotoMono-Regular.woff2") format("woff2"); }
* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; background: var(--bg); color: var(--white); font-family: var(--font); overflow: hidden; }
a { color: var(--blue); text-decoration: none; }
/* addresses on slides are links (rule of 29.09.2026): blue, underlined on hover */
.slide a:hover { text-decoration: underline; }

/* --- the stage: one slide visible, scaled to the window --------------------- */
.deck { position: relative; width: 100%; height: 100%; }
.slide {
  position: absolute; left: 50%; top: 50%;
  width: var(--slide-w); height: var(--slide-h);
  transform: translate(-50%, -50%) scale(var(--scale, 1));
  transform-origin: center center;
  background: var(--bg);
  display: none;
  padding: var(--margin);
  text-transform: var(--lowercase);
  font-size: var(--normal);
  line-height: 1.35;
}
.slide.current { display: block; }
/* Code wird nie kleingeschrieben: `True`, `None`, Klassennamen und Bezeichner
 * muessen stehen bleiben, wie sie im Programm stehen. */
.slide pre, .slide code, .slide .code, .slide .keep-case, .slide .keep-case * { text-transform: none; }

/* --- the building blocks --------------------------------------------------- */
.slide h2 {                       /* the small grey heading top left */
  position: absolute; left: var(--margin); top: calc(var(--margin) * 0.55);
  margin: 0; font-size: var(--small); font-weight: normal; color: var(--gray);
}
.content {                        /* one box, vertically centred, left aligned */
  position: absolute; left: var(--margin); right: var(--margin); top: 0; bottom: 0;
  display: flex; flex-direction: column; justify-content: center; align-items: flex-start; gap: 0.5em;
}
.content.center { align-items: center; text-align: center; }
.header { font-size: var(--small); color: var(--gray); }
.statement { font-size: var(--large); line-height: 1.2; color: var(--white); }
.lines { font-size: var(--normal); color: var(--white); }
.lines.mono, .mono { font-family: var(--mono); }
.lines > div, .code > div { min-height: 1.35em; }
.code { font-family: var(--mono); font-size: var(--normal); color: var(--white); white-space: pre; }
.code .kw { color: var(--blue); }
.code .num { color: var(--yellow); }
/* the copy button stagekit.js adds to every code block: to the right of the
 * block, so it never covers a line; grey, white on hover, green once copied */
.slide .code { position: relative; }
.code .copy { position: absolute; top: 0.1em; right: -80px; width: 52px; height: 52px; padding: 10px;
              background: transparent; border: 1px solid var(--gray-dark); border-radius: 10px;
              color: var(--gray); cursor: pointer; line-height: 0; }
.code .copy svg { width: 100%; height: 100%; }
.code .copy:hover { color: var(--white); border-color: var(--gray); }
.code .copy.done { color: var(--green); border-color: var(--green); }
body.print .code .copy { display: none; }
/* what the slide is about inside a code block: the verb, operator or argument
 * that is new on this slide, <span class="hl">...</span>. Blue, because yellow
 * already means "current step" in drawings (rule of 29.09.2026) */
.code .hl { color: var(--blue); }
/* the code behind a figure: <div class="code figcode">...</div> anywhere on the
 * slide. The code stays invisible, only its copy button shows, top right and
 * level with the small heading; hidden in the print view like every copy button */
.slide .code.figcode { position: absolute; top: calc(var(--margin) * 0.45); right: calc(var(--margin) + 80px);
                       width: 0; height: 0; margin: 0; padding: 0; visibility: hidden; }
.code.figcode .copy { visibility: visible; top: 0; }
/* next to it the show-code button (an eye), and the window it opens over the
 * slide: slightly transparent, the code in the small size, a close button */
.code.figcode .show { visibility: visible; position: absolute; top: 0; right: -140px; width: 52px; height: 52px; padding: 10px;
                      background: transparent; border: 1px solid var(--gray-dark); border-radius: 10px;
                      color: var(--gray); cursor: pointer; line-height: 0; }
.code.figcode .show svg, .code-overlay .close svg { width: 100%; height: 100%; }
.code.figcode .show:hover, .code-overlay .close:hover { color: var(--white); border-color: var(--gray); }
.code-overlay { position: absolute; left: var(--margin); right: var(--margin); top: calc(var(--margin) * 1.3);
                bottom: calc(var(--margin) * 1.2); z-index: 5; box-sizing: border-box; padding: 60px 140px 60px 60px;
                display: flex; align-items: center; overflow: auto;
                background: color-mix(in srgb, var(--bg) 95%, transparent);
                border: 1px solid var(--gray-dark); border-radius: 16px; }
.code-overlay .overlay-code { font-family: var(--mono); font-size: var(--small); color: var(--white); white-space: pre; text-transform: none; }
.code-overlay .close { position: absolute; top: 24px; right: 24px; width: 52px; height: 52px; padding: 12px;
                       background: transparent; border: 1px solid var(--gray-dark); border-radius: 10px;
                       color: var(--gray); cursor: pointer; line-height: 0; }
body.print .code .show, body.print .code-overlay { display: none; }
/* the invisible figcode still takes up layout: its code runs past the right edge,
 * the print page grows wider than 1920 px and Chrome shrinks every page to fit */
body.print .slide .code.figcode { display: none; }
.dim { color: var(--gray-dark); }
.sidenote { font-size: var(--small); color: var(--gray); }
.remark { font-size: var(--small); color: var(--yellow); }
.footnote { position: absolute; left: var(--margin); bottom: calc(var(--margin) * 0.55); font-size: var(--tiny); color: var(--gray); }
.footnote.right { left: auto; right: var(--margin); }
/* the punchline: one yellow sentence at the bottom, always the small size, always
 * the same place. A slide that carries one gets .has-punch, which shortens the
 * content area above so the two never touch. The text content area shrinks by
 * the same amount at the top, so a centred block stays in the middle of the
 * slide: the punchline must not move the content (rule of 29.09.2026). */
.punch { position: absolute; left: var(--margin); right: var(--margin); bottom: calc(var(--margin) * 1.05); text-align: center; font-size: var(--small); color: var(--yellow); }
.slide.has-punch .figure, .slide.has-punch .cols3, .slide.has-punch .cols4, .slide.has-punch .two { bottom: calc(var(--margin) * 2.1); }
.slide.has-punch .content { top: calc(var(--margin) * 1.6); bottom: calc(var(--margin) * 1.6); }
.bright { color: var(--white); }
.y { color: var(--yellow); } .b { color: var(--blue); } .g { color: var(--green); } .r { color: var(--red); } .gr { color: var(--gray); }

/* --- title, agenda, section slides ------------------------------------------ */
.slide.title .content { justify-content: center; }
.slide.title .title-text { font-size: var(--large); line-height: 1.15; }
.slide.title .subtitle-text { font-size: var(--small); color: var(--gray); margin-top: 0.8em; }
.slide.agenda .content { gap: 0.15em; }
.slide.agenda .agenda-item { font-size: var(--normal); color: var(--gray-light); }
.slide.agenda .agenda-item .n { display: inline-block; width: 1.6em; color: var(--gray); font-family: var(--mono); }
.slide.part .content { justify-content: center; }
.slide.part .part-text { font-size: var(--large); }
.slide.part .part-n { font-size: var(--small); color: var(--gray); font-family: var(--mono); }

/* --- the location bar: which part are we in -------------------------------- */
.location {
  position: absolute; left: var(--margin); right: var(--margin); bottom: calc(var(--margin) * 0.3);
  display: flex; align-items: center; gap: 24px; font-size: var(--tiny); color: var(--gray);
}
.location .bar { flex: 1; height: 4px; background: var(--gray-dark); position: relative; }
.location .seg { position: absolute; top: -14px; bottom: -14px; cursor: pointer; }
.location .seg:hover { background: rgba(255,255,255,0.06); }
.location .bar .fill { position: absolute; left: 0; top: 0; bottom: 0; background: var(--part-color); }
.location .bar .tick { position: absolute; top: -4px; width: 2px; height: 12px; background: var(--bg); }
.slide.title .location, .slide.agenda .location, .slide.part .location { display: none; }

/* --- steps: build a slide up piece by piece --------------------------------- */
[data-step] { visibility: hidden; }
[data-step].shown { visibility: visible; }
/* a hidden step must not leave its borders behind (collapsed table borders would) */
.slide [data-step]:not(.shown), .slide [data-step]:not(.shown) * { border-color: transparent; }
.slide.no-hold [data-step] { display: none; }
.slide.no-hold [data-step].shown { display: revert; }

/* --- pictures, drawings, embeds ------------------------------------------- */
.slide img.photo { position: absolute; top: 0; right: 0; height: 100%; }
.slide .photo-text { position: absolute; left: var(--margin); top: 0; bottom: 0; width: 45%; display: flex; align-items: center; font-size: var(--large); line-height: 1.15; }
.figure { position: absolute; left: var(--margin); right: var(--margin); top: calc(var(--margin) * 1.4); bottom: calc(var(--margin) * 0.9); display: flex; align-items: center; justify-content: center; }
.figure svg { width: 100%; height: 100%; }     /* viewBox scales to fit, aspect kept */
.figure.left { justify-content: flex-start; }
/* three or four equal columns of cards, top aligned */
.cols3, .cols4 { position: absolute; left: var(--margin); right: var(--margin); top: calc(var(--margin) * 1.4); bottom: calc(var(--margin) * 0.9); display: grid; gap: 60px; align-items: start; }
.cols3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.cols4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.cols3.center, .cols4.center { align-items: center; }
.embed { position: absolute; left: var(--margin); right: var(--margin); top: calc(var(--margin) * 1.3); bottom: calc(var(--margin) * 0.8); }
.embed iframe { width: 100%; height: 100%; border: 1px solid var(--gray-dark); border-radius: 12px; background: var(--bg); }
/* zoomed embeds: a demo page is laid out for a desktop window; on a projector it
 * wants to be larger. .z125 / .z150 scale the frame by 1.25 / 1.5. */
.embed iframe { transform-origin: 0 0; }
.embed.z125 iframe { width: 80%; height: 80%; transform: scale(1.25); }
.embed.z150 iframe { width: 66.667%; height: 66.667%; transform: scale(1.5); }
.two { position: absolute; left: var(--margin); right: var(--margin); top: calc(var(--margin) * 1.4); bottom: calc(var(--margin) * 0.9); display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 80px; align-items: center; }
.two > * { min-width: 0; }

/* --- tables: truth tables, byte rows, aligned equations ---------------------
 * Everything countable is set in the code font. A quiet frame, a header row
 * with a rule beneath, generous columns. .hl highlights a column. */
table.tt { border-collapse: separate; border-spacing: 0; font-family: var(--mono); font-size: var(--small);
           border: 1px solid var(--gray-dark); border-radius: 10px; overflow: hidden; }
table.tt th { font-weight: normal; color: var(--gray); padding: 10px 26px; text-align: center; min-width: 2.4em;
              border-bottom: 1px solid var(--gray-dark); background: #0b0d10; }
table.tt th.sep, table.tt td.sep { border-left: 1px solid var(--gray-dark); }
table.tt td { padding: 6px 26px; text-align: center; color: var(--gray-light); }
table.tt tr + tr td { border-top: 1px solid #14171a; }
table.tt td.on { color: var(--yellow); }
table.tt tr.now td { color: var(--white); background: #14171a; }
table.tt th.hl, table.tt td.hl { background: #16191d; color: var(--yellow); }
table.tt.large { font-size: var(--normal); }
table.tt.large th { padding: 12px 34px; } table.tt.large td { padding: 8px 34px; }

/* a written addition: label, bits, decimal; a rule above the result */
table.sum { border-collapse: collapse; font-family: var(--mono); font-size: var(--normal); color: var(--gray-light); }
table.sum td { padding: 2px 0; white-space: pre; }
table.sum td.lab { color: var(--gray); font-size: var(--small); padding-right: 1.2em; }
table.sum td.bits { letter-spacing: 0.35em; }
table.sum td.dec { color: var(--gray); padding-left: 1.2em; text-align: right; }
table.sum tr.result td { border-top: 2px solid var(--gray-light); padding-top: 8px; color: var(--white); }
table.sum tr.carries td { color: var(--yellow); }   /* same size as the bits: the columns must line up */

/* aligned equations: term, "=", the rest */
table.eq { border-collapse: collapse; font-size: var(--normal); }
table.eq td { padding: 8px 0; vertical-align: baseline; }
table.eq td.term { color: var(--yellow); padding-right: 0.6em; }
table.eq td.eqs { color: var(--gray); padding: 8px 0.6em; }
table.eq td.note { color: var(--gray); font-size: var(--small); padding-left: 1.2em; }

.lines.pre { white-space: pre; }

/* --- notes are never shown on the slide ----------------------------------- */
.notes { display: none; }

/* --- the slide counter, small, bottom right -------------------------------- */
.counter { position: fixed; right: 12px; bottom: 8px; font-family: var(--mono); font-size: 12px; color: var(--gray-dark); z-index: 5; }
.counter.hidden { display: none; }
/* the control bar of an embedded deck (?bar=1): back, counter, forward, full
 * screen. Small and quiet, so the slide keeps the attention. */
.embedbar { position: fixed; right: 12px; top: 12px; z-index: 6; display: flex; align-items: center; gap: 6px;
  background: rgba(0, 0, 0, 0.55); border: 1px solid var(--gray-dark); border-radius: 999px; padding: 4px 10px; }
.embedbar button { background: none; border: 0; color: var(--gray-light); font-size: 18px; line-height: 1;
  cursor: pointer; padding: 4px 8px; border-radius: 999px; }
.embedbar button:hover { color: var(--white); background: rgba(255, 255, 255, 0.08); }
.embedbar button svg { width: 17px; height: 17px; display: block; fill: none; stroke: currentColor;
  stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.embedbar .counter { position: static; min-width: 4.5em; text-align: center; color: var(--gray); }

/* --- cursor modes (key M): laser pointer and hidden cursor ---------------- */
:root[data-cursor="laser"], :root[data-cursor="laser"] *,
:root[data-cursor="hidden"], :root[data-cursor="hidden"] * { cursor: none !important; }
.laser { position: fixed; left: 0; top: 0; z-index: 30; display: none; pointer-events: none;
  width: 22px; height: 22px; margin: -11px 0 0 -11px; border-radius: 50%;
  background: radial-gradient(circle, var(--white) 0 16%, var(--red) 38%, transparent 72%);
  box-shadow: 0 0 18px 6px color-mix(in srgb, var(--red) 55%, transparent); }
:root[data-cursor="laser"] .laser.seen { display: block; }
/* the trail drawn while the button is held; no text selection in laser mode */
.laser-trail { position: fixed; inset: 0; width: 100vw; height: 100vh; z-index: 29; pointer-events: none; }
:root[data-cursor="laser"] body { user-select: none; -webkit-user-select: none; }
.mode-note { position: fixed; left: 50%; bottom: 28px; transform: translateX(-50%); z-index: 30;
  padding: 6px 14px; border-radius: 999px; font: 16px var(--font); color: var(--gray-light);
  background: color-mix(in srgb, var(--bg) 80%, transparent); border: 1px solid var(--gray-dark);
  opacity: 0; transition: opacity 0.2s; pointer-events: none; }
.mode-note.on { opacity: 1; }

/* --- print: every slide on its own page, unscaled ------------------------- */
@media print {
  html, body { overflow: visible; background: var(--bg); }
  .deck { width: auto; height: auto; }
  .slide { display: block; position: relative; left: 0; top: 0; transform: none; page-break-after: always; break-after: page; }
  /* Ohne ?print gibt es keine Klone je Schritt, also muss der Ausdruck alle
     Schritte zeigen, sonst fehlt Inhalt. Mit ?print klont stagekit je Schritt
     eine Seite, und dort entscheidet .shown -- diese Regel wuerde sie
     ueberstimmen und jede Seite im Endzustand zeigen. */
  body:not(.print) .slide [data-step] { visibility: visible; }
  .counter, .laser, .laser-trail, .mode-note { display: none; }
  @page { size: 1920px 1080px; margin: 0; }
}
body.print { overflow: auto; }
body.print .deck { width: auto; height: auto; }
body.print .slide { display: block; position: relative; left: 0; top: 0; transform: none; margin: 0 auto; overflow: hidden; }

/* --- the notes window ------------------------------------------------------ */
body.notes-view { overflow: auto; background: #111; color: var(--gray-light); font-size: 20px; padding: 24px; }
body.notes-view h1 { font-size: 16px; color: var(--gray); font-weight: normal; margin: 0 0 10px; }
body.notes-view .nv-current { font-size: 26px; line-height: 1.5; color: var(--white); margin-bottom: 30px; }
body.notes-view .nv-next { color: var(--gray); }
body.notes-view .nv-next h1 { color: var(--gray-dark); }
body.notes-view .nv-clock { position: fixed; right: 24px; top: 20px; font-family: var(--mono); color: var(--gray); }

/* --- live polls (.slide.poll, built by stagekit.js) --------------------------
 * left: question and options, bars appear on reveal; right: QR code, address,
 * session code, a pulsing red "live" while the question is open, the counter.
 * While open the empty bars shimmer like a page that is still loading. Every
 * element keeps its place in every state, so nothing jumps between steps. */
.slide.poll h2 .icon { width: 1em; height: 1em; vertical-align: -0.12em; margin-right: 16px; color: var(--gray); }
.poll-main { position: absolute; left: var(--margin); top: 190px; width: 1260px; }
.poll-q { font-size: var(--normal); color: var(--white); line-height: 1.25; min-height: 130px; }
.poll-opts { margin-top: 30px; }
.poll-opts .opt { height: 96px; display: grid; grid-template-columns: 640px 1fr 170px; align-items: center; column-gap: 28px;
                  font-size: var(--normal); color: var(--gray-light); }
.poll-opts .track { height: 40px; border-radius: 6px; background: transparent; position: relative; }
.poll-opts .fill { position: absolute; left: 0; top: 0; bottom: 0; width: 0; border-radius: 6px; background: var(--gray-light); }
.poll-opts .pct { font-family: var(--mono); text-align: right; color: var(--gray-light); white-space: nowrap; }
.poll.reveal .poll-opts .track { background: var(--gray-dark); }
.poll.right .poll-opts .opt:not([data-correct]) { color: var(--gray); }
.poll.right .poll-opts .opt:not([data-correct]) .fill { background: var(--gray); }
.poll.right .poll-opts .opt[data-correct], .poll.right .poll-opts .opt[data-correct] .pct { color: var(--green); }
.poll.right .poll-opts .opt[data-correct] .fill { background: var(--green); }
.poll.open .poll-opts .track {
  background: linear-gradient(90deg, var(--gray-dark) 0%, var(--gray-dark) 35%, var(--gray) 50%, var(--gray-dark) 65%, var(--gray-dark) 100%);
  background-size: 300% 100%; animation: poll-shimmer 1.8s linear infinite; opacity: 0.8; }
.poll.open .poll-opts .opt:nth-child(2) .track { animation-delay: 0.15s; }
.poll.open .poll-opts .opt:nth-child(3) .track { animation-delay: 0.3s; }
.poll.open .poll-opts .opt:nth-child(4) .track { animation-delay: 0.45s; }
.poll.open .poll-opts .opt:nth-child(5) .track { animation-delay: 0.6s; }
.poll.open .poll-opts .opt:nth-child(6) .track { animation-delay: 0.75s; }
@keyframes poll-shimmer { from { background-position: 100% 0; } to { background-position: 0% 0; } }
.poll-side { position: absolute; right: var(--margin); top: 190px; width: 340px; text-align: center; }
/* the one fixed colour: a QR code needs a white ground in every theme, or phones cannot read it */
.poll-side .qr { width: 340px; height: 340px; border-radius: 12px; display: block; background: #fff; }
.poll-side .url { font-size: var(--small); color: var(--blue); margin-top: 18px; }
.poll-side .code { font-size: var(--normal); font-family: var(--mono); color: var(--white); margin-top: 10px; text-transform: none; }
.poll-side .live-badge { font-size: var(--normal); color: var(--red); margin-top: 26px; visibility: hidden;
                         display: flex; align-items: center; justify-content: center; gap: 22px; }
.poll.open .poll-side .live-badge { visibility: visible; }
.live-badge .pulse { position: relative; width: 28px; height: 28px; border-radius: 50%; background: var(--red); }
.live-badge .pulse::after { content: ""; position: absolute; inset: 0; border-radius: 50%; border: 4px solid var(--red);
                            animation: live-ring 1.6s ease-out infinite; }
.poll.open .live-badge .pulse { animation: live-dot 1.6s ease-in-out infinite; }
@keyframes live-ring { from { transform: scale(1); opacity: 0.9; } to { transform: scale(2.8); opacity: 0; } }
@keyframes live-dot { 50% { opacity: 0.55; } }
.poll-side .count { font-size: var(--normal); color: var(--white); margin-top: 18px; }
.poll-side .live-state { font-size: var(--tiny); color: var(--gray); margin-top: 8px; }
body.print .poll-side .count, body.print .poll-side .live-state, body.print .poll-side .code,
body.print .poll-side .live-badge { visibility: hidden; }
