@layer elabora.base;
@layer elabora.base {
/* Elabora player — tokens come from the course theme (see index.html :root).
   This file is the cascade layer elabora.base: components (elabora.components) and the course
   stylesheet (elabora.theme) override it. Stable hooks for themes are documented in docs/design.md. */
*, *::before, *::after { box-sizing: border-box; }
/* Motion (the same rules as the Elabora app's design system, after Emil Kowalski's recipes): rare and
   brief, it says where things come from and go, that a press was heard, and links two states instead
   of swapping them; never to decorate. What a learner does a hundred times (changing screens, scrolling)
   does not move. Curves: --t-ease-out for what comes or goes, --t-ease-in-out for what moves on screen,
   --t-ease-drawer for sheets; ease for a fade that must be seen; never ease-in. What leaves goes the way
   it came. Only opacity, translate and scale. Menus open at once and shrink back toward their button;
   popovers, layers and the viewer grow and go back. --t-move multiplies every distance and scale: 0 when
   the learner asks for less motion, so that only the fades stay.
   What comes in with the scroll (animation-timeline: view()) arrives as a revealed step does, over a
   stretch of scroll instead of a time: --t-scroll-in fades it with ease and lifts it by
   --t-scroll-in-distance on --t-ease-out, which slows down to rest, so that the eye never sees it stop
   (never linear, nor a curve that ends at speed). --t-scroll-in-opacity is where the fade starts. */
:root {
  --t-ease-out: cubic-bezier(.23, 1, .32, 1);
  --t-ease-in-out: cubic-bezier(.77, 0, .175, 1);
  --t-ease-drawer: cubic-bezier(.32, .72, 0, 1);
  --t-dur-press: 160ms; --t-dur-tip: 200ms; --t-dur-pop: 200ms; --t-dur-modal: 250ms; --t-dur-drawer: 350ms; --t-dur-reveal: 400ms;
  --t-move: 1;
  --t-scroll-in: t-scroll-in-fade ease both, t-scroll-in-rise var(--t-ease-out) both;
  --t-scroll-in-distance: 1rem; --t-scroll-in-opacity: 0;
}
@keyframes t-scroll-in-fade { from { opacity: var(--t-scroll-in-opacity); } }
@keyframes t-scroll-in-rise { from { translate: 0 calc(var(--t-scroll-in-distance) * var(--t-move)); } }
@media (prefers-reduced-motion: reduce) { :root { --t-move: 0; } }
/* Size classes. Sizes are in rem and 1rem follows the window, so a design keeps its proportions
   from the reference window down to laptops and stays readable on phones (docs/design.md):
   reference ≥ 1500×840 (designed at 1600×900): 1rem = the browser default (16 px);
   medium ≥ 1360×760: 15 px; compact (1280×720 and smaller desktop windows): 14 px;
   phones and portrait tablets: 15 px. Percentages keep the learner's own default size. */
html { font-size: 100%; }
@media (max-width: 1499px), (max-height: 839px) { html { font-size: 93.75%; } }
@media (max-width: 1359px), (max-height: 759px) { html { font-size: 87.5%; } }
@media (max-width: 760px), (orientation: portrait) and (max-width: 1100px) { html { font-size: 93.75%; } }
[hidden] { display: none !important; }
html { -webkit-text-size-adjust: 100%; }
/* No rubber-band bounce, pull-to-refresh or swipe-back at scroll ends, and no scroll chaining from
   the course frame to the LMS page or from a panel to the screen behind it. */
html, body, .t-menu, .t-dialog, .t-sheet-body, .t-text table, .t-math-display, .t-math-body { overscroll-behavior: none; }
body { margin: 0; background: var(--t-surface); color: var(--t-text); font: 1.0625rem/1.55 var(--t-font-body); }
.elabora { min-height: 100vh; display: flex; flex-direction: column; }
#elabora-app { min-height: 100vh; display: flex; flex-direction: column; }
h1, h2, h3, h4 { font-family: var(--t-font-heading); line-height: 1.25; margin: 0 0 .6em; }
/* A custom token font.mono (elabora font add "JetBrains Mono") sets the face of code. */
code, kbd, samp, pre { font-family: var(--t-font-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace); }
a { color: var(--t-primary); }
.t-sr-only { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.t-skip { position: absolute; left: 8px; top: -60px; z-index: 10; padding: 0.5rem 0.75rem; background: var(--t-surface); border: 2px solid var(--t-focus); border-radius: var(--t-radius); }
.t-skip:focus { top: 8px; }
:focus-visible { outline: 3px solid var(--t-focus); outline-offset: 2px; }

.t-banner { position: relative; margin: 0; padding: 0.5rem 1.25rem; background: color-mix(in srgb, var(--t-accent) 12%, var(--t-surface)); font-size: 0.9375rem; }

/* Backdrop (theme.backdrop): fixed behind the course, first in the app, under every positioned part
   of the shell. The theme stylesheet paints its layers: .t-backdrop-layer[data-layer="…"]; it can
   react to .t-backdrop[data-screen|data-section|data-step|data-variant|data-screen-index|
   data-section-index|data-section-count|data-direction], and #elabora-app[data-backdrop] has the
   variant shown. Painted back to front: the layers (z-index 0), then the object (z-index 1); a layer
   that goes over the object (a grain) takes z-index: 2. */
.t-backdrop { position: fixed; inset: 0; z-index: 0; overflow: hidden; pointer-events: none; }
.t-backdrop-layer, .t-backdrop-object { position: absolute; inset: 0; }
.t-backdrop-layer { z-index: 0; }
.t-backdrop-object { z-index: 1; }
.t-backdrop-object iframe { display: block; width: 100%; height: 100%; border: 0; background: transparent; }


.t-main { position: relative; flex: 1; padding: 1.75rem 1.25rem 2.5rem; isolation: isolate; }
.t-main[data-full-bleed] { padding: 0; }
.t-screen { max-width: var(--t-wide-width, 68.75rem); margin: 0 auto; container-type: inline-size; }
.t-main[data-full-bleed] > .t-screen { max-width: none; }
.t-screen-title { font-size: clamp(1.625rem, 3.2vw, 2.125rem); max-width: var(--t-content-width, 47.5rem); margin-left: auto; margin-right: auto; }
/* What the player focuses so that screen readers read it and the keyboard goes on from it (a screen's,
   a panel's or a sheet's heading on every change, a revealed step's first block, the main area:
   tabindex="-1", never a control) draws no ring, whatever a theme says of :focus-visible (important in
   elabora.base outweighs the later layers). Controls keep theirs. */
:is(h1, h2, h3, h4, h5, h6, .t-main, .t-block)[tabindex="-1"]:focus { outline: none !important; }
/* Slides: each screen fills the window and short content is centred vertically. */
[data-presentation="slides"] .t-main { display: flex; flex-direction: column; padding-block: 1.5rem; }
/* Full bleed means edge to edge in both presentations: the layout owns all of its spacing. */
[data-presentation="slides"] .t-main[data-full-bleed] { padding-block: 0; }
[data-presentation="slides"] .t-screen { margin-block: auto; width: 100%; }
.t-screen > .t-sr-only + .t-blocks { margin-top: 0; }
.t-blocks { display: grid; grid-template-columns: 1fr 1fr; gap: 1.25rem 1.5rem; }
.t-block { grid-column: 1 / -1; width: 100%; max-width: var(--t-content-width, 47.5rem); justify-self: center; min-width: 0; }
.t-block[hidden] { display: none; }
/* Steps (block step): a pending step takes no room in scroll presentation and keeps its place in
   slides; revealed blocks fade in. A slot whose blocks are all pending is hidden the same way. */
#elabora-app:not([data-presentation="slides"]) .t-block[data-t-pending],
#elabora-app:not([data-presentation="slides"]) .t-slot:has(> .t-block):not(:has(> .t-block:not([data-t-pending]))) { display: none; }
/* Blocks concealed by events (hidden, show-block) take no room in scroll presentation and keep
   their place in slides, like pending steps: showing them never moves the slide. */
#elabora-app:not([data-presentation="slides"]) .t-block[data-t-concealed] { display: none; }
[data-presentation="slides"] .t-block[data-t-concealed] { visibility: hidden; }
dialog .t-block[data-t-concealed] { display: none; } /* layers scroll inside: no place to keep */
[data-presentation="slides"] .t-block[data-t-pending],
[data-presentation="slides"] .t-slot:has(> .t-block):not(:has(> .t-block:not([data-t-pending]))) { visibility: hidden; opacity: 0; }
.t-block[data-t-revealed] { transition: opacity var(--t-dur-reveal) ease, translate var(--t-dur-reveal) var(--t-ease-out); }
/* Timed blocks (D28): before they come and after they go, hidden in their place (nothing moves). */
/* The editor's phone width: the steps after the first, faded in their place (canvas view ghost). */
.t-block[data-t-ghost] { opacity: .42; }
.t-block[data-t-timed] { visibility: hidden; }
/* A stack: its contents share one cell, the size of the largest, wherever it is shown (the player,
   the editor's canvas, a capture, a phone), so that the one coming does not move what is around it.
   (A stack is also a slot, which is a flex column: the grid has to outweigh it.) */
.t-stack.t-slot { display: grid; gap: 0; }
.t-stack.t-slot > .t-block { grid-area: 1 / 1; min-width: 0; }
@starting-style { .t-block[data-t-revealed] { opacity: 0; translate: 0 calc(.5rem * var(--t-move)); } }
.t-block { scroll-margin-block: calc(var(--t-bar-top, 0px) + 1.25rem) calc(var(--t-bar-bottom, 0px) + 1.25rem); }
/* Continue in the page (scroll presentation): where the shown content ends, it opens the next step. */
.t-continue { grid-column: 1 / -1; display: flex; flex-direction: column; align-items: center; gap: 0.5rem; width: 100%; max-width: var(--t-content-width, 47.5rem); justify-self: center; margin: 0.5rem auto; }
.t-continue-btn { min-width: 12rem; }
.t-continue-btn[aria-disabled="true"] { opacity: .55; cursor: not-allowed; }
.t-w-wide { max-width: none; }
.t-w-half { grid-column: span 1; max-width: none; }
@media (max-width: 760px) { .t-w-half { grid-column: 1 / -1; } .t-main { padding: 1.25rem 0.875rem 2rem; } }

/* Layouts: the template places the slots; inside a slot, blocks stack and fill its width. */
.t-layout { position: relative; }
.t-slot { display: flex; flex-direction: column; gap: 1.25rem; min-width: 0; }
.t-slot > .t-block { max-width: none; justify-self: stretch; grid-column: auto; }
.t-slot[data-empty] { display: none; }
.t-layout .t-screen-title { max-width: none; margin-left: 0; margin-right: 0; }

.t-text > :first-child { margin-top: 0; }
.t-text table { border-collapse: collapse; width: 100%; margin: 0.75rem 0; font-size: .95em; display: block; overflow-x: auto; }
.t-text th, .t-text td { padding: 0.4375rem 0.75rem; text-align: left; border-bottom: 1px solid color-mix(in srgb, var(--t-text) 14%, transparent); }
.t-text thead th { font-weight: 700; border-bottom: 2px solid color-mix(in srgb, var(--t-text) 30%, transparent); }
.t-text tbody tr:nth-child(even) { background: color-mix(in srgb, var(--t-primary) 4%, transparent); }

/* Maths: MathML rendered at build time. Long equations scroll inside their block on phones. */
/* Inline maths stays on the line of the punctuation around it: "($T$)", "$T$,". */
.t-nobr { white-space: nowrap; }
math { font-family: "STIX Two Math", "Cambria Math", "Latin Modern Math", math; font-size: 1.1em; }
.t-math-display, .t-math-body { overflow-x: auto; overflow-y: hidden; padding: 0.25rem 0; }
.t-math-display math, .t-math-body math { font-size: 1.25em; }
.t-math { margin: 0; }
.t-math-row { display: flex; align-items: center; gap: 1rem; }
.t-math-body { flex: 1; text-align: center; }
.t-math-label { color: var(--t-muted); font-variant-numeric: tabular-nums; }
.t-math figcaption { margin-top: 0.375rem; color: var(--t-muted); font-size: 0.9375rem; text-align: center; }
.t-text > :last-child { margin-bottom: 0; }
.t-figure { margin: 0; }
.t-figure img, .t-figure video, .t-figure .t-figure-svg { display: block; max-width: 100%; height: auto; border-radius: var(--t-radius); }
.t-figure figcaption { margin-top: 0.375rem; color: var(--t-muted); font-size: 0.9375rem; }
.t-genmark { margin: 0.25rem 0 0; font-size: 0.8125rem; color: var(--t-muted); }
/* A looping video, like an animated image: its pause button in a corner (WCAG 2.2.2). */
.t-loop-frame { position: relative; width: fit-content; max-width: 100%; }
.t-loop-toggle { position: absolute; right: 0.5rem; bottom: 0.5rem; width: 2rem; height: 2rem; border: 0; border-radius: 999px; background: rgb(0 0 0 / 0.55); color: #fff; cursor: pointer; display: grid; place-items: center; padding: 0; }
.t-loop-toggle::before { content: ''; width: 0.625rem; height: 0.75rem; box-sizing: border-box; border-left: 0.1875rem solid currentColor; border-right: 0.1875rem solid currentColor; }
.t-loop-toggle[data-state='paused']::before { width: 0; height: 0; border-style: solid; border-width: 0.375rem 0 0.375rem 0.625rem; border-color: transparent transparent transparent currentColor; margin-left: 0.125rem; }
.t-loop-toggle:focus-visible { outline: 2px solid #fff; outline-offset: 2px; box-shadow: 0 0 0 4px rgb(0 0 0 / 0.6); }
.t-transcript, .t-text-alt { margin-top: 0.5rem; }
summary { cursor: pointer; min-height: 32px; padding: 0.25rem 0; font-weight: 600; }

/* A callout is a tinted card: its tone says its kind (no coloured rule down its side, a mark of
   generic interfaces). A hairline of the same tone holds it on a tinted page. */
.t-callout { --t-callout-tone: var(--t-primary); margin: 0; padding: 0.875rem 1.125rem; border-radius: var(--t-radius); background: color-mix(in srgb, var(--t-callout-tone) 8%, var(--t-surface)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--t-callout-tone) 14%, transparent); }
.t-callout--important { --t-callout-tone: var(--t-accent); }
.t-callout--warning { --t-callout-tone: var(--t-error); }
.t-callout--tip { --t-callout-tone: var(--t-success); }
.t-callout-title { margin: 0 0 0.25rem; font-weight: 700; }

.t-accordion details { border: 1px solid color-mix(in srgb, var(--t-text) 16%, transparent); border-radius: var(--t-radius); padding: 0.375rem 0.875rem; margin-bottom: 0.5rem; }
.t-accordion details[open] { padding-bottom: 0.75rem; }

.t-btn { display: inline-flex; align-items: center; justify-content: center; min-height: 44px; min-width: 44px; padding: 0 1.125rem; border-radius: var(--t-radius); border: 2px solid var(--t-primary); font: inherit; font-weight: 600; cursor: pointer; }
.t-btn--primary { background: var(--t-primary); color: var(--t-on-primary); }
.t-btn--secondary { background: var(--t-surface); color: var(--t-primary); }
/* A button pressed gives a little under the finger: the press is heard. */
:is(.t-btn, .t-nav-btn, .t-bar-btn, .t-icon-btn, .t-timeline-btn, .t-chip):not(:disabled):not([aria-disabled="true"]) { transition: scale var(--t-dur-press) var(--t-ease-out); }
:is(.t-btn, .t-nav-btn, .t-bar-btn, .t-icon-btn, .t-timeline-btn, .t-chip):not(:disabled):not([aria-disabled="true"]):active { scale: calc(1 - .03 * var(--t-move)); }
.t-btn[aria-disabled="true"] { opacity: .55; cursor: not-allowed; }

.t-quiz { border: 1px solid color-mix(in srgb, var(--t-text) 16%, transparent); border-radius: var(--t-radius); padding: 1.125rem; margin: 0; }
.t-quiz-stem { font-weight: 600; margin-bottom: 0.75rem; }
.t-options { display: grid; gap: 0.5rem; margin-bottom: 0.875rem; }
.t-option { display: flex; gap: 0.625rem; align-items: flex-start; min-height: 44px; padding: 0.625rem 0.75rem; border: 1px solid color-mix(in srgb, var(--t-text) 18%, transparent); border-radius: var(--t-radius); cursor: pointer; }
.t-option input { width: 20px; height: 20px; margin: 0.125rem 0 0; flex: none; accent-color: var(--t-primary); }
.t-option.is-correct { border-color: var(--t-success); background: color-mix(in srgb, var(--t-success) 8%, var(--t-surface)); }
.t-option.is-wrong { border-color: var(--t-error); background: color-mix(in srgb, var(--t-error) 6%, var(--t-surface)); }
.t-option-flag { font-weight: 600; color: var(--t-success); }
.t-feedback { margin-top: 0.75rem; }
.t-feedback:empty { display: none; }
.t-feedback-head { font-weight: 700; margin: 0 0 0.375rem; }
.t-feedback-head.is-correct { color: var(--t-success); }
.t-feedback-head.is-wrong { color: var(--t-error); }
.t-feedback-item { margin: 0.375rem 0; }
/* Compact feedback (quiz feedbackStyle): the result and the explanation in one paragraph, the chosen
   option's text read to screen readers only (it is marked where it is). */
[data-t-feedback-style="compact"] .t-feedback > :is(.t-feedback-head, .t-feedback-item) { display: inline; margin: 0; }
[data-t-feedback-style="compact"] .t-feedback > .t-feedback-head::after { content: " "; }

/* Numeric answer */
.t-numeric-row { display: flex; flex-wrap: wrap; align-items: center; gap: 0.625rem 0.75rem; margin: 0.25rem 0 0.125rem; }
.t-numeric-label { font-weight: 600; }
.t-numeric-field { display: inline-flex; align-items: center; gap: 0.5rem; }
/* Never under 16 px in a text field: iOS would zoom the page on focus. */
.t-numeric-input { width: 9em; min-height: 44px; padding: 0 0.75rem; border-radius: var(--t-radius); border: 2px solid color-mix(in srgb, var(--t-text) 30%, transparent); background: var(--t-surface); color: var(--t-text); font: inherit; font-size: max(1em, 16px); font-variant-numeric: tabular-nums; text-align: right; }
.t-numeric-input.is-correct { border-color: var(--t-success); }
.t-numeric-input.is-wrong { border-color: var(--t-error); }
.t-numeric-unit { color: var(--t-muted); font-weight: 600; }
.t-numeric-expected { margin: 0.375rem 0 0; }
.t-numeric .t-quiz-submit { margin: 0; }

/* Activities of D63 (fill-in, sort, reflection) and the quiz on pictures: the quiz's frame, fields
   and feedback. What the learner moves goes in 220 ms on the ease-out curve, without spring; under
   less motion, nothing in #t-main moves (the rule at the end of this file). Marks are said and drawn,
   never colour alone. */
.t-feedback-count { margin: 0 0 0.375rem; color: var(--t-muted); font-weight: 600; }

/* Quiz: picture cards (images) and zones on a picture (image). */
.t-options--images { grid-template-columns: repeat(auto-fill, minmax(min(100%, 8.5rem), 1fr)); }
.t-option--image { flex-direction: column; gap: 0.5rem; padding: 0.5rem; }
.t-option-image { display: block; width: 100%; aspect-ratio: 4 / 3; object-fit: cover; border-radius: calc(var(--t-radius) * .75); background: color-mix(in srgb, var(--t-text) 5%, var(--t-surface)); }
.t-option-row { display: flex; gap: 0.625rem; align-items: flex-start; padding: 0 0.25rem 0.25rem; }
.t-option--image.is-selected { border-color: var(--t-primary); box-shadow: inset 0 0 0 1px var(--t-primary); }
.t-option:has(input:focus-visible) { outline: 3px solid var(--t-focus); outline-offset: 2px; }
.t-quiz-picture { position: relative; margin-bottom: 0.875rem; }
.t-quiz-picture-image { display: block; width: 100%; height: auto; border-radius: var(--t-radius); }
.t-options--zones { position: absolute; inset: 0; display: block; margin: 0; pointer-events: none; }
.t-zone { position: absolute; left: calc(var(--x, 0.5) * 100%); top: calc(var(--y, 0.5) * 100%); translate: -50% -50%; display: block; width: 44px; height: 44px; min-height: 0; padding: 0; border: 0; border-radius: 50%; background: none; pointer-events: auto; }
.t-zone input { position: absolute; inset: 0; width: 44px; height: 44px; margin: 0; opacity: 0; cursor: pointer; }
.t-zone-number { display: grid; place-items: center; flex: none; width: 44px; height: 44px; border-radius: 50%; border: 3px solid var(--t-surface); background: var(--t-primary); color: var(--t-on-primary); font-weight: 700; font-variant-numeric: tabular-nums; box-shadow: 0 1px 6px rgb(15 23 42 / .35); transition: scale var(--t-dur-place, 220ms) var(--t-ease-out), background var(--t-dur-place, 220ms) var(--t-ease-out); }
.t-zone.is-selected .t-zone-number { background: var(--t-surface); color: var(--t-primary); border-color: var(--t-primary); scale: calc(1 + .08 * var(--t-move)); }
.t-zone:has(input:focus-visible) { outline: none; }
.t-zone:has(input:focus-visible) .t-zone-number { outline: 3px solid var(--t-focus); outline-offset: 2px; }
.t-zone.is-correct .t-zone-number { background: var(--t-success); color: var(--t-surface); border-color: var(--t-surface); }
.t-zone.is-wrong .t-zone-number { background: var(--t-error); color: var(--t-surface); border-color: var(--t-surface); }
/* The zones' words stay hidden until the answer is final: they would give it away. */
.t-zone-text { display: none; }
/* Under its marker, leaning toward the middle of the picture so that it stays on it near an edge. */
[data-t-final] .t-zone-text { display: block; position: absolute; top: calc(100% + 4px); left: 50%; translate: calc(var(--x, 0.5) * -100%) 0; width: max-content; max-width: 12rem; text-align: center; padding: 0.125rem 0.5rem; border-radius: calc(var(--t-radius) * .75); background: var(--t-surface); color: var(--t-text); font-size: 0.875rem; font-weight: 600; box-shadow: 0 1px 4px rgb(15 23 42 / .25); }
.t-zone .t-option-flag { display: none; }
/* The words under a zone near the bottom edge keep clear of the feedback. */
[data-t-final] .t-quiz-picture { margin-bottom: 2.25rem; }

/* Fill-in: a field, a list or a slot in the sentence; the words to place under it. */
.t-fillin-text { line-height: 2.4; margin-bottom: 0.875rem; }
.t-blank { display: inline-flex; align-items: baseline; gap: 0.25rem; vertical-align: baseline; }
.t-blank-input, .t-blank-select, .t-blank-slot { min-height: 40px; padding: 0 0.5rem; border-radius: calc(var(--t-radius) * .75); border: 2px solid color-mix(in srgb, var(--t-text) 30%, transparent); background: var(--t-surface); color: var(--t-text); font: inherit; font-size: max(1em, 16px); line-height: 1.3; vertical-align: baseline; transition: border-color var(--t-dur-place, 220ms) var(--t-ease-out), background var(--t-dur-place, 220ms) var(--t-ease-out); }
.t-blank-input { max-width: 100%; }
.t-blank-select { padding-inline-end: 0.25rem; cursor: pointer; }
.t-blank-slot { border-style: dashed; cursor: pointer; font-weight: 600; text-align: center; }
/* An empty slot keeps the line's height (an empty inline box would sit on its bottom edge). */
.t-blank-slot:empty::before { content: "\200b"; }
.t-blank.is-filled .t-blank-slot { border-style: solid; border-color: var(--t-primary); background: color-mix(in srgb, var(--t-primary) 8%, var(--t-surface)); }
.t-blank.is-over .t-blank-slot { border-color: var(--t-primary); background: color-mix(in srgb, var(--t-primary) 14%, var(--t-surface)); }
.t-blank.is-correct :is(.t-blank-input, .t-blank-select, .t-blank-slot) { border-style: solid; border-color: var(--t-success); background: color-mix(in srgb, var(--t-success) 8%, var(--t-surface)); }
.t-blank.is-wrong :is(.t-blank-input, .t-blank-select, .t-blank-slot) { border-style: solid; border-color: var(--t-error); background: color-mix(in srgb, var(--t-error) 6%, var(--t-surface)); }
.t-blank.is-correct::after { content: "✓" / ""; color: var(--t-success); font-weight: 700; }
.t-blank.is-wrong::after { content: "✗" / ""; color: var(--t-error); font-weight: 700; }
.t-blank-answer { order: 1; color: var(--t-success); font-weight: 700; }
.t-blank-answer::before { content: "→ " / ""; color: var(--t-muted); font-weight: 400; }
:is(.t-blank-input, .t-blank-select, .t-blank-slot):disabled, .t-blank-input:read-only { cursor: default; opacity: 1; }
.t-bank { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0 0 0.875rem; padding: 0.75rem; border-radius: var(--t-radius); background: color-mix(in srgb, var(--t-text) 4%, var(--t-surface)); }
.t-word { min-height: 44px; padding: 0 0.875rem; border-radius: 999px; border: 2px solid color-mix(in srgb, var(--t-primary) 45%, var(--t-surface)); background: var(--t-surface); color: var(--t-text); font: inherit; font-weight: 600; cursor: pointer; transition: border-color var(--t-dur-place, 220ms) var(--t-ease-out), background var(--t-dur-place, 220ms) var(--t-ease-out), translate var(--t-dur-place, 220ms) var(--t-ease-out), opacity var(--t-dur-place, 220ms) var(--t-ease-out); }
.t-word[aria-pressed="true"] { border-color: var(--t-primary); background: color-mix(in srgb, var(--t-primary) 14%, var(--t-surface)); translate: 0 calc(-2px * var(--t-move)); }
/* A word placed keeps its place, empty: nothing moves in the bank. */
.t-word.is-used { visibility: hidden; opacity: 0; }
.t-word:disabled { cursor: default; }

/* Sort: the items to place, then the targets (pairs and categories), or the items in order. */
.t-sort-board { display: grid; gap: 0.875rem; margin-bottom: 0.875rem; }
.t-sort-pool { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 0.5rem; min-height: 44px; padding: 0.75rem; border-radius: var(--t-radius); background: color-mix(in srgb, var(--t-text) 4%, var(--t-surface)); }
.t-sort-pool.is-over { background: color-mix(in srgb, var(--t-primary) 8%, var(--t-surface)); }
.t-sort-item { display: inline-flex; flex-direction: column; align-items: flex-start; gap: 0.375rem; min-height: 44px; max-width: 100%; padding: 0.5rem 0.875rem; border-radius: var(--t-radius); border: 2px solid color-mix(in srgb, var(--t-primary) 40%, var(--t-surface)); background: var(--t-surface); color: var(--t-text); font: inherit; text-align: start; cursor: pointer; transition: border-color var(--t-dur-place, 220ms) var(--t-ease-out), background var(--t-dur-place, 220ms) var(--t-ease-out), translate var(--t-dur-place, 220ms) var(--t-ease-out), box-shadow var(--t-dur-place, 220ms) var(--t-ease-out); }
.t-sort-item[aria-pressed="true"] { border-color: var(--t-primary); background: color-mix(in srgb, var(--t-primary) 12%, var(--t-surface)); box-shadow: 0 4px 14px rgb(15 23 42 / .14); translate: 0 calc(-2px * var(--t-move)); }
.t-sort-item.is-dragging { opacity: .5; }
.t-sort-item:disabled { cursor: default; }
.t-sort-item.is-correct { border-color: var(--t-success); background: color-mix(in srgb, var(--t-success) 8%, var(--t-surface)); }
.t-sort-item.is-wrong { border-color: var(--t-error); background: color-mix(in srgb, var(--t-error) 6%, var(--t-surface)); }
.t-sort-item.is-correct > .t-sort-text::after { content: " ✓" / ""; color: var(--t-success); font-weight: 700; }
.t-sort-item.is-wrong > .t-sort-text::after { content: " ✗" / ""; color: var(--t-error); font-weight: 700; }
.t-sort-image { display: block; width: 7.5rem; max-width: 100%; aspect-ratio: 4 / 3; object-fit: cover; border-radius: calc(var(--t-radius) * .75); }
.t-sort-belongs { font-size: 0.875rem; font-weight: 600; color: var(--t-success); }
/* The place an item left keeps its room. */
.t-sort-ghost { visibility: hidden; }
/* On a page that scrolls, nothing needs keeping still: the items to place close up. */
#elabora-app:not([data-presentation="slides"]) .t-sort-ghost { display: none; }
.t-sort-targets { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr)); gap: 0.75rem; }
.t-sort--pairs .t-sort-targets { grid-template-columns: 1fr; }
.t-sort-target { display: flex; flex-direction: column; gap: 0.5rem; padding: 0.5rem; border-radius: var(--t-radius); border: 2px dashed color-mix(in srgb, var(--t-text) 22%, transparent); transition: border-color var(--t-dur-place, 220ms) var(--t-ease-out), background var(--t-dur-place, 220ms) var(--t-ease-out); }
.t-sort--pairs .t-sort-target { flex-direction: row; flex-wrap: wrap; align-items: center; }
.t-sort-target.is-over { border-color: var(--t-primary); background: color-mix(in srgb, var(--t-primary) 6%, var(--t-surface)); }
.t-sort-place { display: flex; flex-direction: column; align-items: flex-start; gap: 0.375rem; min-height: 44px; padding: 0.5rem 0.75rem; border: 0; border-radius: calc(var(--t-radius) * .75); background: color-mix(in srgb, var(--t-primary) 8%, var(--t-surface)); color: var(--t-text); font: inherit; font-weight: 700; text-align: start; cursor: pointer; }
.t-sort--pairs .t-sort-place { flex: 1 1 12rem; }
.t-sort-place:disabled { cursor: default; }
.t-sort-zone { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 0.5rem; min-height: 44px; }
.t-sort--pairs .t-sort-zone { flex: 1 1 12rem; }
.t-sort--order .t-sort-pool { flex-direction: column; flex-wrap: nowrap; align-items: stretch; counter-reset: t-sort; }
.t-sort-row { display: flex; align-items: center; gap: 0.5rem; counter-increment: t-sort; }
.t-sort-row::before { content: counter(t-sort) / ""; min-width: 1.5rem; color: var(--t-muted); font-weight: 700; font-variant-numeric: tabular-nums; text-align: end; }
.t-sort-row > .t-sort-item { flex: 1; }
.t-sort-moves { display: flex; gap: 0.25rem; }
.t-sort-move { display: grid; place-items: center; width: 44px; height: 44px; padding: 0; border-radius: calc(var(--t-radius) * .75); border: 1px solid color-mix(in srgb, var(--t-text) 18%, transparent); background: var(--t-surface); color: var(--t-text); cursor: pointer; }
.t-sort-move .t-icon svg { width: 20px; height: 20px; }
.t-sort-move[aria-disabled="true"], .t-sort-move:disabled { opacity: .4; cursor: default; }
/* On a phone the move buttons stand one above the other: the item keeps the width. */
@media (max-width: 560px) { .t-sort-moves { flex-direction: column; } }

/* Reflection: the field and its count, or a scale; then the expert's answer once saved. */
.t-reflection-input { display: block; width: 100%; padding: 0.625rem 0.75rem; border-radius: var(--t-radius); border: 2px solid color-mix(in srgb, var(--t-text) 30%, transparent); background: var(--t-surface); color: var(--t-text); font: inherit; font-size: max(1em, 16px); line-height: 1.5; resize: vertical; }
.t-reflection-count { margin: 0.25rem 0 0.75rem; color: var(--t-muted); font-size: 0.875rem; font-variant-numeric: tabular-nums; text-align: end; }
.t-scale { margin-bottom: 0.875rem; }
.t-scale-points { display: flex; gap: 0.375rem; }
.t-scale-point { position: relative; flex: 1; display: grid; place-items: center; min-width: 44px; min-height: 44px; border-radius: calc(var(--t-radius) * .75); border: 2px solid color-mix(in srgb, var(--t-primary) 40%, var(--t-surface)); font-weight: 700; font-variant-numeric: tabular-nums; cursor: pointer; transition: border-color var(--t-dur-place, 220ms) var(--t-ease-out), background var(--t-dur-place, 220ms) var(--t-ease-out); }
.t-scale-input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.t-scale-point:has(input:checked) { border-color: var(--t-primary); background: var(--t-primary); color: var(--t-on-primary); }
.t-scale-point:has(input:focus-visible) { outline: 3px solid var(--t-focus); outline-offset: 2px; }
.t-scale-ends { display: flex; justify-content: space-between; gap: 1rem; margin-top: 0.375rem; color: var(--t-muted); font-size: 0.875rem; }
.t-scale-end--max { text-align: end; }
.t-reflection-model { margin-top: 0.75rem; padding: 0.75rem 1rem; border-radius: var(--t-radius); background: color-mix(in srgb, var(--t-primary) 6%, var(--t-surface)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--t-primary) 12%, transparent); }
.t-reflection-model-head { margin: 0 0 0.375rem; font-weight: 700; }
.t-reflection-download { gap: 0.5rem; margin-top: 0.75rem; }
.t-reflection-download .t-icon svg { width: 20px; height: 20px; }
.t-reflection-response + .t-quiz-submit, .t-fillin-text + .t-quiz-submit, .t-bank + .t-quiz-submit { margin-top: 0; }

.t-decision-prompt { margin-bottom: 0.75rem; }
.t-choices { display: grid; gap: 0.625rem; }
.t-choice { text-align: left; min-height: 48px; padding: 0.75rem 1rem; border-radius: var(--t-radius); border: 2px solid color-mix(in srgb, var(--t-primary) 40%, var(--t-surface)); background: var(--t-surface); color: var(--t-text); font: inherit; cursor: pointer; }
.t-choice[aria-pressed="true"] { border-color: var(--t-primary); background: color-mix(in srgb, var(--t-primary) 10%, var(--t-surface)); font-weight: 600; }
.t-choice[aria-disabled="true"] { opacity: .6; cursor: not-allowed; }

.t-object { margin: 0; }
.t-object-frame { position: relative; width: 100%; border-radius: var(--t-radius); overflow: hidden; border: 1px solid color-mix(in srgb, var(--t-text) 14%, transparent); background: var(--t-surface); transition: height var(--t-dur-pop) var(--t-ease-out); }
/* Loading indicator, shown when an object takes more than a moment to start (machines without a GPU). */
.t-object-loading { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0.75rem; color: var(--t-muted); font-size: 0.9375rem; pointer-events: none; animation: t-fade-in var(--t-dur-pop) ease both; }
.t-object-loading[hidden] { display: none; }
.t-object-safe { position: absolute; inset: 0; visibility: hidden; pointer-events: none; padding: var(--t-safe-top, 0) var(--t-safe-right, 0) var(--t-safe-bottom, 0) var(--t-safe-left, 0); }
.t-object-spinner { width: 2rem; height: 2rem; border-radius: 50%; border: 3px solid color-mix(in srgb, var(--t-primary) 22%, transparent); border-top-color: var(--t-primary); animation: t-spin .9s linear infinite; }
@keyframes t-spin { to { rotate: 360deg; } }
@keyframes t-fade-in { from { opacity: 0; } }
.t-slot > .t-block--free-object { flex: 1; display: flex; flex-direction: column; }
.t-slot > .t-block--free-object > .t-object { flex: 1; display: flex; flex-direction: column; }
/* fill: the frame takes the height its slot gives it (flex); the iframe is placed in it, since a
   percentage height would not resolve against a flexed height. */
.t-object-frame[data-ratio="fill"] { flex: 1; position: relative; }
.t-object-frame[data-ratio="fill"] iframe { position: absolute; inset: 0; }
.t-object-frame iframe { display: block; width: 100%; height: 100%; border: 0; }
.t-object-error { color: var(--t-error); font-weight: 600; }
/* Continuity between screens (D65): the frame of a free object that carries on from screen to screen
   lives in the keep layer of #t-main, over its block's frame (placed by screen-objects.ts). The layer is
   not a stacking context: the frame is drawn above what the layout draws without a z-index, below what
   it places over the block with one. The block's frame keeps the size and lends its look; its
   ancestors up to the screen let clicks through, their other children keep their own behaviour. */
.t-keep { position: absolute; inset: 0; pointer-events: none; }
.t-keep-frame { position: absolute; overflow: hidden; pointer-events: auto; }
.t-keep-frame > iframe { position: absolute; inset: 0; display: block; width: 100%; height: 100%; border: 0; }
.t-object-frame--kept { background: none !important; border-color: transparent !important; box-shadow: none !important; }
.t-keep-path { pointer-events: none !important; }
:where(.t-keep-path) > :where(:not(.t-keep-path)) { pointer-events: auto; }

.t-results { padding: 1.125rem 1.25rem; border-radius: var(--t-radius); background: color-mix(in srgb, var(--t-primary) 6%, var(--t-surface)); }
.t-score, .t-status { margin: 0 0 0.5rem; font-size: 1.1875rem; }
.t-status--passed strong, .t-status--completed strong { color: var(--t-success); }
.t-status--failed strong { color: var(--t-error); }

/* ── Starter blocks for scroll courses (docs/decisions.md D63) ─────────────────────────────────
   Calm and editorial by default, every colour, font and corner from the theme's tokens. What a
   theme tunes without overriding: --t-scrim and --t-on-scrim (the veil under text over a picture
   and that text's colour), --t-ornament and --t-ornament-color (the divider's drawing), --t-band-short,
   --t-band-medium, --t-band-tall (the heights of bands), --t-aside-width (the margin note). */

/* Edge to edge (block width bleed, a template's data-t-bleed): as wide as the screen's area (#t-main,
   without the window's scrollbar: --t-page-width, measured by the player), whatever the reading
   column. In a layout's slot, the slot's width. What is inside keeps the reading width (--t-bleed-gutter
   for templates). #t-main clips the rest, so that a rounding never makes the page scroll sideways. */
.t-main { overflow-x: clip; }
/* The page's side margin, as #t-main pads the default column. */
:root { --t-gutter: 1.25rem; }
/* The veil under text over a picture when the theme sets none (--t-scrim): lighter at the top. On a
   phone the text is smaller (it needs 4.5:1, not the 3:1 of large text) and its lines climb into the
   light part: an evener, darker veil. */
:root { --t-scrim-default: linear-gradient(to top, rgb(10 13 18 / .78), rgb(10 13 18 / .52) 55%, rgb(10 13 18 / .46)); }
@media (max-width: 760px) { :root { --t-gutter: 0.875rem; --t-scrim-default: linear-gradient(to top, rgb(10 13 18 / .8), rgb(10 13 18 / .64)); } }
.t-w-bleed { --t-bleed-gutter: max(var(--t-gutter), calc((100% - var(--t-content-width, 47.5rem)) / 2)); }
:is(.t-screen > .t-blocks, .t-opening-body.t-slot) > .t-block.t-w-bleed { max-width: none; width: auto; justify-self: stretch; margin-inline: calc((100% - var(--t-page-width, 100vw)) / 2); }
.t-slot > .t-block.t-w-bleed { margin-inline: 0; }
/* A band breathes: a little more room around it than between paragraphs. */
:is(.t-screen > .t-blocks, .t-opening-body.t-slot) > .t-block.t-w-bleed:not(:first-child) { margin-top: .75rem; }
:is(.t-screen > .t-blocks, .t-opening-body.t-slot) > .t-block.t-w-bleed:not(:last-child) { margin-bottom: .75rem; }
.t-w-bleed:not(:has(> [data-t-bleed])) > :not(.t-figure) { max-width: var(--t-content-width, 47.5rem); margin-inline: auto; padding-inline: var(--t-gutter); box-sizing: content-box; }
.t-w-bleed > .t-figure img { width: 100%; border-radius: 0; }
/* A picture cropped to its place keeps its focal point (focus: --focus-x, --focus-y, 0 to 1). */
:is(.t-image, .t-gallery, .t-statement, .t-opening) img { object-position: calc(var(--focus-x, .5) * 100%) calc(var(--focus-y, .5) * 100%); }
/* Wider than the text: a wide image, an image beside its text, a gallery, three columns. */
:is(.t-screen > .t-blocks, .t-opening-body.t-slot) > .t-block:is(:has(> .t-image--wide, > .t-image--beside, > .t-gallery:not(.t-gallery--compare), > .t-columns--3)) { max-width: var(--t-wide-width, 68.75rem); }
.t-block--image, .t-block--gallery, .t-block--columns { container-type: inline-size; }
:root { --t-band-short: clamp(11rem, 24vw, 17rem); --t-band-medium: clamp(15rem, 34vw, 26rem); --t-band-tall: clamp(20rem, 50vw, 38rem); }
[data-presentation="slides"] { --t-band-short: min(clamp(11rem, 24vw, 17rem), 26vh); --t-band-medium: min(clamp(15rem, 34vw, 26rem), 40vh); --t-band-tall: min(clamp(20rem, 50vw, 38rem), 58vh); }

/* Statement (« Énoncé »): the idea to keep, set large in the heading font; its key words in the
   course's colour. */
.t-statement { --t-statement-size: clamp(1.5rem, 1.05rem + 1.35vw, 2.125rem); position: relative; margin: 0; padding: 1.75rem 0; text-align: center; }
.t-statement--start { text-align: start; }
.t-statement-quote { margin: 0; }
.t-statement-text { margin: 0 auto; max-width: 34em; font: 600 var(--t-statement-size)/1.28 var(--t-font-heading); letter-spacing: -0.012em; color: var(--t-text); text-wrap: balance; }
.t-statement--start .t-statement-text { margin-inline: 0; }
.t-statement-text > :is(p, ul, ol) { margin: 0; }
.t-statement-text > * + * { margin-top: .55em; }
.t-statement-text strong { color: var(--t-primary); font-weight: inherit; }
.t-statement--statement::before { content: ""; display: block; width: 2.75rem; height: 3px; margin: 0 auto 1.5rem; border-radius: 2px; background: var(--t-accent); }
.t-statement--statement.t-statement--start::before { margin-inline: 0; }
.t-statement--ruled { padding-block: 2.25rem; border-block: 1px solid color-mix(in srgb, var(--t-text) 20%, transparent); }
.t-statement--quote .t-statement-text { font-weight: 500; }
.t-statement-mark { display: block; width: 2.5rem; height: auto; margin: 0 auto 1.125rem; fill: var(--t-accent); }
.t-statement--start .t-statement-mark { margin-inline: 0; }
.t-statement-by { display: inline-flex; align-items: center; gap: .75rem; margin-top: 1.375rem; text-align: start; }
.t-statement--center .t-statement-by { justify-content: center; }
.t-statement-portrait { flex: none; width: 3rem; height: 3rem; border-radius: 50%; object-fit: cover; box-shadow: 0 0 0 1px color-mix(in srgb, var(--t-text) 12%, transparent); }
.t-statement-who { display: flex; flex-direction: column; line-height: 1.35; }
.t-statement-author { font-weight: 700; font-size: 1rem; }
.t-statement-role { color: var(--t-muted); font-size: .875rem; }
.t-statement .t-genmark { margin-top: 1rem; }
/* Over a picture: edge to edge, the text on the scrim; without a picture, on the course's colour. */
.t-statement--image { display: grid; isolation: isolate; padding: 0; color: var(--t-on-primary); background: var(--t-primary); }
.t-statement--image > :is(.t-statement-media, .t-statement-scrim) { grid-area: 1 / 1; }
.t-statement-media { position: relative; z-index: -1; }
.t-statement-media img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; border-radius: 0; }
.t-statement-scrim { display: grid; align-content: center; min-height: var(--t-band-medium); padding: clamp(2.5rem, 6vw, 4.5rem) var(--t-bleed-gutter, 1.25rem); }
.t-statement--image:has(> .t-statement-media) { color: var(--t-on-scrim, #fff); }
.t-statement--image:has(> .t-statement-media) .t-statement-scrim { background: var(--t-scrim, var(--t-scrim-default)); }
/* Text over a picture keeps the scrim's colour whatever the theme says of its headings and text
   (important in elabora.base outweighs the later layers): a theme changes it with --t-on-scrim. */
.t-statement--image :is(.t-statement-text, .t-statement-text *, .t-statement-author, .t-statement-role, .t-genmark) { color: inherit !important; }
.t-statement--image .t-statement-role { opacity: .88; }
.t-slot > .t-w-bleed :is(.t-statement--image, .t-image--band .t-image-frame, .t-image--over) { border-radius: var(--t-radius); overflow: hidden; }

/* Divider (« Séparateur »): decoration between the parts of a page. The number is the screen's count
   of parts (01, 02…); restart counts again from its block. The ornament is a mask: a theme draws its
   own with --t-ornament (an url() of an SVG, its colour --t-ornament-color), or restyles
   .t-divider-ornament. */
.t-screen { counter-reset: t-part; }
.t-block:has(> .t-divider--number) { counter-increment: t-part; }
.t-block:has(> .t-divider[data-restart="true"]) { counter-reset: t-part; counter-increment: t-part; }
.t-divider { --t-divider-room: 1.25rem; margin: var(--t-divider-room) 0; border: 0; color: color-mix(in srgb, var(--t-text) 22%, transparent); }
.t-divider--small { --t-divider-room: .25rem; }
.t-divider--large { --t-divider-room: 3rem; }
.t-divider--line { height: 1px; background: currentColor; }
.t-divider--space { height: calc(var(--t-divider-room) * .5); }
.t-divider--ornament { display: flex; justify-content: center; }
.t-divider-ornament { display: block; width: 6rem; height: 1rem; background: var(--t-ornament-color, var(--t-accent)); -webkit-mask: var(--t-ornament, url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 96 16'%3E%3Cpath d='M48 2.5 53.5 8 48 13.5 42.5 8Z'/%3E%3Cpath d='M14 7.25h22v1.5H14ZM60 7.25h22v1.5H60Z'/%3E%3Ccircle cx='8' cy='8' r='1.6'/%3E%3Ccircle cx='88' cy='8' r='1.6'/%3E%3C/svg%3E")) center / contain no-repeat; mask: var(--t-ornament, url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 96 16'%3E%3Cpath d='M48 2.5 53.5 8 48 13.5 42.5 8Z'/%3E%3Cpath d='M14 7.25h22v1.5H14ZM60 7.25h22v1.5H60Z'/%3E%3Ccircle cx='8' cy='8' r='1.6'/%3E%3Ccircle cx='88' cy='8' r='1.6'/%3E%3C/svg%3E")) center / contain no-repeat; }
.t-divider--number { display: flex; align-items: center; gap: 1rem; }
.t-divider--number::after { content: ""; flex: 1; height: 1px; background: currentColor; }
.t-divider-number::before { content: counter(t-part, decimal-leading-zero); font: 600 1.5rem/1 var(--t-font-heading); font-variant-numeric: tabular-nums; letter-spacing: .02em; color: var(--t-primary); }

/* Image presentations: wide, band, beside, over (centered is the figure as it always was). */
.t-image { margin: 0; }
.t-image--wide img { width: 100%; }
.t-image--band, .t-image--over { --t-band: var(--t-band-medium); }
:is(.t-image--band, .t-image--over).t-image--short { --t-band: var(--t-band-short); }
:is(.t-image--band, .t-image--over).t-image--tall { --t-band: var(--t-band-tall); }
.t-image--band .t-image-frame { height: var(--t-band); overflow: hidden; }
.t-image--band .t-image-frame img, .t-image--over .t-image-frame img { width: 100%; height: 100%; max-width: none; object-fit: cover; border-radius: 0; }
.t-image--band > .t-image-caption, .t-image--over > .t-image-caption { margin-inline: auto; padding-inline: var(--t-bleed-gutter, 0); }
.t-image--over > .t-image-caption { margin: 0.375rem 0 0; color: var(--t-muted); font-size: 0.9375rem; }
.t-image--beside { display: grid; grid-template-columns: minmax(0, var(--t-beside-image, 1fr)) minmax(0, var(--t-beside-text, 1fr)); gap: 1.25rem clamp(1.5rem, 4cqi, 3rem); align-items: center; }
.t-image--third { --t-beside-image: 1fr; --t-beside-text: 2fr; }
.t-image--two-thirds { --t-beside-image: 2fr; --t-beside-text: 1fr; }
.t-image--end { grid-template-columns: minmax(0, var(--t-beside-text, 1fr)) minmax(0, var(--t-beside-image, 1fr)); }
.t-image--end > .t-figure { order: 2; }
.t-image--beside .t-figure img { width: 100%; max-height: min(34rem, 80vh); object-fit: cover; }
.t-image-title { margin: 0 0 .5rem; font-size: clamp(1.25rem, 1.1rem + .5vw, 1.5rem); }
.t-image--over { display: grid; isolation: isolate; color: var(--t-on-scrim, #fff); }
.t-image--over > :is(.t-image-frame, .t-image-overlay) { grid-area: 1 / 1; }
.t-image--over .t-image-frame { position: relative; z-index: -1; }
.t-image--over .t-image-frame img { position: absolute; inset: 0; }
.t-image-overlay { display: grid; align-content: end; min-height: var(--t-band); padding: clamp(2rem, 5vw, 3.5rem) var(--t-bleed-gutter, 1.25rem); background: var(--t-scrim, var(--t-scrim-default)); }
.t-image--over .t-image-text { max-width: 36rem; }
.t-image--over .t-image-overlay :is(.t-image-title, .t-text, .t-text *) { color: inherit !important; }
.t-image--over .t-image-title { font-size: clamp(1.5rem, 1.15rem + 1.2vw, 2.25rem); line-height: 1.15; }
.t-image--over .t-text { font-size: 1.125rem; }
.t-image--over > .t-genmark { padding-inline: var(--t-bleed-gutter, 0); color: var(--t-muted); }
@container (max-width: 560px) {
  .t-image--beside, .t-image--end { grid-template-columns: minmax(0, 1fr); }
  .t-image--end > .t-figure { order: 0; }
  .t-image--beside .t-figure img { max-height: 24rem; object-fit: cover; }
}

/* Gallery (« Galerie »): a grid of crops to one ratio, a mosaic of whole images, a carousel (one at a
   time, below), or before and after. */
.t-gallery { margin: 0; --t-gallery-columns: 3; --t-gallery-ratio: 4 / 3; }
.t-gallery[data-columns="2"] { --t-gallery-columns: 2; }
.t-gallery[data-columns="4"] { --t-gallery-columns: 4; }
.t-gallery[data-ratio="1:1"] { --t-gallery-ratio: 1; }
.t-gallery[data-ratio="3:2"] { --t-gallery-ratio: 3 / 2; }
.t-gallery[data-ratio="16:9"] { --t-gallery-ratio: 16 / 9; }
.t-gallery[data-ratio="3:4"] { --t-gallery-ratio: 3 / 4; }
.t-gallery-list { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(var(--t-gallery-columns), minmax(0, 1fr)); gap: 1rem; }
.t-gallery-item { margin: 0; min-width: 0; }
.t-gallery-item .t-figure img { width: 100%; }
.t-gallery--grid .t-gallery-item img { aspect-ratio: var(--t-gallery-ratio); object-fit: cover; }
.t-gallery-item figcaption { margin-top: .5rem; font-size: .875rem; line-height: 1.4; }
.t-gallery--mosaic .t-gallery-list { display: block; columns: var(--t-gallery-columns); column-gap: 1rem; }
.t-gallery--mosaic .t-gallery-item { break-inside: avoid; margin-bottom: 1rem; }
.t-gallery-caption { margin-top: .75rem; color: var(--t-muted); font-size: .9375rem; }
@container (max-width: 640px) { .t-gallery[data-columns] { --t-gallery-columns: 2; } .t-gallery-list { gap: .75rem; } .t-gallery--mosaic .t-gallery-list { column-gap: .75rem; } }
@container (max-width: 300px) { .t-gallery[data-columns] { --t-gallery-columns: 1; } }
/* Zoom (D63): an image that opens at full size in the lightbox is a button around it, a small
   magnifier in its corner. Without zoom the image's wrapper is not a box (t-media). */
.t-media { display: contents; }
.t-zoom { position: relative; display: inline-block; max-width: 100%; padding: 0; border: 0; border-radius: var(--t-radius); color: inherit; background: none; font: inherit; vertical-align: top; cursor: zoom-in; }
:is(.t-image--wide, .t-image--beside, .t-gallery) .t-zoom { display: block; width: 100%; }
.t-zoom::after { content: ""; position: absolute; top: .5rem; inset-inline-end: .5rem; width: 2rem; height: 2rem; border-radius: 50%; background: rgb(10 13 18 / .58) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='10.5' cy='10.5' r='6'/%3E%3Cpath d='M15 15l5 5M10.5 8v5M8 10.5h5'/%3E%3C/svg%3E") center / 1.125rem no-repeat; opacity: .85; pointer-events: none; transition: opacity var(--t-dur-item) ease, scale var(--t-dur-press, 120ms) var(--t-ease-out); }
.t-zoom:hover::after { opacity: 1; scale: calc(1 + .06 * var(--t-move)); }
/* The gallery's carousel: one image whole in its frame (ratio), its caption, then Previous, a
   thumbnail per image, where the learner is and Next; narrow containers keep the arrows and the
   position (a swipe moves too). */
.t-gallery-carousel { display: grid; gap: .75rem; }
.t-gallery-slides { display: grid; }
.t-gallery-slide { min-width: 0; margin: 0; }
.t-gallery--carousel .t-gallery-slide img { width: 100%; max-width: none; max-height: min(60vh, 34rem); aspect-ratio: var(--t-gallery-ratio); object-fit: contain; background: color-mix(in srgb, var(--t-text) 5%, var(--t-surface)); }
[data-presentation="slides"] .t-gallery--carousel .t-gallery-slide img { max-height: 52vh; }
.t-gallery-slide figcaption { margin-top: .5rem; font-size: .9375rem; line-height: 1.45; }
.t-gallery-nav { display: flex; align-items: center; gap: .5rem; }
.t-gallery-arrow { display: inline-flex; flex: none; align-items: center; justify-content: center; width: 2.75rem; height: 2.75rem; padding: 0; border: 1px solid color-mix(in srgb, var(--t-text) 22%, transparent); border-radius: 50%; color: var(--t-text); background: var(--t-surface); cursor: pointer; }
.t-gallery-arrow svg { width: 1.25rem; height: 1.25rem; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.t-gallery-thumbs { display: flex; flex: 1; justify-content: center; gap: .375rem; min-width: 0; margin: 0; padding: 0; list-style: none; }
.t-gallery-thumb { display: block; width: 3.5rem; height: 2.625rem; padding: 0; overflow: hidden; border: 0; border-radius: calc(var(--t-radius) * .6); background: color-mix(in srgb, var(--t-text) 6%, var(--t-surface)); opacity: .62; cursor: pointer; transition: opacity var(--t-dur-item) ease, box-shadow var(--t-dur-item) ease; }
.t-gallery-thumb img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: calc(var(--focus-x, .5) * 100%) calc(var(--focus-y, .5) * 100%); border-radius: 0; }
.t-gallery-thumb:hover { opacity: .9; }
.t-gallery-thumb[aria-current="true"] { opacity: 1; box-shadow: 0 0 0 2px var(--t-surface), 0 0 0 4px var(--t-primary); }
.t-gallery-position { flex: none; min-width: 3.5rem; color: var(--t-muted); font-size: .9375rem; font-variant-numeric: tabular-nums; text-align: center; }
@container (max-width: 560px) {
  .t-gallery-thumbs { display: none; }
  .t-gallery-nav { justify-content: center; }
}
/* Before and after (data-t-compare): the second picture over the first, clipped at the line the
   range sets (--t-compare); the range covers both, invisible, its handle drawn on the line. */
.t-compare { --t-compare: 50%; position: relative; overflow: hidden; border-radius: var(--t-radius); touch-action: pan-y; user-select: none; -webkit-user-select: none; }
.t-compare-side { margin: 0; }
.t-compare-side img { display: block; width: 100%; height: auto; border-radius: 0; }
.t-compare-after { position: absolute; inset: 0; clip-path: inset(0 0 0 var(--t-compare)); }
.t-compare-after img { height: 100%; object-fit: cover; }
.t-compare::before { content: ""; position: absolute; z-index: 2; top: 0; bottom: 0; inset-inline-start: var(--t-compare); width: 2px; translate: -1px 0; background: #fff; box-shadow: 0 0 0 1px rgb(10 13 18 / .18); pointer-events: none; }
.t-compare::after { content: ""; position: absolute; z-index: 3; top: 50%; inset-inline-start: var(--t-compare); width: 2.75rem; height: 2.75rem; translate: -50% -50%; border-radius: 50%; background: #fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%231f2933' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 7 4 12l5 5M15 7l5 5-5 5'/%3E%3C/svg%3E") center / 1.375rem no-repeat; box-shadow: 0 2px 10px rgb(10 13 18 / .28); pointer-events: none; transition: scale var(--t-dur-press) var(--t-ease-out); }
.t-compare:has(.t-compare-range:active)::after { scale: calc(1 - .06 * var(--t-move)); }
.t-compare:has(.t-compare-range:focus-visible)::after { outline: 3px solid var(--t-focus); outline-offset: 3px; }
.t-compare-range { position: absolute; z-index: 4; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: ew-resize; appearance: none; -webkit-appearance: none; background: transparent; }
.t-compare-range::-webkit-slider-thumb { -webkit-appearance: none; width: 2.75rem; height: 100%; }
.t-compare-range::-moz-range-thumb { width: 2.75rem; height: 100%; border: 0; }
.t-compare-label { position: absolute; z-index: 1; top: .75rem; inset-inline-start: .75rem; max-width: calc(50% - 2.5rem); margin: 0; padding: .25rem .625rem; border-radius: 999px; background: rgb(10 13 18 / .72); color: #fff; font-size: .8125rem; font-weight: 600; line-height: 1.35; }
.t-compare-after .t-compare-label { inset-inline-start: auto; inset-inline-end: .75rem; }

/* Panels (« Panneaux », D63): one list of items as an accordion, tabs, a grid of flip cards or a stack
   of them. The prompt says what to think of before opening. What shows one thing at a time keeps the
   room of its tallest (tabs: the panels share one cell; cards: the rows share the tallest card; the
   stack: the sequence's room). */
.t-block--accordion { container-type: inline-size; }
.t-panels-prompt { margin: 0 0 1rem; color: var(--t-text); font-size: 1.0625rem; font-style: italic; line-height: 1.5; text-wrap: pretty; }
.t-panels-image { display: block; width: 100%; max-height: 18rem; aspect-ratio: 16 / 9; margin: .25rem 0 .875rem; object-fit: contain; border-radius: calc(var(--t-radius) * .75); background: color-mix(in srgb, var(--t-text) 4%, var(--t-surface)); }
.t-panels-content > :last-child, .t-panels-content > .t-text > :last-child, .t-panels-tabpanel > .t-text > :last-child, .t-panels-back > .t-text > :last-child { margin-bottom: 0; }
/* Tabs: two marks of the tab shown (its colour, a rule under it). */
.t-panels-tablist { display: flex; flex-wrap: wrap; gap: .25rem; box-shadow: inset 0 -1px 0 color-mix(in srgb, var(--t-text) 14%, transparent); }
.t-panels-tab { position: relative; min-height: 2.75rem; padding: .5rem 1rem; border: 0; border-radius: var(--t-radius) var(--t-radius) 0 0; color: var(--t-muted); background: none; font: inherit; font-weight: 600; line-height: 1.3; text-align: start; cursor: pointer; transition: color var(--t-dur-item) ease, background-color var(--t-dur-item) ease; }
.t-panels-tab:hover { color: var(--t-text); background: color-mix(in srgb, var(--t-text) 4%, transparent); }
.t-panels-tab[aria-selected="true"] { color: var(--t-primary); }
.t-panels-tab[aria-selected="true"]::after { content: ""; position: absolute; inset-inline: .625rem; bottom: 0; height: 3px; border-radius: 3px 3px 0 0; background: var(--t-primary); }
.t-panels-tabpanels { display: grid; padding: 1.25rem .125rem .25rem; }
.t-panels-tabpanel { grid-area: 1 / 1; min-width: 0; }
.t-panels-tabpanel[hidden] { display: block !important; visibility: hidden; }
.t-panels-tabpanel:not([hidden]) { animation: t-panels-in var(--t-dur-item) ease; }
@keyframes t-panels-in { from { opacity: 0; } }
/* Narrow containers: the tabs' items as an accordion (one rendered at a time, so one in the
   accessibility tree). */
.t-panels-narrow { display: none; }
@container (max-width: 560px) {
  .t-panels--tabs .t-panels-tabs { display: none; }
  .t-panels--tabs .t-panels-narrow { display: block; }
}
/* Cards: the front (the image cropped around its focus, the title) and the back (the text). The
   flip button covers its face, so a press anywhere on the card turns it; its words are the hint. */
.t-panels-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(13rem, calc(50% - .5rem)), 1fr)); grid-auto-rows: 1fr; gap: 1rem; margin: 0; padding: 0; list-style: none; }
/* Cards take the wide column; four cards in a medium container go two by two. */
:is(.t-screen > .t-blocks, .t-opening-body.t-slot) > .t-block:has(> .t-panels--cards) { max-width: var(--t-wide-width, 68.75rem); }
@container (max-width: 900px) { .t-panels-cards:has(> :nth-child(4):last-child) { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.t-panels-cell { display: grid; min-width: 0; }
.t-panels-card { min-height: 11rem; }
.t-panels-face { position: relative; display: flex; flex-direction: column; min-width: 0; overflow: hidden; border-radius: calc(var(--t-radius) + 4px); }
.t-panels-front { color: var(--t-text); background: color-mix(in srgb, var(--t-primary) 8%, var(--t-surface)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--t-primary) 16%, transparent); }
.t-panels-front:not(:has(.t-panels-cover)) { justify-content: center; }
.t-panels-cover { display: block; flex: none; width: 100%; max-height: 10rem; aspect-ratio: 3 / 2; object-fit: cover; object-position: calc(var(--focus-x, .5) * 100%) calc(var(--focus-y, .5) * 100%); }
.t-panels-title { margin: 0; padding: 1rem 1.125rem .25rem; color: inherit; font-size: 1.125rem; line-height: 1.3; overflow-wrap: anywhere; }
.t-panels-front:not(:has(.t-panels-cover)) .t-panels-title { padding-top: 1.5rem; font-size: 1.25rem; text-align: center; }
.t-panels-back { padding: 1.125rem 1.125rem 0; color: var(--t-text); background: var(--t-surface); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--t-text) 16%, transparent); }
.t-panels-back > .t-text { font-size: .9375rem; line-height: 1.5; }
.t-panels-back > .t-text :is(a, button) { position: relative; z-index: 1; }
.t-panels-flip { display: flex; align-items: center; gap: .375rem; min-height: 2.75rem; margin-top: auto; padding: .5rem 1.125rem .75rem; border: 0; color: var(--t-primary); background: none; font: inherit; font-size: .875rem; font-weight: 600; line-height: 1.3; text-align: start; cursor: pointer; }
.t-panels-front:not(:has(.t-panels-cover)) .t-panels-flip { justify-content: center; margin-top: 0; }
.t-panels-front:not(:has(.t-panels-cover)) .t-panels-title { margin-top: auto; }
.t-panels-front:not(:has(.t-panels-cover)) .t-panels-flip { margin-bottom: auto; }
.t-panels-back .t-panels-flip { padding-inline: 0; }
.t-panels-flip::before { content: ""; flex: none; width: 1.125rem; height: 1.125rem; background: currentColor; -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 11a8 8 0 0 0-14.3-4.9L4 8'/%3E%3Cpath d='M4 3v5h5'/%3E%3Cpath d='M4 13a8 8 0 0 0 14.3 4.9L20 16'/%3E%3Cpath d='M20 21v-5h-5'/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 11a8 8 0 0 0-14.3-4.9L4 8'/%3E%3Cpath d='M4 3v5h5'/%3E%3Cpath d='M4 13a8 8 0 0 0 14.3 4.9L20 16'/%3E%3Cpath d='M20 21v-5h-5'/%3E%3C/svg%3E") center / contain no-repeat; }
.t-panels-flip::after { content: ""; position: absolute; inset: 0; border-radius: inherit; }
.t-panels-flip:focus-visible { outline: none; }
.t-panels-flip:focus-visible::after { outline: 3px solid var(--t-focus); outline-offset: -3px; }
.t-panels-face:has(.t-panels-flip:hover) { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--t-primary) 40%, transparent); }
/* Without the hint, the button keeps its icon; its words are only its name. */
.t-panels[data-hint="false"] .t-panels-flip { font-size: 0; }
@container (max-width: 560px) {
  .t-panels-title { padding: .75rem .875rem .125rem; font-size: 1rem; }
  .t-panels-front:not(:has(.t-panels-cover)) .t-panels-title { font-size: 1.0625rem; }
  .t-panels-back { padding: .875rem .875rem 0; }
  .t-panels-back > .t-text { font-size: .875rem; }
  .t-panels-flip { padding: .375rem .875rem .625rem; font-size: .8125rem; }
  .t-panels-cover { max-height: 7rem; }
}
/* Stack: one card at a time, a second card's edge under it, Previous, where the learner is, Next. */
.t-panels-stack { display: grid; justify-items: center; gap: .75rem; }
.t-panels-stack-items { position: relative; display: grid; width: 100%; max-width: 32rem; padding-bottom: .5rem; }
.t-panels-stack-items::after { content: ""; position: absolute; z-index: -1; inset: auto .875rem 0; height: 2rem; border-radius: 0 0 calc(var(--t-radius) + 4px) calc(var(--t-radius) + 4px); background: color-mix(in srgb, var(--t-primary) 5%, var(--t-surface)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--t-primary) 14%, transparent); }
.t-panels-stack-items { isolation: isolate; }
.t-panels-stack-item { display: grid; min-width: 0; }
.t-panels--stack .t-panels-card { min-height: 14rem; }
.t-panels-nav { display: flex; align-items: center; gap: .75rem; }
.t-panels-arrow { display: inline-flex; align-items: center; justify-content: center; width: 2.75rem; height: 2.75rem; padding: 0; border: 1px solid color-mix(in srgb, var(--t-text) 22%, transparent); border-radius: 50%; color: var(--t-text); background: var(--t-surface); cursor: pointer; }
.t-panels-arrow svg { width: 1.25rem; height: 1.25rem; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.t-panels-position { min-width: 3.5rem; color: var(--t-muted); font-size: .9375rem; font-variant-numeric: tabular-nums; text-align: center; }

/* A character speaking (« Personnage », D63): its round portrait beside its bubbles, its name above
   them in its colour; the bubbles take the dialogues' colours (dialog.* tokens). A thought is a
   cloud, its tail two small rounds. Nothing moves: the character rests. */
.t-block--speech { container-type: inline-size; }
.t-speech { --t-sp-bubble: var(--t-dialog-bubble, color-mix(in srgb, var(--t-text) 5%, var(--t-surface))); --t-sp-text: var(--t-dialog-text, var(--t-text)); --t-sp-avatar: 4rem; display: flex; align-items: flex-start; gap: .875rem; }
.t-speech--end { flex-direction: row-reverse; }
.t-speech-portrait { flex: none; width: var(--t-sp-avatar); height: var(--t-sp-avatar); overflow: hidden; border-radius: 50%; background: color-mix(in srgb, var(--t-speech-color, var(--t-text)) 12%, var(--t-surface)); }
.t-speech-portrait .t-character-initial { width: 100%; height: 100%; font-size: 1.375rem; color: color-mix(in srgb, var(--t-speech-color, var(--t-text)) 70%, var(--t-text)); }
.t-speech-lines { display: flex; flex-direction: column; align-items: flex-start; gap: .375rem; min-width: 0; max-width: min(36rem, 100%); }
.t-speech--end .t-speech-lines { align-items: flex-end; }
.t-speech-name { margin: .25rem .375rem 0; font-size: .875rem; font-weight: 650; line-height: 1.2; color: color-mix(in srgb, var(--t-speech-color, var(--t-muted)) 72%, var(--t-sp-text)); }
.t-speech-name:empty { display: none; }
.t-speech-bubble { position: relative; min-width: 0; max-width: 100%; padding: .75rem 1.125rem .8125rem; border-radius: 1.25rem; color: var(--t-sp-text); background: var(--t-sp-bubble); line-height: 1.5; overflow-wrap: anywhere; }
.t-speech-bubble > .t-text > :last-child { margin-bottom: 0; }
.t-speech-bubble > .t-text > :first-child { margin-top: 0; }
/* The first bubble points to the character. */
.t-speech--speech.t-speech--start .t-speech-name + .t-speech-bubble, .t-speech--speech.t-speech--start .t-speech-lines > .t-speech-bubble:first-child { border-top-left-radius: .375rem; }
.t-speech--speech.t-speech--end .t-speech-name + .t-speech-bubble, .t-speech--speech.t-speech--end .t-speech-lines > .t-speech-bubble:first-child { border-top-right-radius: .375rem; }
.t-speech--speech .t-speech-name + .t-speech-bubble::before, .t-speech--speech .t-speech-lines > .t-speech-bubble:first-child::before { content: ""; position: absolute; top: 0; inset-inline-start: -.4375rem; width: .875rem; height: .875rem; background: inherit; clip-path: polygon(0 0, 100% 0, 100% 100%); }
.t-speech--speech.t-speech--end .t-speech-name + .t-speech-bubble::before, .t-speech--speech.t-speech--end .t-speech-lines > .t-speech-bubble:first-child::before { inset-inline: auto -.4375rem; clip-path: polygon(0 0, 100% 0, 0 100%); }
.t-speech--thought .t-speech-bubble { border-radius: 1.75rem; font-style: italic; }
.t-speech--thought .t-speech-name + .t-speech-bubble { margin-inline-start: .875rem; }
.t-speech--thought.t-speech--end .t-speech-name + .t-speech-bubble { margin-inline: 0 .875rem; }
.t-speech--thought .t-speech-name + .t-speech-bubble::before, .t-speech--thought .t-speech-name + .t-speech-bubble::after { content: ""; position: absolute; border-radius: 50%; background: var(--t-sp-bubble); }
.t-speech--thought .t-speech-name + .t-speech-bubble::before { top: 1.25rem; inset-inline-start: -.875rem; width: .75rem; height: .75rem; }
.t-speech--thought .t-speech-name + .t-speech-bubble::after { top: 1.875rem; inset-inline-start: -1.375rem; width: .4375rem; height: .4375rem; }
.t-speech--thought.t-speech--end .t-speech-name + .t-speech-bubble::before { inset-inline: auto -.875rem; }
.t-speech--thought.t-speech--end .t-speech-name + .t-speech-bubble::after { inset-inline: auto -1.375rem; }
@container (max-width: 560px) { .t-speech { --t-sp-avatar: 3rem; gap: .625rem; } }

/* Columns (« Colonnes »): two or three, stacked in reading order in narrow containers. */
.t-columns { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.5rem clamp(1.5rem, 4cqi, 2.5rem); align-items: start; }
.t-columns--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.t-columns--2.t-columns--wide-start { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); }
.t-columns--2.t-columns--wide-end { grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); }
.t-columns--3.t-columns--wide-start { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr) minmax(0, 1fr); }
.t-columns--3.t-columns--wide-end { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 2fr); }
.t-columns--center { align-items: center; }
.t-columns > .t-slot[data-empty] { display: flex; }
.t-columns--2 > [data-slot="third"] { display: none; }
@container (max-width: 560px) {
  .t-columns, .t-columns:is(.t-columns--3, .t-columns--wide-start, .t-columns--wide-end) { grid-template-columns: minmax(0, 1fr); }
  .t-columns > .t-slot[data-empty] { display: none; }
}

/* A text's note in the margin (aside): after the text, smaller and quieter, in narrow windows; beside
   it, level with its first line, where the window leaves room beside the reading column. */
.t-aside { margin: .875rem 0 0; color: var(--t-muted); font-size: .9375rem; line-height: 1.5; }
@media (min-width: 1180px) and (not ((orientation: portrait) and (max-width: 1100px))) {
  :is(.t-screen > .t-blocks, .t-opening-body.t-slot) > .t-block--text.t-w-full:has(> .t-aside) { display: grid; grid-template-columns: 100% var(--t-aside-width, 13.5rem); column-gap: 2.5rem; align-items: start; }
  :is(.t-screen > .t-blocks, .t-opening-body.t-slot) > .t-block--text.t-w-full > .t-aside { margin: .25rem 0 0; }
}

/* Opening (« Ouverture »), a built-in screen layout: the head of a lesson (no line above its title),
   then its page as the default column. The layout owns the page (full bleed): its head may go edge to edge. */
.t-opening { --t-opening-gutter: max(var(--t-gutter), calc((100% - var(--t-content-width, 47.5rem)) / 2)); }
.t-opening-head { position: relative; display: grid; isolation: isolate; }
.t-opening-copy { position: relative; padding: clamp(2.5rem, 6vw, 4.5rem) var(--t-opening-gutter) clamp(1.25rem, 2.5vw, 2rem); }
.t-opening .t-screen-title { max-width: 18em; margin: 0; font-size: clamp(2.125rem, 1.35rem + 2.6vw, 3.5rem); line-height: 1.08; letter-spacing: -0.02em; text-wrap: balance; }
.t-opening-lead { max-width: 36em; margin-top: 1.25rem; font-size: clamp(1.125rem, 1.02rem + .35vw, 1.3125rem); line-height: 1.5; }
.t-opening-meta { display: flex; align-items: center; gap: .4rem; margin: 1.5rem 0 0; color: var(--t-muted); font-size: .875rem; font-weight: 600; }
.t-opening-clock { flex: none; width: 1rem; height: 1rem; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.t-opening--title .t-opening-copy::after { content: ""; display: block; width: 2.75rem; height: 3px; margin-top: 1.75rem; border-radius: 2px; background: var(--t-accent); }
.t-opening-media { position: relative; }
.t-opening-media img { display: block; width: 100%; height: 100%; object-fit: cover; }
.t-opening-media .t-genmark { position: absolute; inset-inline-end: .75rem; bottom: .5rem; margin: 0; padding: .125rem .5rem; border-radius: 999px; color: #fff; background: rgb(10 13 18 / .6); }
.t-opening--title .t-opening-media { max-width: var(--t-wide-width, 68.75rem); width: calc(100% - 2.5rem); margin: 0 auto; }
.t-opening--title .t-opening-media img { aspect-ratio: 21 / 9; height: auto; border-radius: var(--t-radius); }
/* band and cover: the picture behind the head, the text at its foot on the scrim. */
.t-opening:is(.t-opening--band, .t-opening--cover) .t-opening-head { color: var(--t-on-primary); background: var(--t-primary); }
.t-opening:is(.t-opening--band, .t-opening--cover) .t-opening-copy { align-self: end; }
.t-opening--band .t-opening-head { min-height: clamp(22rem, 44vw, 34rem); }
.t-opening--cover .t-opening-head { min-height: calc(100svh - var(--t-bar-top, 0px) - var(--t-bar-bottom, 0px)); }
.t-opening:is(.t-opening--band, .t-opening--cover) :is(.t-opening-copy, .t-opening-media) { grid-area: 1 / 1; }
.t-opening:is(.t-opening--band, .t-opening--cover) .t-opening-media { z-index: -2; }
.t-opening:is(.t-opening--band, .t-opening--cover) .t-opening-media img { position: absolute; inset: 0; }
.t-opening:is(.t-opening--band, .t-opening--cover) .t-opening-head:has(> .t-opening-media) { color: var(--t-on-scrim, #fff); }
.t-opening:is(.t-opening--band, .t-opening--cover) .t-opening-head:has(> .t-opening-media) .t-opening-copy { --t-opening-fade: clamp(5rem, 12vw, 9rem); padding-top: var(--t-opening-fade); }
/* The scrim under the text fades in above it: no edge across the picture. */
.t-opening:is(.t-opening--band, .t-opening--cover) .t-opening-head:has(> .t-opening-media) .t-opening-copy::before { content: ""; position: absolute; inset: 0; z-index: -1; background: var(--t-scrim, var(--t-scrim-default)); -webkit-mask: linear-gradient(transparent, #000 var(--t-opening-fade)); mask: linear-gradient(transparent, #000 var(--t-opening-fade)); }
.t-opening:is(.t-opening--band, .t-opening--cover) .t-opening-copy :is(.t-screen-title, .t-opening-lead, .t-opening-lead *, .t-opening-meta) { color: inherit !important; }
.t-opening--cover .t-opening-copy { padding-bottom: clamp(2.5rem, 7vh, 4.5rem); }
/* split: the head beside the picture; the picture above it in narrow windows. */
.t-opening--split .t-opening-head:has(> .t-opening-media) { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); min-height: clamp(24rem, 40vw, 36rem); }
.t-opening--split .t-opening-head:has(> .t-opening-media) .t-opening-copy { align-self: center; padding: clamp(2.5rem, 5vw, 4rem) clamp(1.5rem, 4vw, 3.5rem) clamp(2.5rem, 5vw, 4rem) max(1.25rem, calc((var(--t-page-width, 100vw) - var(--t-wide-width, 68.75rem)) / 2)); }
.t-opening--split .t-opening-media img { position: absolute; inset: 0; }
@container (max-width: 760px) {
  .t-opening--split .t-opening-head:has(> .t-opening-media) { grid-template-columns: minmax(0, 1fr); min-height: 0; }
  .t-opening--split .t-opening-media { order: -1; aspect-ratio: 3 / 2; }
  .t-opening--split .t-opening-head:has(> .t-opening-media) .t-opening-copy { padding: 2rem 1.25rem 1.25rem; }
  .t-opening--band .t-opening-head { min-height: 22rem; }
  .t-opening--title .t-opening-media { width: calc(100% - 1.75rem); }
  .t-opening--title .t-opening-media img { aspect-ratio: 3 / 2; }
}
/* In slides the opening is the slide: its head takes the room its page leaves (a cover, all of it). */
[data-presentation="slides"] .t-screen.t-layout--opening { display: flex; flex-direction: column; align-self: stretch; margin-block: 0; flex: 1; }
[data-presentation="slides"] .t-opening { display: flex; flex: 1; flex-direction: column; }
[data-presentation="slides"] .t-opening-head { flex: 1 0 auto; }
[data-presentation="slides"] .t-opening:is(.t-opening--band, .t-opening--cover, .t-opening--split) .t-opening-head { min-height: min(22rem, 45vh); }
/* The question before the lesson, then the page: the default column, under the head. */
.t-opening-question.t-slot { width: 100%; max-width: calc(var(--t-content-width, 47.5rem) + 2.5rem); margin: 0 auto; padding: clamp(1.75rem, 4vw, 2.5rem) 1.25rem 0; }
.t-opening-body.t-slot { display: grid; grid-template-columns: 1fr 1fr; gap: 1.25rem 1.5rem; width: 100%; max-width: calc(var(--t-wide-width, 68.75rem) + 2.5rem); margin: 0 auto; padding: clamp(1.75rem, 4vw, 2.75rem) 1.25rem 2.5rem; }
.t-opening-body.t-slot > .t-block { grid-column: 1 / -1; width: 100%; max-width: var(--t-content-width, 47.5rem); justify-self: center; }
.t-opening-body.t-slot > .t-block.t-w-wide { max-width: none; }
.t-opening-body.t-slot > .t-block.t-w-half { grid-column: span 1; max-width: none; }
@media (max-width: 760px) { .t-opening-body.t-slot > .t-block.t-w-half { grid-column: 1 / -1; } .t-opening-body.t-slot { padding: 1.5rem .875rem 2rem; } .t-opening-question.t-slot { padding-inline: .875rem; } }


.t-dialog { max-width: min(40rem, calc(100vw - 2rem)); border: 0; border-radius: calc(var(--t-radius) + 4px); padding: 1.5rem; color: var(--t-text); background: var(--t-surface); box-shadow: 0 20px 60px rgba(0,0,0,.25); }
.t-dialog::backdrop { background: rgba(15, 23, 42, .45); }
/* A layer, a modal one or a panel, and the viewer: they come and go with a movement. Their exits need
   the dialog to stay drawn once closed (display, and overlay for the modal ones, the top layer); where
   a browser cannot, they close at once. */
.t-dialog, .t-viewer { transition: opacity var(--t-dur-modal) var(--t-ease-out), scale var(--t-dur-modal) var(--t-ease-out); }
@starting-style { .t-dialog[open], .t-viewer[open] { opacity: 0; scale: calc(1 - .04 * var(--t-move)); } }
.t-dialog::backdrop, .t-viewer::backdrop { transition: opacity var(--t-dur-modal) var(--t-ease-out); }
@starting-style { .t-dialog[open]::backdrop, .t-viewer[open]::backdrop { opacity: 0; } }
@supports (overlay: auto) {
  .t-dialog, .t-viewer { transition: opacity var(--t-dur-modal) var(--t-ease-out), scale var(--t-dur-modal) var(--t-ease-out), display var(--t-dur-modal) allow-discrete, overlay var(--t-dur-modal) allow-discrete; }
  .t-dialog:not([open]), .t-viewer:not([open]) { opacity: 0; scale: calc(1 - .04 * var(--t-move)); }
  .t-dialog::backdrop, .t-viewer::backdrop { transition: opacity var(--t-dur-modal) var(--t-ease-out), display var(--t-dur-modal) allow-discrete, overlay var(--t-dur-modal) allow-discrete; }
  .t-dialog:not([open])::backdrop, .t-viewer:not([open])::backdrop { opacity: 0; }
}
.t-dialog .t-blocks { grid-template-columns: 1fr; }
.t-dialog-title { font-size: 1.3125rem; font-weight: 700; margin: 0 0 0.875rem; }
.t-dialog-actions { display: flex; justify-content: flex-end; gap: 0.625rem; margin-top: 1.125rem; }
/* A layer's own timeline (D62): its compact bar beside Close, in the layer's colours, its captions
   above it, in the layer. Its room is there from the opening: nothing moves when it plays. */
.t-layer[data-timeline] .t-dialog-actions { align-items: center; }
.t-dialog[data-timeline] { width: min(40rem, calc(100vw - 2rem)); }
.t-layer-timeline { position: relative; display: flex; flex: 1 1 auto; min-width: 0; color: var(--t-text); --t-pl-bottom-fg: var(--t-text); --t-pl-bottom-bg: var(--t-surface); }
.t-layer-timeline .t-timeline-seek { flex-basis: 6rem; min-width: 4rem; margin: 0 0.5rem; }
.t-layer-timeline .t-timeline-tools { padding-inline-start: 0.375rem; }
.t-layer-timeline .t-timeline-band { left: 50%; bottom: calc(100% + 0.75rem); width: min(100%, 34rem); }
.t-layer-timeline .t-timeline-caption { font-size: 1.0625rem; }
/* Captions on: two lines of room under the layer's blocks, where the band comes (it would cover them). */
.t-layer[data-timeline][data-captions] .t-blocks { margin-bottom: calc(2 * 1.0625rem * 1.6 + 1.625rem); }
#elabora-app[data-captions="large"] .t-layer[data-timeline][data-captions] .t-blocks { margin-bottom: calc(2 * 1.75rem * 1.6 + 1.625rem); }
/* Panel layer (presentation "panel"): over part of the screen, which stays usable; anchored to the
   screen area between the bars. On phones, a sheet at the bottom of the window. */
.t-panel { position: absolute; inset: 1.25rem 1.25rem auto auto; z-index: 4; width: min(28rem, calc(100% - 2.5rem)); max-height: calc(100% - 2.5rem); overflow-y: auto; overscroll-behavior: contain; margin: 0; padding: 1.25rem 1.375rem; border: 1px solid color-mix(in srgb, var(--t-text) 14%, transparent); border-radius: calc(var(--t-radius) + 4px); color: var(--t-text); background: var(--t-surface); box-shadow: 0 18px 48px rgba(15, 23, 42, .22); }
.t-panel { transition: opacity var(--t-dur-modal) var(--t-ease-out), translate var(--t-dur-modal) var(--t-ease-out), display var(--t-dur-modal) allow-discrete; }
.t-panel:not([open]) { opacity: 0; translate: calc(1rem * var(--t-move)) 0; }
@starting-style { .t-panel[open] { opacity: 0; translate: calc(1rem * var(--t-move)) 0; } }
.t-panel:dir(rtl):not([open]) { translate: calc(-1rem * var(--t-move)) 0; }
@starting-style { .t-panel[open]:dir(rtl) { translate: calc(-1rem * var(--t-move)) 0; } }
.t-panel .t-blocks { grid-template-columns: 1fr; }
.t-panel .t-block { max-width: none; }
.t-panel .t-dialog-title:focus { outline: none; }
@media (max-width: 760px) {
  .t-panel { position: fixed; inset: auto 0.75rem 0.75rem; width: auto; max-height: 70vh; max-height: 70dvh; transition-duration: var(--t-dur-drawer); transition-timing-function: var(--t-ease-drawer); }
  .t-panel:not([open]), .t-panel:dir(rtl):not([open]) { opacity: 1; translate: 0 calc(100% + 0.75rem); }
  @starting-style { .t-panel[open], .t-panel[open]:dir(rtl) { opacity: 1; translate: 0 calc(100% + 0.75rem); } }
}
.t-ended { max-width: 40rem; margin: 15vh auto 0; text-align: center; }


/* A narrated slide's Continue: its place kept at the end of the screen, shown at the end of a step. */
.t-continue--slot { align-items: flex-end; max-width: none; margin: 1rem 0 0; }
.t-continue--slot[data-t-waiting] { visibility: hidden; }
/* Progress kept in this browser (web, progress local): a quiet line at the end of the outline and of the ended page. */
.t-progress-note { margin: 0.75rem 0.625rem 0; padding-top: 0.625rem; border-top: 1px solid color-mix(in srgb, var(--t-text) 10%, transparent); font-size: 0.8125rem; color: var(--t-muted); }
.t-ended .t-progress-note { margin: 2rem auto 0; max-width: 28rem; }
.t-progress-note p { margin: 0 0 0.25rem; }
.t-link-btn { padding: 0.25rem 0; min-height: 24px; border: 0; background: none; color: inherit; font: inherit; text-decoration: underline; text-underline-offset: 2px; cursor: pointer; }
.t-link-btn:hover { color: var(--t-text); }
.t-progress-note-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.5rem; }
.t-ended .t-progress-note-actions { justify-content: center; }

/* ── The player's bars (docs/decisions.md D58) ──────────────────────────────────────────────
   Two bars of items, top and bottom, as the Lin pages 36 and 27 draw them: a title bar in the
   course's colour, a light bottom bar with the outline, the narration's controls and Previous /
   Next. Colours and size come from the theme's player.* tokens, with the charter as default; the
   compiler gives player.bottom.text a colour that reads on the bar. Nothing here moves the layout
   while learners use it: Next keeps the width of its longest label, Previous and Next unavailable
   stay greyed in place, and every refusal or hint is the one tooltip (.t-tip). */
:root {
  --t-pl-top-bg: var(--t-player-top-background, var(--t-primary));
  --t-pl-top-fg: var(--t-player-top-text, var(--t-on-primary));
  --t-pl-bottom-bg: var(--t-player-bottom-background, var(--t-surface));
  --t-pl-bottom-fg: var(--t-player-bottom-text, var(--t-text));
  --t-pl-accent: var(--t-player-accent, var(--t-primary));
  --t-pl-on-accent: var(--t-player-on-accent, var(--t-on-primary));
  --t-pl-tip-bg: var(--t-player-tooltip-background, var(--t-text));
  --t-pl-tip-fg: var(--t-player-tooltip-text, var(--t-surface));
  --t-pl-radius: var(--t-player-radius, 999px);
  /* Sizes at the reference window (in rem: they follow the size classes); compact below. */
  --t-pl-top-h: 3.5rem;
  --t-pl-bottom-h: 4.5rem;
  --t-pl-btn: max(44px, 2.75rem);
  --t-pl-icon-btn: max(36px, 2.5rem);
}
[data-density="compact"] { --t-pl-top-h: 3rem; --t-pl-bottom-h: 3.75rem; --t-pl-btn: max(36px, 2.5rem); --t-pl-icon-btn: max(32px, 2.25rem); }

.t-bar { position: relative; z-index: 6; flex: none; display: flex; align-items: center; gap: 0.5rem; min-width: 0; font-family: var(--t-font-body); }
.t-bar[data-position="window"] { position: sticky; }
.t-bar--top { top: 0; min-height: var(--t-pl-top-h); padding: 0.375rem 1rem 0.375rem 1.75rem; background: var(--t-pl-top-bg); color: var(--t-pl-top-fg); font-size: 1rem; }
.t-bar--bottom, .t-bar--controls { bottom: 0; min-height: var(--t-pl-bottom-h); padding: 0.5rem 1.25rem; gap: 0.75rem; background: var(--t-pl-bottom-bg); color: var(--t-pl-bottom-fg); font-size: 0.9375rem; box-shadow: inset 0 1px 0 color-mix(in srgb, var(--t-pl-bottom-fg) 12%, transparent); }
.t-bar--top { box-shadow: inset 0 -1px 0 color-mix(in srgb, var(--t-pl-top-fg) 10%, transparent); }
.t-bar--controls { position: sticky; }
.t-bar--controls:not(:has(.t-timeline)) { display: none; }
.t-item { display: flex; align-items: center; flex: none; min-width: 0; }
.t-item--push { margin-inline-start: auto; }
.t-item--title, .t-item--controls { flex: 1 1 auto; }
.t-item--title { margin-inline-end: 0.5rem; }
.t-course-title { margin: 0; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 700; }
/* The bar's height less its margins (32 px in a bar of 56), never wider than 220 px, never enlarged. */
.t-logo { display: block; width: auto; height: auto; max-height: calc(var(--t-pl-top-h) - 1.5rem); max-width: 13.75rem; object-fit: contain; }
.t-bar--bottom .t-logo { max-height: 2rem; }
/* An SVG scales without loss, and one with a viewBox but no width or height has no size of its own (it
   would shrink to nothing in the bar): it takes the height. */
.t-logo[src$=".svg" i] { height: calc(var(--t-pl-top-h) - 1.5rem); }
.t-bar--bottom .t-logo[src$=".svg" i] { height: 2rem; }
/* The progress: a slim bar and its share, in the colour of the bar's text unless player.progress says otherwise. */
.t-item--progress { gap: 0.625rem; flex: 0 1 11rem; min-width: 6rem; }
.t-progress { flex: 1 1 auto; height: 6px; border-radius: 3px; background: color-mix(in srgb, currentColor 20%, transparent); overflow: hidden; }
.t-progress-bar { height: 100%; width: 100%; border-radius: inherit; translate: calc((var(--t-progress, 0) - 100) * 1%) 0; background: var(--t-player-progress, currentColor); transition: translate var(--t-dur-modal) var(--t-ease-out); }
.t-progress-bar:dir(rtl) { translate: calc((100 - var(--t-progress, 0)) * 1%) 0; }
.t-progress-value { min-width: 3.25em; font-size: 0.8125rem; font-weight: 600; font-variant-numeric: tabular-nums; opacity: .85; }
/* A course in parts: one segment per part, as wide as its share of the screens, a little wider for
   many parts. Each is a button as tall as a bar's button around its slim line; the part shown has a
   stronger line, one completed is full. Hovered, a line darkens; nothing else changes. */
.t-item--progress[data-parts] { flex-basis: clamp(11rem, calc(var(--t-parts) * 1.75rem + 4rem), 22rem); }
.t-progress--parts { display: flex; gap: 3px; height: auto; border-radius: 0; background: none; overflow: visible; }
.t-part { display: flex; align-items: center; flex: 1 1 0; min-width: 0; height: var(--t-pl-btn); padding: 0; border: 0; border-radius: 4px; color: inherit; background: transparent; cursor: pointer; }
.t-part-track { width: 100%; height: 6px; border-radius: 3px; background: color-mix(in srgb, currentColor 20%, transparent); overflow: hidden; transition: background-color var(--t-dur-press) ease; }
.t-part[data-current] .t-part-track { background: color-mix(in srgb, currentColor 38%, transparent); }
/* A halo too, which a full part shows (its fill covers the line). */
.t-part:not([aria-disabled="true"]):hover .t-part-track { background: color-mix(in srgb, currentColor 32%, transparent); box-shadow: 0 0 0 2px color-mix(in srgb, currentColor 16%, transparent); }
.t-part[data-current]:hover .t-part-track { background: color-mix(in srgb, currentColor 46%, transparent); }
.t-part[aria-disabled="true"], #elabora-app[data-ended] .t-part { cursor: default; }
.t-part-fill { display: block; height: 100%; width: 100%; border-radius: inherit; translate: calc((var(--t-part, 0) - 100) * 1%) 0; background: var(--t-player-progress, currentColor); transition: translate var(--t-dur-modal) var(--t-ease-out); }
.t-part-fill:dir(rtl) { translate: calc((100 - var(--t-part, 0)) * 1%) 0; }
/* Focused, the ring goes around the line, not around the tall button. */
.t-bar .t-part:focus-visible { outline: none; }
.t-part:focus-visible .t-part-track { outline: 3px solid var(--t-focus); outline-offset: 2px; }

/* Buttons of the bars: a ghost (the outline), a chip (Ressources, Glossaire, Quitter), an icon (IA et
   crédits, the narration's tools), Previous and Next. Icons are 20 px, 16 px in chips. */
.t-bar-btn, .t-icon-btn, .t-nav-btn { display: inline-flex; align-items: center; justify-content: center; gap: 0.4375rem; flex: none; min-width: 0; padding: 0; border: 0; color: inherit; background: transparent; font: inherit; font-weight: 600; white-space: nowrap; cursor: pointer; }
.t-icon { display: inline-flex; flex: none; }
.t-icon svg { display: block; width: 1.25rem; height: 1.25rem; }
.t-bar-btn { height: var(--t-pl-btn); padding: 0 0.625rem; border-radius: var(--t-pl-radius); font-weight: 700; }
.t-bar-btn .t-icon svg { width: 1.0625rem; height: 1.0625rem; }
.t-bar-btn:hover, .t-icon-btn:hover { background: color-mix(in srgb, currentColor 9%, transparent); }
.t-bar-btn[aria-expanded="true"], .t-icon-btn[aria-expanded="true"] { background: color-mix(in srgb, currentColor 14%, transparent); }
.t-chip { height: 2.25rem; min-height: 32px; padding: 0 0.875rem; font-size: 0.875rem; font-weight: 600; background: color-mix(in srgb, currentColor 11%, transparent); }
.t-chip:hover { background: color-mix(in srgb, currentColor 18%, transparent); }
.t-chip .t-icon svg { width: 1rem; height: 1rem; }
.t-icon-btn { width: var(--t-pl-icon-btn); height: var(--t-pl-icon-btn); border-radius: 50%; }
.t-outline-btn { max-width: 18rem; }
.t-outline-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* With the part's or the screen's title as its label, one width for every screen (the full title in
   the tooltip when it is cut), so that nothing after it moves from one screen to the next. */
.t-outline-btn[data-label] { width: min(15rem, 24vw); justify-content: flex-start; }
.t-outline-btn[data-label] .t-outline-label { flex: 1; min-width: 0; text-align: start; }
.t-nav-btn { height: var(--t-pl-btn); padding: 0 1.25rem; border-radius: var(--t-pl-radius); font-weight: 700; box-shadow: inset 0 0 0 1.5px currentColor; }
.t-nav-btn .t-icon svg { width: 1.0625rem; height: 1.0625rem; }
.t-nav-btn--previous { padding-inline-start: 0.875rem; }
.t-nav-btn--next { padding-inline-end: 0.875rem; color: var(--t-pl-on-accent); background: var(--t-pl-accent); box-shadow: none; }
.t-nav-btn:hover { background: color-mix(in srgb, currentColor 8%, transparent); }
.t-nav-btn--next:hover { background: color-mix(in srgb, var(--t-pl-accent) 86%, var(--t-pl-bottom-fg)); }
/* Unavailable: greyed in place, the same size; the tooltip says why. */
.t-nav-btn[aria-disabled="true"] { cursor: default; opacity: .42; }
.t-nav-btn[aria-disabled="true"]:hover { background: transparent; }
.t-nav-btn--next[aria-disabled="true"]:hover { background: var(--t-pl-accent); }
/* Next and Continue in one cell: the button is as wide as the longer label. */
.t-nav-labels { display: inline-grid; }
.t-nav-labels > .t-nav-label { grid-area: 1 / 1; text-align: center; }
.t-nav-labels > [aria-hidden="true"] { visibility: hidden; }
.t-bar :focus-visible { outline: 3px solid var(--t-focus); outline-offset: 2px; }
.t-bar--top :focus-visible { outline-color: var(--t-pl-top-fg); }

/* « Espace flexible » (D58): before it, the start of the line; after it, the end. The controls
   stretch first, the spacer takes what remains; in a bar with a spacer the title keeps its width. */
.t-item--spacer { flex: 1 1 0; min-width: 0; }
.t-bar:has(> .t-item--controls) > .t-item--spacer { flex-grow: 0.0001; }
.t-bar[data-spacer] > .t-item--title { flex: 0 1 auto; }
/* The logo on a light plate (option plate). */
.t-item--plate { padding: 0.25rem 0.625rem; border-radius: min(var(--t-pl-radius), 10px); background: #fff; }
.t-item--plate .t-logo { max-height: calc(var(--t-pl-top-h) - 2rem); }
.t-item--plate .t-logo[src$=".svg" i] { height: calc(var(--t-pl-top-h) - 2rem); }
/* « IA et crédits » with a generated voice or generated media: « IA » instead of « i ». */
.t-ai-mark { font: 800 0.8125rem/1 var(--t-font-body); letter-spacing: .04em; }
.t-about-btn[data-ai] { box-shadow: inset 0 0 0 1.5px color-mix(in srgb, currentColor 30%, transparent); }
/* « Langue » and « Affichage »: small menus from their buttons, like the outline. */
.t-item--language, .t-item--display { position: relative; }
.t-language-btn .t-icon:last-child svg { width: 0.875rem; height: 0.875rem; }
.t-pop { position: absolute; inset-inline-end: 0; z-index: 7; width: max-content; min-width: 14rem; max-width: min(22rem, calc(100vw - 2rem)); padding: 0.375rem; border-radius: 14px; color: var(--t-text); background: var(--t-surface); box-shadow: 0 0 0 1px color-mix(in srgb, var(--t-text) 9%, transparent), 0 12px 32px rgb(15 23 42 / .18); font-size: 0.9375rem; font-weight: 400; }
.t-pop[hidden] { display: none; }
/* A popover (Affichage, the language, the timeline's speeds and more) grows from its button and shrinks
   back to it; a menu (the outline) opens at once and shrinks back. Their origin is their button's side,
   written next to where they are placed. */
.t-pop, .t-timeline-popup { transition: opacity var(--t-dur-pop) var(--t-ease-out), scale var(--t-dur-pop) var(--t-ease-out), display var(--t-dur-pop) allow-discrete; }
:is(.t-pop, .t-timeline-popup)[hidden] { opacity: 0; scale: calc(1 - .05 * var(--t-move)); }
@starting-style { :is(.t-pop, .t-timeline-popup):not([hidden]) { opacity: 0; scale: calc(1 - .05 * var(--t-move)); } }
.t-bar--bottom :is(.t-pop, .t-timeline-popup) { transform-origin: bottom right; }
.t-bar--top :is(.t-pop, .t-timeline-popup) { transform-origin: top right; }
.t-bar--bottom .t-pop[data-align="start"], .t-bar--bottom :is(.t-pop, .t-timeline-popup):dir(rtl) { transform-origin: bottom left; }
.t-bar--top .t-pop[data-align="start"], .t-bar--top :is(.t-pop, .t-timeline-popup):dir(rtl) { transform-origin: top left; }
.t-pop[data-align="start"], .t-menu[data-align="start"] { inset-inline-start: 0; inset-inline-end: auto; }
.t-pop[data-align="end"], .t-menu[data-align="end"] { inset-inline-start: auto; inset-inline-end: 0; }
.t-bar--bottom .t-pop { bottom: calc(100% + 0.75rem); }
.t-bar--top .t-pop { top: calc(100% + 0.75rem); }
.t-pop-head { margin: 0.5rem 0.75rem 0.375rem; font-size: 0.75rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--t-muted); }
.t-pop-item, .t-pop-row { display: flex; align-items: center; gap: 0.625rem; width: 100%; min-height: max(40px, 2.5rem); padding: 0.375rem 0.75rem; border: 0; border-radius: 9px; background: transparent; color: var(--t-text); font: inherit; text-align: start; }
.t-pop-item { cursor: pointer; }
.t-pop-item:hover { background: color-mix(in srgb, var(--t-text) 6%, transparent); }
.t-pop-item[aria-checked="true"] { font-weight: 650; }
.t-pop-item > span:not(.t-icon) { flex: 1; }
.t-pop-item > .t-icon, .t-pop-row > .t-icon { flex: none; }
.t-pop-item .t-icon svg, .t-pop-row > .t-icon svg { width: 1.125rem; height: 1.125rem; }
.t-pop-label { flex: 1; min-width: 0; white-space: nowrap; }
.t-pop-sep { margin: 0.25rem 0.5rem; border: 0; border-top: 1px solid color-mix(in srgb, var(--t-text) 10%, transparent); }
.t-display-sizes { display: inline-flex; gap: 0.25rem; }
.t-display-size { display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 30px; border: 0; border-radius: 8px; font-family: var(--t-font-body); font-weight: 700; color: var(--t-primary); background: transparent; box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--t-text) 16%, transparent); cursor: pointer; }
.t-display-size--normal { font-size: 12px; } .t-display-size--large { font-size: 15px; } .t-display-size--larger { font-size: 18px; }
.t-display-size[aria-checked="true"] { color: var(--t-on-primary); background: var(--t-primary); box-shadow: none; }
.t-switch { position: relative; flex: none; width: 36px; height: 22px; padding: 0; border: 0; border-radius: 11px; background: color-mix(in srgb, var(--t-text) 22%, transparent); cursor: pointer; transition: background var(--t-dur-press) ease; }
.t-switch-knob { position: absolute; top: 3px; left: 3px; width: 16px; height: 16px; border-radius: 50%; background: #fff; box-shadow: 0 1px 2px rgb(15 23 42 / .3); transition: translate var(--t-dur-press) var(--t-ease-out); }
.t-switch[aria-checked="true"] { background: var(--t-primary); }
.t-switch[aria-checked="true"] .t-switch-knob { translate: 14px 0; }
.t-display-keys { display: grid; grid-template-columns: auto 1fr; gap: 0.375rem 0.75rem; margin: 0.25rem 0.75rem 0.5rem; font-size: 0.875rem; }
.t-display-keys[hidden] { display: none; }
.t-display-keys dt { white-space: nowrap; }
.t-display-keys dd { margin: 0; color: var(--t-muted); }
.t-display-keys kbd { padding: 0.0625rem 0.375rem; margin-inline-end: 0.25rem; border-radius: 5px; font: 600 0.75rem/1.4 var(--t-font-mono, ui-monospace, monospace); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--t-text) 20%, transparent); }
/* The editor's preview (the canvas with chrome=live, the app's « Lecteur » tab): the item of the
   bars the author points at. A spacer shows its room, however small. */
.t-item[data-t-highlight] { outline: 2px dashed currentColor; outline-offset: 3px; border-radius: 8px; }
.t-item--spacer[data-t-highlight] { min-width: 2rem; align-self: stretch; background: color-mix(in srgb, currentColor 14%, transparent); }
/* The learner's text size (« Affichage »): the screen and the layers over it grow, the bars do not move. Scroll pages
   reflow; a slide grows as a whole, and scrolls when it no longer fits. */
#elabora-app[data-text-size="large"] #t-main, body:has(> #elabora-app[data-text-size="large"]) > dialog.t-layer > .t-blocks { zoom: 1.15; }
#elabora-app[data-text-size="larger"] #t-main, body:has(> #elabora-app[data-text-size="larger"]) > dialog.t-layer > .t-blocks { zoom: 1.3; }
#elabora-app[data-captions="large"] .t-timeline-caption { font-size: 1.75rem; }

/* The outline: a menu over the screen from its button, upwards in the bottom bar. */
.t-item--outline { position: relative; }
.t-menu { position: absolute; inset-inline-start: 0; z-index: 7; width: min(24rem, calc(100vw - 2rem)); max-height: calc(100vh - var(--t-bar-top, 0px) - var(--t-bar-bottom, 0px) - 2rem); max-height: calc(100dvh - var(--t-bar-top, 0px) - var(--t-bar-bottom, 0px) - 2rem); overflow-y: auto; padding: 0.375rem; border-radius: 14px; color: var(--t-text); background: var(--t-surface); box-shadow: 0 0 0 1px color-mix(in srgb, var(--t-text) 9%, transparent), 0 12px 32px rgb(15 23 42 / .18); font-size: 0.9375rem; font-weight: 400; }
.t-bar--bottom .t-menu { bottom: calc(100% + 0.75rem); }
.t-bar--top .t-menu { top: calc(100% + 0.75rem); }
.t-menu[hidden] { opacity: 0; scale: calc(1 - .05 * var(--t-move)); transition: opacity var(--t-dur-pop) ease, scale var(--t-dur-pop) var(--t-ease-out), display var(--t-dur-pop) allow-discrete; }
.t-bar--bottom .t-menu { transform-origin: bottom left; }
.t-bar--top .t-menu { transform-origin: top left; }
.t-bar--bottom .t-menu[data-align="end"], .t-bar--bottom .t-menu:dir(rtl) { transform-origin: bottom right; }
.t-bar--top .t-menu[data-align="end"], .t-bar--top .t-menu:dir(rtl) { transform-origin: top right; }
.t-menu-where { margin: 0.5rem 0.75rem 0.25rem; font-size: 0.8125rem; color: var(--t-muted); font-variant-numeric: tabular-nums; }
.t-menu h2 { margin: 0.625rem 0.75rem 0.25rem; font-family: var(--t-font-body); font-size: 0.75rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--t-muted); }
.t-menu ul { list-style: none; margin: 0; padding: 0; }
.t-menu-item { display: flex; align-items: center; gap: 0.625rem; width: 100%; min-height: max(40px, 2.5rem); padding: 0.375rem 0.75rem; border: 0; border-radius: 9px; background: transparent; color: var(--t-text); font: inherit; line-height: 1.35; text-align: start; cursor: pointer; }
.t-menu-item:hover { background: color-mix(in srgb, var(--t-text) 6%, transparent); }
.t-menu-item[aria-current="page"] { background: color-mix(in srgb, var(--t-primary) 10%, var(--t-surface)); font-weight: 650; }
.t-menu-item[aria-disabled="true"] { color: var(--t-muted); cursor: not-allowed; }
.t-menu-item[aria-disabled="true"]:hover { background: transparent; }
.t-menu-mark { display: inline-flex; align-items: center; justify-content: center; flex: none; width: 1.125rem; height: 1.125rem; color: var(--t-primary); }
.t-menu-mark .t-icon svg { width: 1.125rem; height: 1.125rem; }
.t-menu-item[data-state="locked"] .t-menu-mark { color: var(--t-muted); }
.t-menu-ring { width: 0.875rem; height: 0.875rem; border-radius: 50%; box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--t-text) 35%, transparent); }
.t-menu-text { min-width: 0; }

/* The one tooltip: refusals, hints, the seek bar's quote, glossary definitions (WCAG 1.4.13). */
.t-tip { position: fixed; z-index: 40; max-width: min(28rem, calc(100vw - 16px)); padding: 0.3125rem 0.625rem; border-radius: 8px; color: var(--t-pl-tip-fg); background: var(--t-pl-tip-bg); box-shadow: 0 4px 14px rgb(15 23 42 / .22); font: 600 0.8125rem/1.4 var(--t-font-body); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; transition: opacity var(--t-dur-tip) ease, scale var(--t-dur-tip) ease, display var(--t-dur-tip) allow-discrete; }
.t-tip--wrap { width: max-content; max-width: min(22rem, calc(100vw - 16px)); white-space: normal; font-weight: 500; padding: 0.4375rem 0.75rem; }
.t-tip[hidden] { opacity: 0; scale: calc(1 - .03 * var(--t-move)); }
@starting-style { .t-tip:not([hidden]) { opacity: 0; scale: calc(1 - .03 * var(--t-move)); } }

/* Side panels: Resources, Glossary, « IA et crédits », the transcript. Over the screen from the end of
   the line, between the bars that stay in the window; a sheet from the bottom on phones. */
.t-sheet { position: fixed; z-index: 8; inset-block: var(--t-bar-top, 0px) var(--t-bar-bottom, 0px); inset-inline-end: 0; display: flex; flex-direction: column; width: min(26.25rem, 100vw); color: var(--t-text); background: var(--t-surface); box-shadow: -1px 0 0 color-mix(in srgb, var(--t-text) 10%, transparent), -14px 0 32px rgb(15 23 42 / .1); font-family: var(--t-font-body); transition: translate var(--t-dur-drawer) var(--t-ease-drawer), opacity var(--t-dur-drawer) var(--t-ease-drawer), display var(--t-dur-drawer) allow-discrete; }
.t-sheet[hidden] { translate: 100% 0; }
@starting-style { .t-sheet:not([hidden]) { translate: 100% 0; } }
.t-sheet:dir(rtl)[hidden] { translate: -100% 0; }
@starting-style { .t-sheet:dir(rtl):not([hidden]) { translate: -100% 0; } }
.t-sheet-head { display: flex; align-items: center; gap: 0.5rem; flex: none; min-height: 3.75rem; padding: 0.5rem 0.75rem 0.5rem 1.625rem; box-shadow: inset 0 -1px 0 color-mix(in srgb, var(--t-text) 9%, transparent); }
.t-sheet-title { flex: 1; margin: 0; font-family: var(--t-font-body); font-size: 1.0625rem; font-weight: 700; color: var(--t-text); }
.t-sheet-title:focus { outline: none; }
.t-sheet-body { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 0.75rem 1.125rem 1.5rem; }
.t-sheet .t-icon-btn { color: var(--t-text); }
@media (max-width: 760px) {
  .t-sheet { inset: auto 0 0 0; width: auto; max-height: 78vh; max-height: 78dvh; border-radius: 16px 16px 0 0; box-shadow: 0 -10px 30px rgb(15 23 42 / .16); }
  .t-sheet[hidden], .t-sheet:dir(rtl)[hidden] { translate: 0 100%; }
  @starting-style { .t-sheet:not([hidden]), .t-sheet:dir(rtl):not([hidden]) { translate: 0 100%; } }
}

/* Resources: a list of files; a PDF opens in the preview, any other file downloads. */
.t-resource-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.375rem; }
.t-resource { display: flex; align-items: center; gap: 0.875rem; width: 100%; padding: 0.75rem 0.75rem 0.75rem 0.625rem; border: 0; border-radius: 12px; color: var(--t-text); background: transparent; font: inherit; text-align: start; text-decoration: none; cursor: pointer; }
.t-resource:hover { background: color-mix(in srgb, var(--t-text) 5%, transparent); }
.t-resource-icon { display: inline-flex; align-items: center; justify-content: center; flex: none; width: 2.5rem; height: 2.5rem; border-radius: 10px; color: var(--t-primary); background: color-mix(in srgb, var(--t-primary) 10%, var(--t-surface)); }
.t-resource-text { display: flex; flex-direction: column; flex: 1; min-width: 0; line-height: 1.35; }
.t-resource-title { font-weight: 650; }
.t-resource-description { margin-top: 0.125rem; font-size: 0.875rem; color: var(--t-muted); }
.t-resource-info { margin-top: 0.1875rem; font-size: 0.8125rem; color: var(--t-muted); font-variant-numeric: tabular-nums; }
.t-resource-action { display: inline-flex; color: var(--t-muted); }
/* The preview of a PDF: over the module, its head with « Télécharger ». */
.t-viewer { width: min(72rem, calc(100vw - 2.5rem)); height: calc(100vh - 2.5rem); height: calc(100dvh - 2.5rem); max-width: none; max-height: none; margin: auto; padding: 0; border: 0; border-radius: 14px; color: var(--t-text); background: var(--t-surface); box-shadow: 0 24px 64px rgb(15 23 42 / .32); overflow: hidden; font-family: var(--t-font-body); }
.t-viewer[open] { display: flex; flex-direction: column; }
.t-viewer::backdrop { background: rgb(15 23 42 / .55); }
.t-viewer-head { display: flex; align-items: center; gap: 1rem; flex: none; min-height: 4rem; padding: 0.625rem 0.75rem 0.625rem 1.5rem; box-shadow: inset 0 -1px 0 color-mix(in srgb, var(--t-text) 10%, transparent); }
.t-viewer-name { display: flex; flex-direction: column; flex: 1; min-width: 0; }
.t-viewer-title { margin: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: var(--t-font-body); font-size: 1.0625rem; font-weight: 700; }
.t-viewer-title:focus { outline: none; }
.t-viewer-actions { display: flex; align-items: center; gap: 0.375rem; color: var(--t-text); --t-pl-bottom-fg: var(--t-text); }
.t-viewer-download { text-decoration: none; margin-inline-end: 0.375rem; }
.t-viewer-body { position: relative; flex: 1; min-height: 0; background: color-mix(in srgb, var(--t-text) 6%, var(--t-surface)); }
.t-viewer-frame { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.t-viewer-image { position: absolute; inset: 0; width: 100%; height: 100%; padding: 1.5rem; object-fit: contain; }
.t-viewer-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0.75rem; height: 100%; padding: 2rem; text-align: center; color: var(--t-muted); }
.t-viewer-empty .t-icon svg { width: 3rem; height: 3rem; }
.t-viewer :focus-visible { outline: 3px solid var(--t-focus); outline-offset: 2px; }

/* Glossary: search, then the entries in alphabetical order. */
.t-glossary-search { position: sticky; top: -0.75rem; z-index: 1; display: flex; align-items: center; gap: 0.5rem; margin: -0.75rem -1.125rem 0.5rem; padding: 0.75rem 1.125rem 0.625rem; background: var(--t-surface); color: var(--t-muted); }
.t-glossary-search .t-icon { position: absolute; inset-inline-start: 1.875rem; pointer-events: none; }
.t-glossary-search .t-icon svg { width: 1.125rem; height: 1.125rem; }
.t-glossary-input { width: 100%; min-height: 44px; padding: 0 0.875rem 0 2.5rem; border: 1px solid color-mix(in srgb, var(--t-text) 18%, transparent); border-radius: 10px; color: var(--t-text); background: var(--t-surface); font: inherit; font-size: max(1em, 16px); }
.t-glossary-count { margin: 0 0.25rem 0.5rem; font-size: 0.8125rem; color: var(--t-muted); }
.t-glossary-count:empty { display: none; }
.t-glossary-list { margin: 0; }
.t-glossary-entry { padding: 0.75rem 0.5rem; border-radius: 10px; box-shadow: inset 0 -1px 0 color-mix(in srgb, var(--t-text) 8%, transparent); scroll-margin-block: 4rem; }
.t-glossary-entry[data-t-found] { background: color-mix(in srgb, var(--t-primary) 10%, var(--t-surface)); transition: background .4s ease; }
.t-glossary-entry dt { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.25rem 0.5rem; }
.t-glossary-term { font-weight: 700; }
.t-glossary-variants { font-size: 0.8125rem; color: var(--t-muted); }
.t-glossary-entry dd { margin: 0.25rem 0 0; line-height: 1.5; }
/* A term of a screen's text that links to its entry: dotted, its definition in the tooltip. */
.t-term { color: inherit; text-decoration: underline dotted color-mix(in srgb, currentColor 55%, transparent); text-decoration-thickness: 1.5px; text-underline-offset: 0.2em; cursor: help; }
.t-term:hover { text-decoration-color: currentColor; }

/* « IA et crédits » */
.t-about-section + .t-about-section { margin-top: 1.25rem; padding-top: 1rem; box-shadow: inset 0 1px 0 color-mix(in srgb, var(--t-text) 9%, transparent); }
.t-about-heading { margin: 0.25rem 0.25rem 0.625rem; font-family: var(--t-font-body); font-size: 0.75rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--t-muted); }
.t-about-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.5rem; }
.t-about-ai { display: flex; align-items: flex-start; gap: 0.625rem; padding: 0.625rem 0.75rem; border-radius: 10px; background: color-mix(in srgb, var(--t-primary) 7%, var(--t-surface)); line-height: 1.4; }
.t-about-ai .t-icon { color: var(--t-primary); margin-top: 0.0625rem; }
.t-about-ai .t-icon svg { width: 1.125rem; height: 1.125rem; }
.t-about-ai-text { display: block; font-weight: 650; }
.t-about-ai-detail { display: block; margin-top: 0.125rem; font-size: 0.875rem; color: var(--t-muted); }
.t-about-credits p { margin: 0 0.25rem 0.5rem; font-size: 0.875rem; line-height: 1.5; overflow-wrap: anywhere; }
.t-about-credits a { color: inherit; }

/* After Quit: the bars keep the course's identity and nothing to press. */
#elabora-app[data-ended] .t-bar--bottom, #elabora-app[data-ended] .t-bar--controls,
#elabora-app[data-ended] .t-bar--top > .t-item:not(.t-item--logo, .t-item--title, .t-item--progress) { display: none; }

/* ── Narrated screens: the bar, captions and transcript (D24, D28) ──────────────────────────────
   In the controls item, the bar of Lin 27: Play (filled), Replay, the seek bar (dotted where not
   heard yet), the time, a separator, Captions, the settings, the volume, the transcript. */
.t-controls { display: flex; align-items: center; flex: 1 1 auto; min-width: 0; }
.t-item--controls:has(.t-timeline):not(:first-child) { padding-inline-start: 0.75rem; box-shadow: inset 1px 0 0 color-mix(in srgb, var(--t-pl-bottom-fg) 14%, transparent); }
.t-item--controls:has(.t-timeline):not(:last-child) { padding-inline-end: 0.75rem; box-shadow: inset -1px 0 0 color-mix(in srgb, var(--t-pl-bottom-fg) 14%, transparent); }
.t-item--controls:has(.t-timeline):not(:first-child):not(:last-child) { box-shadow: inset 1px 0 0 color-mix(in srgb, var(--t-pl-bottom-fg) 14%, transparent), inset -1px 0 0 color-mix(in srgb, var(--t-pl-bottom-fg) 14%, transparent); }
.t-timeline { display: flex; align-items: center; gap: 0.125rem; flex: 1 1 auto; min-width: 0; min-height: var(--t-pl-btn); }
.t-timeline-btn { position: relative; display: inline-flex; align-items: center; justify-content: center; flex: none; width: var(--t-pl-icon-btn); height: var(--t-pl-icon-btn); padding: 0; border: 0; border-radius: 50%; color: inherit; background: transparent; font: inherit; font-weight: 700; cursor: pointer; }
.t-timeline-btn:hover { background: color-mix(in srgb, currentColor 9%, transparent); }
.t-timeline-btn[aria-pressed="true"], .t-timeline-btn[aria-expanded="true"] { background: color-mix(in srgb, currentColor 13%, transparent); }
.t-timeline-play { width: var(--t-pl-btn); height: var(--t-pl-btn); color: var(--t-pl-on-accent); background: var(--t-pl-accent); }
.t-timeline-play:hover { background: color-mix(in srgb, var(--t-pl-accent) 86%, var(--t-pl-bottom-fg)); }
.t-timeline-play .t-icon svg { width: 1.125rem; height: 1.125rem; }
.t-timeline-play[data-state="paused"] .t-icon { margin-inline-start: 2px; }
.t-timeline-rate-badge { position: absolute; inset-inline-end: -0.125rem; bottom: 0.125rem; padding: 0 0.1875rem; border-radius: 4px; font-size: 0.625rem; line-height: 1.35; font-variant-numeric: tabular-nums; color: var(--t-pl-on-accent); background: var(--t-pl-accent); }
.t-timeline-rate-badge:empty { display: none; }
.t-timeline-seek { position: relative; flex: 1 1 8rem; display: flex; align-items: center; min-width: 5rem; height: 2.25rem; margin: 0 0.625rem; cursor: pointer; touch-action: none; }
.t-timeline-seek:focus-visible, .t-timeline-btn:focus-visible { outline: 3px solid var(--t-focus); outline-offset: 2px; }
.t-timeline-seek:focus-visible { border-radius: 6px; }
/* The track: dotted where not heard yet, solid where heard, filled up to the playhead; a mark at
   each step's end. */
.t-timeline-track { position: relative; width: 100%; height: 6px; background: radial-gradient(circle, color-mix(in srgb, var(--t-pl-bottom-fg) 42%, transparent) 1.3px, transparent 1.8px) 0 50% / 7px 6px repeat-x; }
[data-seek="free"] .t-timeline-track { border-radius: 3px; background: color-mix(in srgb, var(--t-pl-accent) 18%, var(--t-pl-bottom-bg)); }
.t-timeline-seen, .t-timeline-played { position: absolute; inset: 0 auto 0 0; border-radius: 3px; }
.t-timeline-seen { background: color-mix(in srgb, var(--t-pl-accent) 18%, var(--t-pl-bottom-bg)); }
.t-timeline-played { background: var(--t-pl-accent); }
.t-timeline-mark { position: absolute; top: -4px; width: 6px; height: 14px; transform: translateX(-3px); background: linear-gradient(to right, var(--t-pl-bottom-bg) 0 2px, color-mix(in srgb, var(--t-pl-bottom-fg) 40%, transparent) 2px 4px, var(--t-pl-bottom-bg) 4px); }
.t-timeline-thumb { position: absolute; top: 50%; width: 18px; height: 18px; border-radius: 50%; background: var(--t-pl-accent); box-shadow: 0 0 0 3px var(--t-pl-bottom-bg), 0 1px 4px rgb(15 23 42 / .3); transform: translate(-50%, -50%); transition: scale var(--t-dur-press) var(--t-ease-out); }
.t-timeline-seek:active .t-timeline-thumb { scale: 1.22; }
@media (hover: hover) and (pointer: fine) { .t-timeline-seek:hover .t-timeline-thumb { scale: 1.22; } }
.t-timeline-time { flex: none; padding: 0 0.5rem 0 0.25rem; font-size: 0.875rem; font-weight: 500; font-variant-numeric: tabular-nums; white-space: nowrap; opacity: .85; }
.t-timeline-tools { display: inline-flex; align-items: center; gap: 0.125rem; margin-inline-start: 0.25rem; padding-inline-start: 0.625rem; box-shadow: inset 1px 0 0 color-mix(in srgb, var(--t-pl-bottom-fg) 14%, transparent); }
.t-timeline-anchor { position: relative; display: inline-flex; }
.t-timeline-anchor[hidden] { display: none; }
/* The volume's slider, above its button while the pointer or the focus is there (it moves nothing). */
.t-timeline-volume { position: relative; display: inline-flex; }
.t-timeline-volume[hidden] { display: none; }
.t-timeline-volume-pop { position: absolute; bottom: calc(100% + 0.375rem); left: 50%; z-index: 7; display: flex; padding: 0.75rem 0.5rem; border-radius: 12px; background: var(--t-surface); box-shadow: 0 0 0 1px color-mix(in srgb, var(--t-text) 9%, transparent), 0 8px 24px rgb(15 23 42 / .18); translate: -50% calc(4px * var(--t-move)); opacity: 0; visibility: hidden; transition: opacity var(--t-dur-pop) var(--t-ease-out), translate var(--t-dur-pop) var(--t-ease-out), visibility var(--t-dur-pop); }
.t-timeline-volume:hover .t-timeline-volume-pop, .t-timeline-volume:focus-within .t-timeline-volume-pop { opacity: 1; visibility: visible; translate: -50% 0; }
.t-timeline-volume-range { width: 1.5rem; height: 6rem; margin: 0; writing-mode: vertical-lr; direction: rtl; accent-color: var(--t-pl-accent); cursor: pointer; }
.t-timeline-more-menu .t-timeline-volume-pop { display: none; }
/* The settings and « … »: menus above their button. */
.t-timeline-popup { position: absolute; inset-inline-end: 0; bottom: calc(100% + 0.625rem); z-index: 7; display: flex; flex-direction: column; min-width: 16rem; padding: 0.375rem; border-radius: 14px; color: var(--t-text); background: var(--t-surface); box-shadow: 0 0 0 1px color-mix(in srgb, var(--t-text) 9%, transparent), 0 12px 32px rgb(15 23 42 / .18); font-size: 0.9375rem; font-weight: 400; }
.t-timeline-popup[hidden] { display: none; }
.t-timeline-popup fieldset { display: flex; flex-direction: column; margin: 0; padding: 0; border: 0; }
.t-timeline-popup legend { padding: 0.5rem 0.75rem 0.25rem; font-size: 0.75rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--t-muted); }
.t-timeline-option { position: relative; display: flex; align-items: center; gap: 0.625rem; width: 100%; min-height: max(40px, 2.5rem); padding: 0.375rem 0.75rem; border: 0; border-radius: 9px; color: inherit; background: none; font: inherit; text-align: start; font-variant-numeric: tabular-nums; cursor: pointer; }
.t-timeline-option:hover { background: color-mix(in srgb, var(--t-text) 6%, transparent); }
.t-timeline-speeds .t-timeline-option input { position: absolute; opacity: 0; pointer-events: none; }
.t-timeline-speeds .t-timeline-option:has(input:focus-visible) { outline: 3px solid var(--t-focus); outline-offset: -3px; }
.t-timeline-option-text { flex: 1; }
.t-timeline-option-check { color: var(--t-primary); visibility: hidden; }
.t-timeline-option:has(input:checked) .t-timeline-option-check { visibility: visible; }
.t-timeline-option:has(input:checked) { font-weight: 650; }
.t-timeline-option input[type="checkbox"] { margin: 0.2em 0 0; accent-color: var(--t-primary); align-self: flex-start; }
.t-timeline-stop { align-items: flex-start; line-height: 1.35; }
.t-timeline-stop small { display: block; margin-top: 0.125rem; font-size: 0.8125rem; color: var(--t-muted); }
.t-timeline-speeds + .t-timeline-stop, .t-timeline-speeds + .t-timeline-keys-btn, .t-timeline-stop + .t-timeline-keys-btn { margin-top: 0.375rem; box-shadow: 0 -1px 0 color-mix(in srgb, var(--t-text) 9%, transparent); border-radius: 0 0 9px 9px; }
.t-timeline-more-menu { min-width: 0; flex-direction: row; gap: 0.125rem; }
.t-timeline-more-menu .t-timeline-anchor { position: static; }
.t-timeline-more-menu .t-timeline-btn { color: var(--t-text); }
/* The keyboard shortcuts (Shift+? on the bar). */
.t-timeline-keys { inset-inline-end: 0.75rem; min-width: min(24rem, calc(100vw - 1.5rem)); padding: 0.75rem 1rem 1rem; }
.t-timeline-popup-head { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; }
.t-timeline-keys-title { margin: 0; font-family: var(--t-font-body); font-size: 1.0625rem; }
.t-timeline-keys-title:focus { outline: none; }
.t-timeline-keys dl { display: grid; grid-template-columns: max-content 1fr; gap: 0.375rem 0.75rem; margin: 0.5rem 0 0; }
.t-timeline-keys dt { display: flex; gap: 0.25rem; }
.t-timeline-keys dd { margin: 0; }
.t-timeline-keys kbd { padding: 0 0.375rem; font: inherit; font-size: 0.8125rem; border: 1px solid color-mix(in srgb, var(--t-text) 25%, transparent); border-radius: 4px; }
/* Captions: a band laid over the bottom of the screen, above the bar; it moves nothing. */
.t-timeline-band { position: absolute; left: 50%; bottom: calc(100% + 1.25rem); z-index: 3; width: min(66%, 56rem); text-align: center; transform: translateX(-50%); pointer-events: none; }
.t-timeline-caption { display: inline; padding: 0.375rem 1.125rem 0.5rem; border-radius: 10px; font: 500 1.25rem/1.6 var(--t-font-body); color: #fff; background: rgb(19 38 58 / 0.9); -webkit-box-decoration-break: clone; box-decoration-break: clone; }
.t-timeline-caption .t-timeline-speaker { font-weight: 700; color: color-mix(in srgb, var(--t-accent) 45%, #fff); }
/* The transcript: a side panel; the line said marked. */
.t-timeline-generated { display: flex; align-items: center; gap: 0.5rem; margin: 0 0.25rem 0.5rem; font-size: 0.8125rem; color: var(--t-muted); }
.t-timeline-generated .t-icon svg { width: 1rem; height: 1rem; }
.t-timeline-transcript-step h3 { margin: 1rem 0.5rem 0.25rem; font-family: var(--t-font-body); font-size: 0.75rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--t-muted); }
.t-timeline-line { display: block; width: 100%; margin: 0 0 0.125rem; padding: 0.5rem 0.75rem 0.5625rem; border: 0; border-radius: 10px; color: inherit; background: none; font: inherit; line-height: 1.5; text-align: start; }
.t-timeline-line .t-timeline-speaker { display: block; font-size: 0.8125rem; font-weight: 700; color: var(--t-primary); }
button.t-timeline-line:not(:disabled) { cursor: pointer; }
button.t-timeline-line:not(:disabled):hover { background: color-mix(in srgb, var(--t-text) 5%, transparent); }
button.t-timeline-line:disabled { color: var(--t-muted); }
.t-timeline-line[aria-current] { background: color-mix(in srgb, var(--t-accent) 9%, var(--t-surface)); box-shadow: inset 3px 0 0 var(--t-accent); }
.t-timeline-credits { margin: 1rem 0.5rem 0; padding-top: 0.625rem; box-shadow: inset 0 1px 0 color-mix(in srgb, var(--t-text) 9%, transparent); font-size: 0.8125rem; color: var(--t-muted); }
.t-timeline-credits h3 { margin: 0 0 0.25rem; font-family: var(--t-font-body); font-size: 0.75rem; letter-spacing: .06em; text-transform: uppercase; }
.t-timeline-credits p { margin: 0 0 0.25rem; overflow-wrap: anywhere; }
.t-timeline-credits a { color: inherit; }
/* Sound refused before a gesture: one large Play button over the screen, inviting (Lin 27). */
.t-timeline-start { position: absolute; inset: 0; z-index: 5; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1rem; width: 100%; padding: 1.5rem; border: 0; font: inherit; color: var(--t-pl-accent); background: color-mix(in srgb, var(--t-surface) 72%, transparent); cursor: pointer; animation: t-fade-in var(--t-dur-pop) ease both; }
.t-timeline-start-circle { display: flex; align-items: center; justify-content: center; width: 6.5rem; height: 6.5rem; border-radius: 50%; color: var(--t-pl-on-accent); background: var(--t-pl-accent); box-shadow: 0 0 0 8px color-mix(in srgb, var(--t-pl-accent) 14%, transparent), 0 10px 28px rgb(15 23 42 / .28); transition: scale var(--t-dur-press) var(--t-ease-out); }
.t-timeline-start-circle .t-icon { margin-inline-start: 0.375rem; }
.t-timeline-start-circle .t-icon svg { width: 2.75rem; height: 2.75rem; }
@media (hover: hover) and (pointer: fine) { .t-timeline-start:hover .t-timeline-start-circle { scale: calc(1 + .05 * var(--t-move)); } }
.t-timeline-start:active .t-timeline-start-circle { scale: calc(1 - .03 * var(--t-move)); }
.t-timeline-start-label { font-size: 1.3125rem; font-weight: 700; }
.t-timeline-start:focus-visible { outline: none; }
.t-timeline-start:focus-visible .t-timeline-start-circle { outline: 3px solid var(--t-focus); outline-offset: 4px; }

/* Phones and narrow windows (player.ts narrow(): a tap on the progress opens the outline): chips keep their icon, the bar of a narrated screen takes its own row. */
@media (max-width: 760px) {
  .t-bar--top { padding: 0.25rem 0.5rem 0.25rem 1rem; }
  .t-bar[data-position="window"].t-bar--top { position: relative; }
  .t-bar--bottom { flex-wrap: wrap; padding: 0.5rem 0.75rem; gap: 0.5rem; }
  .t-chip { width: var(--t-pl-icon-btn); height: var(--t-pl-icon-btn); padding: 0; border-radius: 50%; }
  .t-chip-label, .t-outline-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .t-item--progress, .t-item--progress[data-parts] { flex-basis: 5rem; min-width: 4rem; }
  .t-progress--parts { gap: 2px; }
  .t-progress-value { display: none; }
  /* The controls' row is there on every screen of a course that has one (empty on the others), so
     the bar keeps its height from one screen to the next. */
  .t-item--controls { flex-basis: 100%; order: -1; min-height: max(var(--t-pl-btn), 3rem); padding-inline: 0; box-shadow: none !important; }
  .t-outline-btn[data-label] { width: auto; }
  /* On its line (the controls on theirs), the spacer takes what remains. */
  .t-item--spacer { flex-grow: 1 !important; }
  .t-timeline-time { display: none; }
  .t-timeline-seek { height: 3rem; }
  .t-timeline-thumb { width: 22px; height: 22px; }
  .t-nav-btn { padding: 0 1rem; }
}
/* The controls in the top bar: their popups open downward, and the captions stay over the bottom
   of the screen, above the bottom bar when there is one. */
.t-bar--top .t-timeline-popup { bottom: auto; top: calc(100% + 0.625rem); }
.t-bar--top .t-timeline-volume-pop { bottom: auto; top: calc(100% + 0.375rem); translate: -50% calc(-4px * var(--t-move)); }
.t-bar--top .t-timeline-volume:hover .t-timeline-volume-pop, .t-bar--top .t-timeline-volume:focus-within .t-timeline-volume-pop { translate: -50% 0; }
.t-bar--top .t-timeline-band { position: fixed; bottom: calc(var(--t-bar-bottom, 0px) + 1.25rem); }
/* A side panel open: captions stay in the room the screen has left. */
@media (min-width: 761px) { #elabora-app:has(> .t-sheet:not([hidden])) .t-timeline-band { left: calc((100% - min(26.25rem, 100vw)) / 2); width: min(60%, 48rem); } }
/* Less motion asked: what slides from an edge (a side sheet, a panel on a phone) fades in its place. */
@media (prefers-reduced-motion: reduce) {
  .t-sheet[hidden], .t-sheet:dir(rtl)[hidden], .t-panel:not([open]), .t-panel:dir(rtl):not([open]) { translate: none; opacity: 0; }
  @starting-style { .t-sheet:not([hidden]), .t-sheet:dir(rtl):not([hidden]), .t-panel[open], .t-panel[open]:dir(rtl) { translate: none; opacity: 0; } }
}
/* Less motion asked: what the course's authors wrote (themes, components, a block's own CSS) is stilled
   entirely, since the player cannot tell what in it moves; the player's own pieces keep their fades
   (--t-move). A step's revealed blocks keep theirs too: with --t-move at 0 it moves nothing; so do the
   faces of a flip card, whose turn becomes a cross-fade (D63). Pseudo-elements are named outside
   :is(), which cannot hold them (a layer's ::after would keep its fade). */
@media (prefers-reduced-motion: reduce) {
  :is(#t-main, dialog.t-layer, .t-backdrop) *, :is(#t-main, dialog.t-layer, .t-backdrop) ::before, :is(#t-main, dialog.t-layer, .t-backdrop) ::after { animation: none !important; }
  :is(#t-main, dialog.t-layer, .t-backdrop) *:not(.t-block[data-t-revealed], [data-t-card] [data-t-face]), :is(#t-main, dialog.t-layer, .t-backdrop) ::before, :is(#t-main, dialog.t-layer, .t-backdrop) ::after { transition: none !important; }
  /* The backdrop itself and the bars change with a variant at once too (a capture never takes them
     halfway). */
  :is(.t-backdrop, .t-bar), :is(.t-backdrop, .t-bar)::before, :is(.t-backdrop, .t-bar)::after, .t-bar *, .t-bar ::before, .t-bar ::after { transition: none !important; }
}

/* ── Primitives of any template (D63; docs/components.md §3) ──────────────────────────────────
   What shows one thing at a time keeps the room of its tallest thing: a sequence's items (the player
   sets the min-height of their container), a flip card's faces (both in one cell, so whichever shows,
   the card is as tall as its taller face). Interactions are soothing: --t-dur-item on the ease-out
   curve, no spring; with less motion a short fade, or nothing. Nothing moves by itself. */
:root { --t-dur-item: 220ms; }
/* A sequence: Previous and Next stay in reach at its ends (aria-disabled), a swipe sideways is the
   player's while the page keeps its vertical scroll. */
[data-t-sequence] [data-t-item] { touch-action: pan-y; }
:is([data-t-prev], [data-t-next])[aria-disabled="true"] { opacity: .4; cursor: default; }
/* A flip card turns on its vertical axis; the face away is out of reach (inert) and hidden. */
[data-t-card] { display: grid; perspective: 1600px; }
[data-t-card] [data-t-face] { grid-area: 1 / 1; backface-visibility: hidden; transition: rotate var(--t-dur-item) var(--t-ease-out), opacity var(--t-dur-item) ease; }
[data-t-card] [data-t-face="back"] { rotate: y 180deg; }
[data-t-card][data-t-flipped] [data-t-face="front"] { rotate: y -180deg; }
[data-t-card][data-t-flipped] [data-t-face="back"] { rotate: y 0deg; }
@media (prefers-reduced-motion: reduce) {
  [data-t-card] [data-t-face] { rotate: none !important; transition: opacity var(--t-dur-item) ease !important; }
  [data-t-card]:not([data-t-flipped]) [data-t-face="back"], [data-t-card][data-t-flipped] [data-t-face="front"] { opacity: 0; }
}
/* A native disclosure that is visited: its content fades in where the browser can. */
details[data-t-details]::details-content { opacity: 0; transition: opacity var(--t-dur-item) ease, content-visibility var(--t-dur-item) allow-discrete; }
details[data-t-details][open]::details-content { opacity: 1; }
/* The lightbox: the image at full size over the page (the viewer's frame and motion), its caption,
   previous and next between the images of the block, and Close. */
.t-lightbox { width: min(80rem, calc(100vw - 2.5rem)); }
.t-lightbox[open] { display: flex; flex-direction: column; }
.t-lightbox-stage { position: relative; flex: 1; min-height: 0; background: color-mix(in srgb, var(--t-text) 6%, var(--t-surface)); }
.t-lightbox-image { position: absolute; inset: 0; width: 100%; height: 100%; padding: 1.5rem; object-fit: contain; }
.t-lightbox-foot { display: flex; align-items: center; gap: 0.5rem; flex: none; min-height: 4rem; padding: 0.625rem 0.75rem 0.625rem 1.5rem; color: var(--t-text); box-shadow: inset 0 1px 0 color-mix(in srgb, var(--t-text) 10%, transparent); --t-pl-bottom-fg: var(--t-text); }
.t-lightbox-caption { flex: 1; min-width: 0; margin: 0; color: var(--t-text); font-size: 0.9375rem; line-height: 1.45; }
.t-lightbox-caption[hidden] { display: block !important; visibility: hidden; }
.t-lightbox-position { min-width: 3.5rem; color: var(--t-muted); font-size: 0.875rem; font-variant-numeric: tabular-nums; text-align: center; }
.t-lightbox .t-icon-btn[aria-disabled="true"] { opacity: .4; cursor: default; }
/* A Continue that waits for exploration says what is left under it; its line stays once unlocked. */
.t-continue-hint { margin: 0; color: var(--t-muted); font-size: 0.9375rem; text-align: center; }
.t-continue-hint[data-t-empty] { visibility: hidden; }

/* ── Steps (« Étapes », D63): a steps block, not the screen's steps ─────────────────────────────
   carousel: one step at a time in a card, its room the tallest step's (the sequence keeps it);
   timeline (« Frise »): the steps on a line, their dates before them, a dot that fills once seen;
   scroll (« Défilé »): the text scrolls beside a figure that follows it (data-t-follow). On wide places,
   with motion and the player, the figure stays in view while the step crossing the middle of the window
   decides what it shows; otherwise (a phone, a column, a slide, less motion, no script) each step shows
   its own picture above its words. Native scroll always; the figure changes by fading (opacity only). */
.t-block--steps, .t-block--hotspots { container-type: inline-size; }
:is(.t-screen > .t-blocks, .t-opening-body.t-slot) > .t-block:is(:has(> .t-steps--scroll, > .t-hotspots--side)) { max-width: var(--t-wide-width, 68.75rem); }
.t-steps { margin: 0; }
.t-steps-title { margin: 0 0 .5rem; font-size: 1.25rem; line-height: 1.3; }
.t-steps-body > :last-child { margin-bottom: 0; }
.t-steps-picture { margin: 0; }
.t-steps-picture img { display: block; width: 100%; height: auto; border-radius: var(--t-radius); }
.t-steps-number { display: inline-grid; place-items: center; min-width: 2rem; height: 2rem; margin: 0 0 .625rem; padding: 0 .5rem; border-radius: 999px; color: var(--t-primary); background: color-mix(in srgb, var(--t-primary) 13%, var(--t-surface)); font-weight: 700; font-size: .9375rem; line-height: 1; font-variant-numeric: tabular-nums; }
/* Previous, the steps, where the learner is, Next: the carousel's and the tour's. 44 px arrows; the
   steps as 24 px targets around a small dot (a step seen darker, the step shown in the course's colour). */
.t-steps-nav, .t-hotspots-nav { display: flex; align-items: center; gap: .75rem; }
.t-steps-arrow { display: inline-flex; flex: none; align-items: center; justify-content: center; width: 2.75rem; height: 2.75rem; padding: 0; border: 1px solid color-mix(in srgb, var(--t-text) 22%, transparent); border-radius: 50%; color: var(--t-text); background: var(--t-surface); cursor: pointer; transition: scale var(--t-dur-press) var(--t-ease-out); }
.t-steps-arrow svg { width: 1.25rem; height: 1.25rem; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.t-steps-arrow:not([aria-disabled="true"]):active { scale: calc(1 - .06 * var(--t-move)); }
.t-steps-dots { display: flex; flex-wrap: wrap; gap: .125rem; margin: 0; padding: 0; list-style: none; }
.t-steps-dot { display: grid; place-items: center; width: max(1.5rem, 24px); height: max(1.5rem, 24px); padding: 0; border: 0; border-radius: 50%; background: transparent; cursor: pointer; }
.t-steps-dot::before { content: ""; width: .625rem; height: .625rem; border-radius: 50%; background: color-mix(in srgb, var(--t-text) 22%, transparent); transition: background var(--t-dur-item) ease, scale var(--t-dur-item) var(--t-ease-out); }
.t-steps-dot--end::before { border-radius: 2px; }
.t-steps-dot[data-t-visited]::before { background: color-mix(in srgb, var(--t-text) 50%, transparent); }
.t-steps-dot[aria-current="true"]::before { background: var(--t-primary); scale: calc(1 + .25 * var(--t-move)); }
.t-steps-position { margin-inline-start: auto; color: var(--t-muted); font-size: .9375rem; font-variant-numeric: tabular-nums; }
/* carousel */
.t-steps--carousel { display: grid; gap: 1.25rem; padding: 1.5rem 1.75rem 1.25rem; border-radius: var(--t-radius); background: color-mix(in srgb, var(--t-primary) 5%, var(--t-surface)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--t-text) 8%, transparent); }
.t-steps--carousel .t-steps-item { display: grid; gap: 1.25rem; align-content: start; }
.t-steps--carousel .t-steps-picture img { max-height: 18rem; object-fit: contain; }
.t-steps-start { margin-top: 1.25rem; }
@container (min-width: 560px) { .t-steps--carousel .t-steps-item:has(> .t-steps-picture) { grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr); align-items: start; } }
@container (max-width: 420px) {
  .t-steps--carousel { padding: 1.125rem 1rem 1rem; }
  .t-steps--carousel .t-steps-dots { display: none; }
}
/* timeline: date | line and dot | words; on narrow places the date above the words. */
.t-steps--timeline { --t-steps-date: 8.5rem; list-style: none; margin: 0; padding: 0; display: grid; }
.t-steps--timeline:not(:has(.t-steps-date)) { --t-steps-date: 0rem; }
.t-steps-event { position: relative; display: grid; grid-template-columns: var(--t-steps-date) 2.75rem minmax(0, 1fr); padding-bottom: 2.25rem; }
.t-steps-event:last-child { padding-bottom: 0; }
.t-steps-date { grid-column: 1; margin: .1rem 0 0; color: var(--t-primary); font-weight: 700; font-size: 1.0625rem; line-height: 1.35; text-align: end; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.t-steps-event > .t-steps-words { grid-column: 3; }
.t-steps-event .t-steps-picture { margin: .25rem 0 .75rem; }
.t-steps-event .t-steps-picture img { max-height: 16rem; width: auto; max-width: 100%; }
.t-steps-event::before { content: ""; position: absolute; inset-block: 1.25rem -.25rem; inset-inline-start: calc(var(--t-steps-date) + 1.375rem - 1px); width: 2px; border-radius: 1px; background: color-mix(in srgb, var(--t-text) 14%, transparent); transition: background var(--t-dur-reveal) ease; }
.t-steps-event:last-child::before { display: none; }
.t-steps-event::after { content: ""; position: absolute; inset-block-start: .4rem; inset-inline-start: calc(var(--t-steps-date) + 1.375rem - 7px); width: 14px; height: 14px; box-sizing: border-box; border: 2px solid var(--t-primary); border-radius: 50%; background: var(--t-surface); transition: background var(--t-dur-reveal) ease; }
.t-steps-event[data-t-visited]::after { background: var(--t-primary); }
.t-steps-event[data-t-visited]:has(+ .t-steps-event[data-t-visited])::before { background: color-mix(in srgb, var(--t-primary) 55%, transparent); }
@container (max-width: 559px) {
  .t-steps--timeline { --t-steps-date: 0rem; }
  .t-steps-event { grid-template-columns: 0 2.25rem minmax(0, 1fr); }
  .t-steps-event::before { inset-inline-start: calc(1.125rem - 1px); }
  .t-steps-event::after { inset-inline-start: calc(1.125rem - 7px); }
  .t-steps-date { grid-column: 3; margin: 0 0 .25rem; text-align: start; font-size: 1rem; }
}
/* scroll: by default (and as it ends up on phones, in slides, with less motion, without the player)
   each step with its own picture; the following figure is not shown. */
.t-steps--scroll { position: relative; }
.t-steps-stage { display: none; }
.t-steps-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 2.5rem; }
.t-steps-step { display: grid; gap: 1rem; align-content: start; }
.t-steps-own:not(:has(*)) { display: none; }
.t-steps-own .t-steps-picture img { max-height: 24rem; width: auto; max-width: 100%; margin-inline: auto; }
/* build: the base and the layers up to the step, stacked; focus: the whole picture, the step's part outlined. */
.t-steps-stack { display: grid; }
.t-steps-stack > img { grid-area: 1 / 1; }
.t-steps-stack > .t-steps-layer { opacity: clamp(0, calc(var(--step) - var(--layer) + 1), 1); }
.t-steps-spot { position: relative; width: fit-content; max-width: 100%; margin-inline: auto; overflow: hidden; border-radius: var(--t-radius); }
.t-steps-spot img { border-radius: 0; }
.t-steps-region { position: absolute; left: calc(var(--rx) * 100%); top: calc(var(--ry) * 100%); width: calc(var(--rw) * 100%); height: calc(var(--rh) * 100%); border-radius: 6px; box-shadow: 0 0 0 3px var(--t-primary), 0 0 0 100vmax rgb(10 13 18 / .32); pointer-events: none; }
@media (prefers-reduced-motion: no-preference) {
  @container (min-width: 560px) {
    #elabora-app:not([data-presentation="slides"]) .t-steps--scroll[data-t-following] { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.3fr); grid-template-areas: "list stage"; column-gap: clamp(1.5rem, 5cqi, 3.5rem); align-items: start; }
    #elabora-app:not([data-presentation="slides"]) .t-steps--scroll.t-steps--side-start[data-t-following] { grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr); grid-template-areas: "stage list"; }
    #elabora-app:not([data-presentation="slides"]) [data-t-following] > .t-steps-list { grid-area: list; gap: 0; padding-block: 8svh 30svh; }
    #elabora-app:not([data-presentation="slides"]) [data-t-following] .t-steps-step { min-height: 72svh; align-content: center;
      --t-steps-on: clamp(0, calc(1 - max(var(--t-current, 1) - var(--step), var(--step) - var(--t-current, 1))), 1); }
    #elabora-app:not([data-presentation="slides"]) [data-t-following] .t-steps-number { color: color-mix(in srgb, var(--t-on-primary) calc(var(--t-steps-on) * 100%), var(--t-primary)); background: color-mix(in srgb, var(--t-primary) calc(13% + var(--t-steps-on) * 87%), var(--t-surface)); transition: color var(--t-dur-reveal) ease, background var(--t-dur-reveal) ease; }
    /* Each step's own picture stays for screen readers (the figure is hidden from them). */
    #elabora-app:not([data-presentation="slides"]) [data-t-following] .t-steps-own { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
    #elabora-app:not([data-presentation="slides"]) [data-t-following] > .t-steps-stage { grid-area: stage; position: sticky; top: var(--t-bar-top, 0px); display: grid; place-items: center; height: calc(100svh - var(--t-bar-top, 0px) - var(--t-bar-bottom, 0px)); padding-block: 1.5rem; }
    #elabora-app:not([data-presentation="slides"]) [data-t-following] .t-steps-frame { --t-steps-room: calc(100svh - var(--t-bar-top, 0px) - var(--t-bar-bottom, 0px) - 3rem); position: relative; display: grid; width: fit-content; max-width: 100%; overflow: hidden; border-radius: var(--t-radius); }
    #elabora-app:not([data-presentation="slides"]) [data-t-following] .t-steps-frame img { grid-area: 1 / 1; display: block; max-width: 100%; max-height: var(--t-steps-room); }
    #elabora-app:not([data-presentation="slides"]) [data-t-following] .t-steps-layers { display: contents; }
    #elabora-app:not([data-presentation="slides"]) [data-t-following] .t-steps-frame .t-steps-base { width: auto; height: auto; }
    #elabora-app:not([data-presentation="slides"]) [data-t-following] .t-steps-frame .t-steps-layer { width: 100%; height: 100%; object-fit: contain; opacity: clamp(0, calc(var(--t-current, 1) - var(--layer) + 1), 1); transition: opacity var(--t-dur-reveal) ease; will-change: opacity; }
    /* Each layer is its own composited layer, painted once (a picture shown for the first time would
       otherwise be decoded on the frame it starts fading in). */
    /* replace: each picture covers the one before it (the same size, or on the page's colour). */
    #elabora-app:not([data-presentation="slides"]) .t-steps--replace[data-t-following] .t-steps-frame { width: 100%; }
    #elabora-app:not([data-presentation="slides"]) .t-steps--replace[data-t-following] .t-steps-frame .t-steps-layer { background: var(--t-surface); }
    #elabora-app:not([data-presentation="slides"]) .t-steps--replace[data-t-following] .t-steps-frame .t-steps-layer:first-of-type { background: none; }
    #elabora-app:not([data-presentation="slides"]) [data-t-following] .t-steps-regions { display: contents; }
    #elabora-app:not([data-presentation="slides"]) [data-t-following] .t-steps-frame .t-steps-region { opacity: clamp(0, calc(1 - max(var(--t-current, 1) - var(--layer), var(--layer) - var(--t-current, 1))), 1); transition: opacity var(--t-dur-reveal) ease; will-change: opacity; }
  }
}
/* The words arrive softly as they scroll in (--t-scroll-in, from half seen; scroll-driven where the
   browser can; nothing otherwise). */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    #elabora-app:not([data-presentation="slides"]) :is(.t-steps-event, .t-steps-step) > .t-steps-words { --t-scroll-in-opacity: .45; animation: var(--t-scroll-in); animation-timeline: view(); animation-range: entry 0% entry 60%; }
  }
}

/* ── Interactive picture (« Image interactive », D63) ───────────────────────────────────────────
   Markers at x, y of the whole picture (0 to 1), 44 px, numbered, with a ring that reads on any picture;
   they never pulse. popover: the text floats by its marker inside the picture, below it when the marker
   is in the top half and above it otherwise, scrolling inside itself rather than leaving the picture;
   side and below: the texts share one place (the room of the longest, the hint while none is open);
   tour: one text at a time under the picture. Narrower than 560 px the texts are a numbered list under
   the picture (a tour stays a tour), and a picture with a focal point is shown half as large again,
   cropped at its sides around it; a marker the crop leaves out stays at the edge. */
.t-hotspots { display: grid; gap: .875rem; margin: 0; }
.t-hotspots-prompt { margin: 0; color: var(--t-muted); font-size: .9375rem; }
.t-hotspots-figure { position: relative; display: grid; gap: 1.25rem; align-items: start; }
.t-hotspots-frame { position: relative; grid-area: 1 / 1; overflow: hidden; border-radius: var(--t-radius); }
.t-hotspots-picture { position: relative; --t-hotspots-from: 0; --t-hotspots-span: 1; }
.t-hotspots-image { display: block; width: 100%; height: auto; }
.t-hotspots-marker { position: absolute; z-index: 1;
  left: clamp(calc(var(--t-hotspots-from) * 100% + 26px), calc(var(--x, .5) * 100%), calc((var(--t-hotspots-from) + var(--t-hotspots-span)) * 100% - 26px));
  top: clamp(26px, calc(var(--y, .5) * 100%), calc(100% - 26px)); translate: -50% -50%;
  display: grid; place-items: center; width: 44px; height: 44px; padding: 0; border: 3px solid var(--t-surface); border-radius: 50%;
  color: var(--t-on-primary); background: var(--t-primary); font: inherit; font-weight: 700; font-size: 1rem; line-height: 1; font-variant-numeric: tabular-nums;
  box-shadow: 0 0 0 1px rgb(10 13 18 / .25), 0 2px 8px rgb(10 13 18 / .35); cursor: pointer;
  transition: background var(--t-dur-item) ease, color var(--t-dur-item) ease, border-color var(--t-dur-item) ease, scale var(--t-dur-press) var(--t-ease-out); }
.t-hotspots-marker:focus-visible { z-index: 3; outline: 3px solid var(--t-focus); outline-offset: 2px; }
.t-hotspots-marker:active { scale: calc(1 - .06 * var(--t-move)); }
.t-hotspots-marker[data-t-visited] { background: color-mix(in srgb, var(--t-primary) 72%, var(--t-text)); }
.t-hotspots-marker:is([aria-expanded="true"], [aria-current="true"]) { color: var(--t-primary); background: var(--t-surface); border-color: var(--t-primary); }
.t-hotspots-icon, .t-hotspots-icon svg { display: block; width: 22px; height: 22px; }
.t-hotspots-icon svg { fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.t-hotspots-icon circle { fill: currentColor; stroke: none; }
.t-hotspots-panels { margin: 0; padding: 0; list-style: none; }
.t-hotspots-panel { color: var(--t-text); }
.t-hotspots-tag { float: inline-start; display: grid; place-items: center; min-width: 1.75rem; height: 1.75rem; margin: 0 .625rem 0 0; padding: 0 .375rem; border-radius: 999px; color: var(--t-on-primary); background: var(--t-primary); font-weight: 700; font-size: .875rem; line-height: 1; font-variant-numeric: tabular-nums; }
.t-hotspots-title { margin: 0 0 .5rem; font-size: 1.125rem; line-height: 1.4; }
.t-hotspots-body { clear: both; }
.t-hotspots-body > :last-child { margin-bottom: 0; }
.t-hotspots-detail { margin: 0 0 .75rem; clear: both; }
.t-hotspots-detail img { display: block; max-width: 100%; max-height: 12rem; border-radius: calc(var(--t-radius) * .75); }
/* popover */
.t-hotspots--popover .t-hotspots-panels { position: relative; z-index: 2; grid-area: 1 / 1; align-self: stretch; pointer-events: none; }
.t-hotspots--popover .t-hotspots-entry { display: contents; }
.t-hotspots--popover .t-hotspots-panel { --t-hotspots-pw: min(21rem, calc(100% - 1rem)); --t-hotspots-above: clamp(0, calc((var(--y, .5) - .5) * 1000), 1);
  position: absolute; width: var(--t-hotspots-pw); left: clamp(.5rem, calc(var(--x, .5) * 100% - var(--t-hotspots-pw) / 2), calc(100% - var(--t-hotspots-pw) - .5rem));
  top: calc(var(--y, .5) * 100% + 30px - var(--t-hotspots-above) * 60px); translate: 0 calc(var(--t-hotspots-above) * -100%);
  max-height: calc((var(--t-hotspots-above) * var(--y, .5) + (1 - var(--t-hotspots-above)) * (1 - var(--y, .5))) * 100% - 38px); overflow-y: auto; overscroll-behavior: contain;
  padding: .875rem 1rem 1rem; border-radius: var(--t-radius); background: var(--t-surface); pointer-events: auto;
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--t-text) 10%, transparent), 0 12px 32px rgb(15 23 42 / .2);
  transition: opacity var(--t-dur-pop) ease, scale var(--t-dur-pop) var(--t-ease-out); }
@starting-style { .t-hotspots--popover .t-hotspots-panel:not([hidden]) { opacity: 0; scale: calc(1 - .04 * var(--t-move)); } }
/* side and below: the texts in one place, the longest's room kept. */
.t-hotspots-room { display: grid; min-width: 0; }
.t-hotspots-room > * { grid-area: 1 / 1; min-width: 0; }
:is(.t-hotspots--side, .t-hotspots--below) .t-hotspots-room { grid-area: auto; padding: 1.125rem 1.25rem; border-radius: var(--t-radius); background: color-mix(in srgb, var(--t-primary) 5%, var(--t-surface)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--t-text) 8%, transparent); }
:is(.t-hotspots--side, .t-hotspots--below) .t-hotspots-panels { display: grid; }
:is(.t-hotspots--side, .t-hotspots--below) .t-hotspots-entry { display: contents; }
:is(.t-hotspots--side, .t-hotspots--below) .t-hotspots-panel { grid-area: 1 / 1; min-width: 0; transition: opacity var(--t-dur-item) ease, visibility var(--t-dur-item); }
:is(.t-hotspots--side, .t-hotspots--below) .t-hotspots-panel[hidden] { display: block !important; visibility: hidden; opacity: 0; }
.t-hotspots-hint { margin: 0; align-self: center; color: var(--t-muted); font-size: .9375rem; transition: opacity var(--t-dur-item) ease; }
.t-hotspots-room:has(.t-hotspots-panel:not([hidden])) .t-hotspots-hint { visibility: hidden; opacity: 0; }
@container (min-width: 720px) { .t-hotspots--side .t-hotspots-figure { grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr); } }
/* tour: the texts one at a time under the picture (the sequence keeps the longest's room), then the nav. */
.t-hotspots--tour .t-hotspots-room { padding: 1.125rem 1.25rem; border-radius: var(--t-radius); background: color-mix(in srgb, var(--t-primary) 5%, var(--t-surface)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--t-text) 8%, transparent); }
.t-hotspots--tour .t-hotspots-frame { grid-area: auto; }
:is(.t-hotspots--tour, .t-hotspots--side, .t-hotspots--below) .t-hotspots-detail img { max-height: 8rem; }
/* Under the picture, a detail sits beside its text rather than above it. */
@container (min-width: 560px) { :is(.t-hotspots--tour, .t-hotspots--below) .t-hotspots-detail { float: inline-end; clear: none; max-width: 35%; margin: 0 0 .5rem 1.25rem; } :is(.t-hotspots--tour, .t-hotspots--below) .t-hotspots-body { clear: none; } }
/* Narrow places: a numbered list under the picture; the marker pressed lights its entry. */
@container (max-width: 559px) {
  .t-hotspots[data-focus] .t-hotspots-picture { --t-hotspots-from: calc(var(--focus-x, .5) / 3); --t-hotspots-span: calc(2 / 3); width: 150%; margin-inline-start: calc(var(--focus-x, .5) * -50%); }
  .t-hotspots[data-focus] .t-hotspots-picture:dir(rtl) { margin-inline-start: 0; margin-inline-end: calc((1 - var(--focus-x, .5)) * -50%); }
  .t-hotspots:not(.t-hotspots--tour) .t-hotspots-figure { grid-template-columns: minmax(0, 1fr); gap: 1rem; }
  .t-hotspots:not(.t-hotspots--tour) .t-hotspots-room { display: block; padding: 0; background: none; box-shadow: none; }
  .t-hotspots:not(.t-hotspots--tour) .t-hotspots-hint { display: none; }
  .t-hotspots:not(.t-hotspots--tour) .t-hotspots-panels { position: static; grid-area: auto; display: grid; gap: .5rem; pointer-events: auto; }
  .t-hotspots:not(.t-hotspots--tour) .t-hotspots-entry { display: block; }
  .t-hotspots:not(.t-hotspots--tour) .t-hotspots-panel, .t-hotspots:not(.t-hotspots--tour) .t-hotspots-panel[hidden] { display: block !important; visibility: visible; opacity: 1; position: static; width: auto; max-height: none; translate: none; overflow: visible; padding: .75rem .875rem; border-radius: var(--t-radius); background: none; box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--t-text) 10%, transparent); transition: background var(--t-dur-item) ease, box-shadow var(--t-dur-item) ease; }
  .t-hotspots:not(.t-hotspots--tour) .t-hotspots-panel:not([hidden]) { background: color-mix(in srgb, var(--t-primary) 8%, var(--t-surface)); box-shadow: inset 0 0 0 2px var(--t-primary); }
  .t-hotspots--tour .t-hotspots-room { padding: 1rem; }
}
/* In slides the picture keeps to the slide's height (the texts under it too), its markers on it. */
@container (min-width: 560px) {
  [data-presentation="slides"] .t-hotspots-picture { width: fit-content; max-width: 100%; margin-inline: auto; }
  [data-presentation="slides"] .t-hotspots-image { width: auto; max-width: 100%; max-height: min(34rem, 60vh); }
  [data-presentation="slides"] :is(.t-hotspots--below, .t-hotspots--tour) .t-hotspots-image { max-height: min(22rem, 38vh); }
  [data-presentation="slides"] .t-steps-event { padding-bottom: 1.5rem; }
}

/* A sound's caption (D67): over the bottom of the screen, as the narration's captions, moving nothing. */
.t-sound-caption { position: fixed; left: 50%; bottom: calc(var(--t-bar-bottom, 0px) + 1.5rem); transform: translateX(-50%); z-index: 30; max-width: min(46rem, calc(100vw - 2rem)); margin: 0; padding: 0.375rem 1.125rem 0.5rem; border-radius: 10px; font: italic 500 1.25rem/1.6 var(--t-font-body); color: #fff; background: rgb(19 38 58 / 0.9); text-align: center; pointer-events: none; }
.t-sound-caption[hidden] { display: none; }
#elabora-app[data-captions="large"] .t-sound-caption { font-size: 1.75rem; }
/* A sound line's caption and its line in the transcript (D67): in italics, as subtitles mark sounds. */
.t-timeline-sound { font-style: italic; }

/* Charts and diagrams (D60). Built from the course's tokens only: every tint is a color-mix() of its
   ink, surface and accent, so a theme change restyles a chart at once, without building it again.

   Motion, reread for charts from the rules above (« Motion »): entrances are written by the player
   frame by frame (charts/behavior.ts), so nothing here transitions while .is-entering. What answers
   the learner (pointer, keys, tap) or the voice is soothing: 220 ms, ease or --t-ease-out, no
   overshoot, a few pixels at most; what is not pointed at (or not talked about) steps back to 40 %.
   The focus pull (.is-pulled) changes colours over half a second: the one moment that is slow on purpose. */
.t-chart {
  --t-chart-ink: var(--t-text);
  --t-chart-paper: var(--t-surface);
  --t-chart-accent: var(--t-accent, var(--t-primary));
  --t-chart-quiet: color-mix(in oklab, var(--t-chart-ink) 22%, var(--t-chart-paper));
  --t-chart-quieter: color-mix(in oklab, var(--t-chart-ink) 11%, var(--t-chart-paper));
  --t-chart-tint: color-mix(in oklab, var(--t-chart-accent) 74%, var(--t-chart-paper));
  --t-chart-rule: color-mix(in oklab, var(--t-chart-ink) 14%, transparent);
  --t-chart-muted: var(--t-muted);
  --t-chart-radius: min(var(--t-radius, 8px), 8px);
  --t-chart-calm: 220ms;
  --t-chart-pull: 500ms;
  position: relative;
  margin: 0;
  container-type: inline-size;
  color: var(--t-chart-ink);
  font-family: var(--t-font-body);
}
.t-chart:focus-visible { outline: 2px solid var(--t-focus); outline-offset: 0.5rem; border-radius: 4px; }
.t-chart-head { margin: 0 0 1.25rem; }
.t-chart-title { margin: 0; max-width: 36ch; font-family: var(--t-font-heading, var(--t-font-body)); font-size: 1.375rem; font-weight: 650; line-height: 1.22; letter-spacing: -0.01em; text-wrap: balance; }
.t-chart-context { margin: 0.375rem 0 0; max-width: 62ch; color: var(--t-chart-muted); font-size: 0.9375rem; line-height: 1.45; text-wrap: pretty; }
.t-chart-body { position: relative; }
.t-chart-source { margin: 1rem 0 0; color: var(--t-chart-muted); font-size: 0.8125rem; }
/* For screen readers only. A table keeps the width of its content whatever its width says: shown as a block
   and clipped, it cannot widen the slide (or scroll a phone sideways). */
.t-chart-table { position: absolute !important; display: block; width: 1px; height: 1px; max-width: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }
.t-chart-list { margin: 0; padding-left: 1.25rem; }
.t-chart :is(.t-bars-value, .t-figures-figure, .t-trend-start, .t-trend-end, .t-trend-ytick, .t-trend-xtick, .t-trend-guess-label, .t-chart-tip) { font-variant-numeric: tabular-nums; }

/* Pointing and the voice: the rest steps back. :where() keeps these weak, so a type may say otherwise. */
.t-chart [data-t-item] { transition: opacity var(--t-chart-calm) ease; }
.t-chart.is-focused :where([data-t-item]:not(.is-pointed, .is-lit)),
.t-chart.is-spotlit:not(.is-focused) :where([data-t-item]:not(.is-spoken, .is-said)) { opacity: 0.4; }
.t-chart.is-entering :where([data-t-item], [data-t-item] *) { transition: none; }

/* The value's bubble: it fades in where it is needed, and glides to the next item only while still
   shown (kit.ts createTip). */
.t-chart-tip {
  position: absolute; z-index: 3; top: 0; left: 0; width: max-content; max-width: 16rem;
  padding: 0.3125rem 0.625rem; border-radius: 10px; pointer-events: none;
  color: var(--t-chart-paper); background: var(--t-chart-ink);
  box-shadow: 0 6px 18px color-mix(in oklab, var(--t-chart-ink) 20%, transparent);
  font-size: 0.8125rem; font-weight: 550; line-height: 1.3; text-align: center;
  opacity: 0;
  transition: opacity 180ms ease, transform var(--t-chart-calm) var(--t-ease-out);
}
.t-chart-tip.is-on { opacity: 1; }

/* ── bars ── */
.t-bars-grid { display: grid; grid-template-columns: minmax(5rem, max-content) 1fr; align-items: center; gap: 0.5rem 1rem; }
.t-bars-label { justify-self: end; max-width: 15rem; font-size: 0.9375rem; line-height: 1.25; text-align: right; text-wrap: balance; }
.t-bars-track { position: relative; display: flex; align-items: center; gap: 0.625rem; min-height: 2.25rem; }
.t-bars-bar { width: calc(var(--w) * (100% - 4.5rem)); min-width: 3px; height: 1.625rem; border-radius: 3px var(--t-chart-radius) var(--t-chart-radius) 3px; background: var(--t-chart-tint); transform-origin: 0 50%; transition: background-color var(--t-chart-pull) ease; }
.t-bars-value { font-size: 0.9375rem; font-weight: 600; white-space: nowrap; transition: color var(--t-chart-pull) ease; }
/* With a highlight, every bar stands quiet until the pull gives the one that matters the colour. */
.t-chart:has(.t-bars-track.is-hl) .t-bars-bar { background: var(--t-chart-quiet); }
.t-chart.is-pulled .t-bars-track.is-hl .t-bars-bar { background: var(--t-chart-accent); }
.t-chart.is-pulled .t-bars-track:not(.is-hl) .t-bars-bar { background: var(--t-chart-quieter); }
.t-chart.is-pulled .t-bars-track.is-hl .t-bars-value { color: var(--t-chart-accent); font-weight: 700; }
.t-chart.is-pulled .t-bars-track:not(.is-hl) .t-bars-value { color: var(--t-chart-muted); }
.t-chart.is-pulled .t-bars-label.is-hl { font-weight: 650; }
.t-chart.is-spotlit .t-bars-track.is-spoken .t-bars-bar { background: var(--t-chart-accent); }
@container (max-width: 560px) {
  .t-bars-grid { grid-template-columns: 1fr; row-gap: 0.125rem; }
  .t-bars-label { justify-self: start; max-width: none; margin-top: 0.5rem; text-align: left; }
}

/* ── key figures ── */
.t-figures-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(12rem, 100%), 1fr)); gap: 1rem; }
.t-figures-card { position: relative; overflow: hidden; padding: 1.375rem 1.25rem 1.25rem; border-radius: var(--t-radius); background: color-mix(in oklab, var(--t-chart-ink) 4%, var(--t-chart-paper)); }
.t-figures-figure { margin: 0; font-family: var(--t-font-heading, var(--t-font-body)); font-size: 2.75rem; font-weight: 700; line-height: 1; letter-spacing: -0.03em; white-space: nowrap; transition: color var(--t-chart-pull) ease; }
.t-figures-label { margin: 0.5rem 0 0; font-size: 1rem; line-height: 1.35; text-wrap: pretty; }
.t-figures-was { margin: 0.375rem 0 0; color: var(--t-chart-muted); font-size: 0.8125rem; }
.t-figures-meter { position: absolute; bottom: 0; left: 0; width: 100%; height: 4px; background: var(--t-chart-accent); transform-origin: 0 50%; scale: calc(var(--p, 0) * var(--t-progress, 1)) 1; }
.t-chart.is-pulled .t-figures-card.is-hl .t-figures-figure { color: var(--t-chart-accent); }

/* ── trend ── */
.t-trend-plot { padding: 1.75rem 4.75rem 2.25rem 3rem; }
.t-trend-area-box { position: relative; height: 16rem; touch-action: pan-y; }
.t-trend-svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.t-trend-grid line { stroke: var(--t-chart-rule); stroke-dasharray: 2 4; vector-effect: non-scaling-stroke; }
.t-trend-area { fill: color-mix(in oklab, var(--t-chart-accent) 13%, transparent); }
.t-trend-line { fill: none; stroke: var(--t-chart-accent); stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; vector-effect: non-scaling-stroke; }
.t-trend-guess { fill: none; stroke: var(--t-chart-ink); stroke-width: 2.5; stroke-dasharray: 1 7; stroke-linecap: round; vector-effect: non-scaling-stroke; }
.t-trend-ytick { position: absolute; right: calc(100% + 0.625rem); translate: 0 -50%; color: var(--t-chart-muted); font-size: 0.75rem; white-space: nowrap; pointer-events: none; }
.t-trend-xtick { position: absolute; top: calc(100% + 0.5rem); translate: -50% 0; color: var(--t-chart-muted); font-size: 0.8125rem; white-space: nowrap; }
.t-trend-start { position: absolute; translate: -0.25rem calc(-100% - 0.625rem); color: var(--t-chart-muted); font-size: 0.875rem; font-weight: 650; white-space: nowrap; }
.t-trend-end { position: absolute; translate: 0.75rem -50%; color: var(--t-chart-accent); font-size: 1.0625rem; font-weight: 700; white-space: nowrap; }
.t-trend-dot { position: absolute; width: 12px; height: 12px; margin: -6px 0 0 -6px; border-radius: 50%; background: var(--t-chart-paper); box-shadow: inset 0 0 0 3px var(--t-chart-accent); }
.t-trend-note { position: absolute; top: 0; bottom: 0; width: 0; pointer-events: none; }
.t-trend-note::before { content: ""; position: absolute; top: 0.25rem; bottom: 0; left: 0; border-left: 1.5px solid var(--t-chart-ink); opacity: 0.5; }
.t-trend-note span { position: absolute; top: 0; left: 0.5rem; width: max-content; max-width: 12rem; font-size: 0.8125rem; font-weight: 550; line-height: 1.3; }
.t-trend-note.is-left span { right: 0.5rem; left: auto; text-align: right; }
/* The year pointed at: a knob that fades and settles, without bounce. */
.t-chart .t-trend-point { position: absolute; width: 14px; height: 14px; margin: -7px 0 0 -7px; border-radius: 50%; background: var(--t-chart-accent); box-shadow: 0 0 0 4px color-mix(in oklab, var(--t-chart-accent) 22%, transparent); pointer-events: none; opacity: 0; scale: 0.6; transition: opacity 180ms ease, scale var(--t-chart-calm) var(--t-ease-out); }
.t-chart .t-trend-point:is(.is-pointed, .is-spoken) { opacity: 1; scale: 1; }
/* Stronger than the dimming above: a year not pointed at (or one still to predict) stays hidden while the voice speaks. */
.t-chart .t-trend-plot .t-trend-point:not(.is-pointed, .is-spoken) { opacity: 0; }
.t-chart.is-spotlit:not(.is-focused) .t-trend-point.is-spoken { scale: 0.85; }
/* Predict: the zone to draw in, the guess, the reveal. */
.t-trend-zone { position: absolute; top: 0; right: 0; bottom: 0; margin-left: 6px; border-radius: 10px; background: repeating-linear-gradient(135deg, color-mix(in oklab, var(--t-chart-ink) 11%, transparent) 0 1px, transparent 1px 9px); cursor: crosshair; touch-action: none; transition: opacity 400ms ease; }
.t-trend-hint { position: absolute; inset: 0; display: grid; place-content: center; padding: 1rem; color: var(--t-chart-muted); font-size: 0.9375rem; font-weight: 600; text-align: center; text-wrap: balance; pointer-events: none; transition: opacity 300ms ease; }
.t-chart.has-guess .t-trend-hint { opacity: 0; }
.t-chart.is-revealed .t-trend-zone { opacity: 0; pointer-events: none; }
.t-chart:has(.t-trend-range:focus-visible) .t-trend-zone { outline: 2px solid var(--t-focus); outline-offset: 2px; }
.t-trend-guess-label { position: absolute; translate: calc(-100% - 0.5rem) calc(-100% - 0.375rem); font-size: 0.8125rem; font-weight: 600; text-align: right; white-space: nowrap; pointer-events: none; }
/* Away from the line that comes into it (trend.ts drawGuess). */
.t-trend-guess-label.is-below { translate: calc(-100% - 0.5rem) 0.375rem; }
.t-trend-ask { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 1.25rem; min-height: 2.75rem; margin-top: 0.5rem; }
.t-trend-reveal:disabled { opacity: 0.4; cursor: default; }
.t-trend-feedback { margin: 0; max-width: 52ch; font-size: 0.9375rem; line-height: 1.45; }
.t-trend-feedback:empty { display: none; }
@container (max-width: 560px) {
  .t-trend-plot { padding-right: 0.75rem; }
  .t-trend-area-box { height: 12rem; }
  .t-trend-xtick.is-minor { display: none; }
  .t-trend-end { translate: -100% calc(-100% - 0.625rem); }
}

/* ── diagram (Pele's SVG; its colours are --pele-* variables) ── */
.t-diagram {
  --pele-bg: var(--t-chart-paper);
  --pele-fg: var(--t-chart-ink);
  --pele-muted: var(--t-chart-muted);
  --pele-line: color-mix(in oklab, var(--t-chart-ink) 50%, var(--t-chart-paper));
  --pele-surface: color-mix(in oklab, var(--t-chart-ink) 5%, var(--t-chart-paper));
  --pele-surface-alt: color-mix(in oklab, var(--t-chart-ink) 10%, var(--t-chart-paper));
  --pele-border: color-mix(in oklab, var(--t-chart-ink) 24%, var(--t-chart-paper));
  --pele-accent: var(--t-chart-accent);
  --pele-radius: var(--t-chart-radius);
  --pele-font: var(--t-font-body);
}
.t-diagram svg { display: block; max-width: 100%; height: auto; margin: 0 auto; font-size: 16px; }
.t-diagram-narrow { display: none; }
@container (max-width: 560px) {
  .t-diagram-wide { display: none; }
  .t-diagram-narrow { display: block; }
}
.t-diagram :is(.pele-edge, .pele-edge-label) { transition: opacity var(--t-chart-calm) ease; }
.t-diagram .pele-node > :is(rect, polygon, circle, ellipse, path) { transition: fill var(--t-chart-calm) ease, stroke var(--t-chart-calm) ease; }
.t-chart.is-pulled .t-diagram .pele-node.is-hl > :is(rect, polygon, circle, ellipse, path) { fill: color-mix(in oklab, var(--t-chart-accent) 16%, var(--t-chart-paper)); stroke: var(--t-chart-accent); }
/* The path to the node pointed at (or said) stays; the other edges step back further. */
.t-chart.is-focused .t-diagram :is(.pele-edge, .pele-edge-label):not(.is-lit),
.t-chart.is-spotlit:not(.is-focused) .t-diagram :is(.pele-edge, .pele-edge-label):not(.is-said) { opacity: 0.25; }
.t-chart.is-focused .t-diagram .pele-node.is-pointed > :is(rect, polygon, circle, ellipse, path),
.t-chart.is-spotlit:not(.is-focused) .t-diagram .pele-node.is-spoken > :is(rect, polygon, circle, ellipse, path) { fill: color-mix(in oklab, var(--t-chart-accent) 14%, var(--t-chart-paper)); stroke: var(--t-chart-accent); stroke-width: 1.5; }
.t-diagram .pele-edge > path { transition: stroke var(--t-chart-calm) ease, fill var(--t-chart-calm) ease; }
.t-chart.is-focused .t-diagram .pele-edge.is-lit > path:not(.pele-marker),
.t-chart.is-spotlit:not(.is-focused) .t-diagram .pele-edge.is-said > path:not(.pele-marker) { stroke: var(--t-chart-accent); }
.t-chart.is-focused .t-diagram .pele-edge.is-lit > .pele-marker,
.t-chart.is-spotlit:not(.is-focused) .t-diagram .pele-edge.is-said > .pele-marker { fill: var(--t-chart-accent); }
.t-chart.is-entering .t-diagram :is(.pele-edge, .pele-edge-label, .pele-edge *, .pele-node > *) { transition: none; }
.t-diagram-problem { margin: 0; padding: 0.75rem 1rem; border-radius: var(--t-chart-radius); color: var(--t-error); background: color-mix(in oklab, var(--t-error) 8%, var(--t-chart-paper)); font-family: var(--t-font-mono, monospace); font-size: 0.8125rem; }

@media (prefers-reduced-motion: reduce) {
  .t-chart-tip { transition: opacity 180ms ease; }
  .t-chart .t-trend-point { scale: 1; }
}

/* ── before-after (D60): a slope chart ──
   The plot is --h rem high (--hn narrow; core charts/before-after.ts places values and pushes labels apart in
   fractions of it); --x0 and --x1 are its two columns, wide and narrow. Labels are positioned with
   transform, so the entrance may move them with translate. */
.t-slope { --x0: 0.34; --x1: 0.66; --t-slope-dot: 11px; }
.t-slope-plot { position: relative; height: calc(var(--h, 18) * 1rem); max-width: 42rem; margin: calc(1.75rem + var(--heads, 1) * 1.0625rem) auto 0.5rem; touch-action: pan-y; }
/* A heading stays over its column and within its half: a long one wraps upwards. */
.t-slope-head {
  position: absolute; bottom: calc(100% + 1.25rem); left: calc(var(--x0) * 100%); width: max-content;
  max-width: calc(min(2 * var(--x0), var(--x1) - var(--x0)) * 100%); margin: 0; transform: translateX(-50%);
  color: var(--t-chart-muted); font-size: 0.8125rem; font-weight: 650; line-height: 1.25; letter-spacing: 0.06em; text-align: center; text-transform: uppercase; text-wrap: balance;
}
.t-slope-head.is-after { left: calc(var(--x1) * 100%); max-width: calc(min(2 * (1 - var(--x1)), var(--x1) - var(--x0)) * 100%); }
.t-slope-line {
  position: absolute; top: 0; left: calc(var(--x0) * 100%); width: calc((var(--x1) - var(--x0)) * 100%); height: 100%;
  overflow: visible; pointer-events: none; --t-slope-ink: var(--t-chart-tint);
}
.t-slope-line line {
  stroke: var(--t-slope-ink); stroke-width: 2.25; stroke-linecap: round; vector-effect: non-scaling-stroke;
  transition: stroke var(--t-chart-pull) ease, stroke-width var(--t-chart-pull) ease;
}
.t-slope-dot {
  position: absolute; z-index: 2; top: calc(var(--y) * 100%); left: calc(var(--x0) * 100%);
  width: var(--t-slope-dot); height: var(--t-slope-dot); margin: calc(var(--t-slope-dot) / -2) 0 0 calc(var(--t-slope-dot) / -2);
  border-radius: 50%; background: var(--t-chart-paper); box-shadow: inset 0 0 0 2.5px var(--t-slope-ink);
  --t-slope-ink: var(--t-chart-tint);
  transition: background-color var(--t-chart-pull) ease, box-shadow var(--t-chart-pull) ease;
}
.t-slope-dot.is-after { left: calc(var(--x1) * 100%); }
.t-slope-label {
  position: absolute; z-index: 2; top: calc(var(--y) * 100%); margin: 0; transform: translateY(-50%);
  font-size: 0.9375rem; line-height: 1.25rem; text-wrap: balance;
  transition: color var(--t-chart-pull) ease;
}
.t-slope-label.is-before { right: calc((1 - var(--x0)) * 100% + 0.875rem); max-width: calc(var(--x0) * 100% - 0.875rem); text-align: right; }
.t-slope-label.is-after { left: calc(var(--x1) * 100% + 0.875rem); max-width: calc((1 - var(--x1)) * 100% - 0.875rem); }
.t-slope-num { font-weight: 700; white-space: nowrap; }
.t-slope-label.is-after .t-slope-name { color: var(--t-chart-muted); }
.t-chart .t-slope-num { font-variant-numeric: tabular-nums; }

/* With a highlight, every line stands quiet until the pull gives the one that matters the colour
   and a little more weight. */
.t-chart:has(.t-slope-line.is-hl) :is(.t-slope-line, .t-slope-dot) { --t-slope-ink: var(--t-chart-quiet); }
.t-chart.is-pulled :is(.t-slope-line, .t-slope-dot).is-hl,
.t-chart.is-spotlit :is(.t-slope-line, .t-slope-dot).is-spoken { --t-slope-ink: var(--t-chart-accent); }
.t-chart.is-pulled .t-slope-line.is-hl { z-index: 1; }
.t-chart.is-pulled .t-slope-line.is-hl line { stroke-width: 3.5; }
.t-chart.is-pulled .t-slope-dot.is-hl { background: var(--t-chart-accent); }
.t-chart.is-pulled .t-slope-label.is-hl,
.t-chart.is-pulled .t-slope-label.is-after.is-hl .t-slope-name { color: var(--t-chart-accent); font-weight: 650; }
/* The line pointed at comes forward a little. */
.t-chart.is-focused .t-slope-line.is-pointed { z-index: 1; }
.t-chart.is-focused :is(.t-slope-line, .t-slope-dot).is-pointed:not(.is-hl) { --t-slope-ink: color-mix(in oklab, var(--t-chart-ink) 45%, var(--t-chart-paper)); }
.t-chart.is-focused .t-slope-line.is-pointed line,
.t-chart.is-focused .t-slope-dot.is-pointed { transition-duration: var(--t-chart-calm); }

@container (max-width: 560px) {
  .t-slope { --x0: 0.2; --x1: 0.6; }
  .t-slope-plot { height: calc(var(--hn, 18) * 1rem); margin-top: calc(1.75rem + var(--headsn, 1) * 1rem); }
  .t-slope-label { top: calc(var(--yn) * 100%); font-size: 0.875rem; }
  .t-slope-label.is-before .t-slope-name { display: none; }
  .t-slope-head { font-size: 0.75rem; line-height: 1.25; letter-spacing: 0.04em; }
}

/* ── cycle (D60) ──
   A 3:2 box (cut under an odd ring, --h): the ring's SVG fills it with a uniform viewBox (charts/cycle.ts VIEW), the stages sit at
   --x, --y (the number's centre), their words on the outer side. The centre stacks every text in one
   cell and shows one. Positions use transform; the entrance uses scale and translate (they compose). */
.t-cycle { position: relative; max-width: 44rem; margin: 0 auto; padding: 1.25rem 0; }
.t-cycle-ring { position: relative; aspect-ratio: 300 / var(--h, 200); }
.t-cycle-svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
/* The viewBox is uniform (no stretching), so strokes are in its units: 1.3 ≈ 3 px at full size; dashes
   then follow the arc's pathLength while it draws. */
.t-cycle-line { fill: none; stroke: var(--t-chart-quiet); stroke-width: 1.3; stroke-linecap: round; transition: stroke var(--t-chart-pull) ease; }
.t-cycle-head { fill: var(--t-chart-quiet); transition: fill var(--t-chart-pull) ease; }

.t-cycle-stage { position: absolute; left: var(--x); top: var(--y); width: 0; height: 0; z-index: 1; }
.t-cycle-num {
  position: absolute; left: 0; top: 0; display: grid; place-items: center;
  width: 2.625rem; height: 2.625rem; transform: translate(-50%, -50%);
  border-radius: 50%; background: var(--t-chart-paper);
  box-shadow: inset 0 0 0 2px var(--t-chart-quiet);
  font-family: var(--t-font-heading, var(--t-font-body)); font-size: 1rem; font-weight: 700; line-height: 1; font-variant-numeric: tabular-nums;
  transition: background-color var(--t-chart-pull) ease, color var(--t-chart-pull) ease, box-shadow var(--t-chart-calm) var(--t-ease-out);
}
.t-cycle-words { position: absolute; width: max-content; max-width: min(11rem, 26cqi); }
.t-cycle-title { display: block; font-size: 0.9375rem; font-weight: 650; line-height: 1.25; text-wrap: balance; transition: color var(--t-chart-pull) ease; }
.t-cycle-text { display: none; }
.t-cycle-stage.is-right .t-cycle-words { left: 2.125rem; top: 0; transform: translateY(-50%); text-align: left; }
.t-cycle-stage.is-left .t-cycle-words { right: 2.125rem; top: 0; transform: translateY(-50%); text-align: right; }
.t-cycle-stage.is-top .t-cycle-words { bottom: 1.875rem; left: 0; transform: translateX(-50%); text-align: center; max-width: min(13rem, 34cqi); }
.t-cycle-stage.is-bottom .t-cycle-words { top: 1.875rem; left: 0; transform: translateX(-50%); text-align: center; max-width: min(13rem, 34cqi); }

/* The centre: the loop's name at rest, the stage pointed at or said. One grid cell: no layout moves. */
.t-cycle-centre {
  position: absolute; z-index: 0; left: 50%; top: calc(1.25rem + (100% - 2.5rem) * var(--cy, 0.5)); width: min(16rem, 34cqi);
  display: grid; transform: translate(-50%, -50%); text-align: center; pointer-events: none;
}
.t-cycle-rest, .t-cycle-say { grid-area: 1 / 1; align-self: center; transition: opacity 200ms ease, translate var(--t-chart-calm) var(--t-ease-out); }
.t-cycle-say { opacity: 0; translate: 0 4px; }
.t-cycle-say.is-shown { opacity: 1; translate: 0 0; }
.t-cycle-rest.is-away { opacity: 0; translate: 0 -4px; }
.t-cycle-name { margin: 0; font-family: var(--t-font-heading, var(--t-font-body)); font-size: 1.1875rem; font-weight: 650; line-height: 1.2; letter-spacing: -0.01em; text-wrap: balance; }
.t-cycle-about { margin: 0.375rem 0 0; color: var(--t-chart-muted); font-size: 0.875rem; line-height: 1.45; text-wrap: pretty; }
.t-cycle-say .t-cycle-name { font-size: 1.0625rem; }

/* Pointed at, or said: the number's ring darkens (no scale, no bounce). */
.t-chart .t-cycle-stage:is(.is-pointed, .is-spoken) .t-cycle-num { box-shadow: inset 0 0 0 2px var(--t-chart-ink); }
.t-chart .t-cycle-arc:is(.is-pointed, .is-spoken) .t-cycle-line { stroke: color-mix(in oklab, var(--t-chart-ink) 55%, var(--t-chart-paper)); }
.t-chart .t-cycle-arc:is(.is-pointed, .is-spoken) .t-cycle-head { fill: color-mix(in oklab, var(--t-chart-ink) 55%, var(--t-chart-paper)); }
.t-chart .t-cycle-arc { transition: opacity var(--t-chart-calm) ease; }
.t-chart.is-entering .t-cycle-arc :is(.t-cycle-line, .t-cycle-head) { transition: none; }

/* The focus pull: the stage that carries the idea, and the arc that brings it, take the accent. */
.t-chart.is-pulled .t-cycle-stage.is-hl .t-cycle-num { color: var(--t-chart-on-accent, var(--t-chart-paper)); background: var(--t-chart-accent); box-shadow: inset 0 0 0 2px var(--t-chart-accent); }
.t-chart.is-pulled .t-cycle-stage.is-hl .t-cycle-title { font-weight: 700; }
.t-chart.is-pulled .t-cycle-arc.is-hl .t-cycle-line { stroke: var(--t-chart-accent); }
.t-chart.is-pulled .t-cycle-arc.is-hl .t-cycle-head { fill: var(--t-chart-accent); }

.t-cycle-back { display: none; }

/* Narrow: a list down a spine, every stage's text shown, and a line back from the last to the first.
   The spine and the return are one rounded box: its right edge runs through the numbers' centres. */
@container (max-width: 560px) {
  .t-cycle { padding: 0; }
  .t-cycle-centre { position: static; width: auto; margin: 0 0 1.25rem; transform: none; text-align: left; }
  .t-cycle-say { display: none; }
  .t-cycle-centre:not(:has(.t-cycle-rest)) { display: none; }
  .t-cycle-rest.is-away { opacity: 1; translate: none; }
  .t-cycle-name { font-size: 1.0625rem; }
  .t-cycle-ring { aspect-ratio: auto; display: grid; gap: 1.125rem; padding: 0 0 1.25rem 1.125rem; }
  .t-cycle-svg { display: none; }
  .t-cycle-stage { position: relative; left: auto; top: auto; width: auto; height: auto; display: grid; grid-template-columns: 2.25rem 1fr; column-gap: 0.875rem; align-items: start; }
  .t-cycle-num { position: relative; width: 2.25rem; height: 2.25rem; transform: none; font-size: 0.9375rem; }
  .t-cycle-ring .t-cycle-stage .t-cycle-words { position: static; width: auto; max-width: none; transform: none; text-align: left; padding-top: 0.3125rem; }
  .t-cycle-title { font-size: 1rem; text-wrap: pretty; }
  .t-cycle-text { display: block; margin-top: 0.1875rem; color: var(--t-chart-muted); font-size: 0.875rem; line-height: 1.45; text-wrap: pretty; }
  .t-cycle-back {
    display: block; position: absolute; left: 0; top: 1.125rem; bottom: 0; width: 2.25rem; z-index: 0;
    border: 2px solid var(--t-chart-quiet); border-radius: 0.875rem; pointer-events: none;
  }
  /* The return's arrowheads: up the left side, and into the first number. */
  .t-cycle-back::before, .t-cycle-back::after { content: ""; position: absolute; width: 0; height: 0; border: 0 solid transparent; }
  .t-cycle-back::before { left: -8px; top: 50%; border-width: 0 7px 9px; border-bottom-color: var(--t-chart-quiet); translate: 0 -50%; }
  .t-cycle-back::after { top: -8px; right: calc(1.125rem - 2px); border-width: 7px 0 7px 9px; border-left-color: var(--t-chart-quiet); }
}

/* ── donut (D60) ── A ring in a uniform viewBox beside its legend; under 560 px the legend goes under
   the ring. Parts take --c: steps of ink beside a highlighted part (darker ink until the focus pull
   gives it the accent), or steps of the accent when there is none. */
.t-chart--donut {
  --t-donut-hl: color-mix(in oklab, var(--t-chart-ink) 58%, var(--t-chart-paper));
  --t-donut-k0: color-mix(in oklab, var(--t-chart-ink) 40%, var(--t-chart-paper));
  --t-donut-k1: color-mix(in oklab, var(--t-chart-ink) 28%, var(--t-chart-paper));
  --t-donut-k2: color-mix(in oklab, var(--t-chart-ink) 20%, var(--t-chart-paper));
  --t-donut-k3: color-mix(in oklab, var(--t-chart-ink) 14%, var(--t-chart-paper));
  --t-donut-k4: color-mix(in oklab, var(--t-chart-ink) 10%, var(--t-chart-paper));
  --t-donut-a0: var(--t-chart-accent);
  --t-donut-a1: color-mix(in oklab, var(--t-chart-accent) 70%, var(--t-chart-paper));
  --t-donut-a2: color-mix(in oklab, var(--t-chart-accent) 50%, var(--t-chart-paper));
  --t-donut-a3: color-mix(in oklab, var(--t-chart-accent) 36%, var(--t-chart-paper));
  --t-donut-a4: color-mix(in oklab, var(--t-chart-accent) 26%, var(--t-chart-paper));
  --t-donut-a5: color-mix(in oklab, var(--t-chart-accent) 18%, var(--t-chart-paper));
}
.t-donut-layout { display: grid; grid-template-columns: minmax(10rem, 17rem) minmax(0, 24rem); align-items: center; gap: 1.5rem 3rem; }
.t-donut-ring { position: relative; aspect-ratio: 1; }
.t-donut-svg { display: block; width: 100%; height: 100%; overflow: visible; }

/* A part never moves. Its colour changes over the pull's half second (charts.css), and at the
   calm pace while the learner points. (.t-chart: stronger than charts.css's opacity alone.) */
.t-chart .t-donut-arc {
  fill: var(--c);
  transition: opacity var(--t-chart-calm) ease, fill var(--t-chart-pull) ease;
}
.t-chart.is-focused .t-donut-arc { transition: opacity var(--t-chart-calm) ease, fill var(--t-chart-calm) ease; }

/* The centre: the face at rest, and one face per part, stacked in one cell. The face shown and the one
   before cross-fade on the same time and curve, so that one makes up for the other (never a blink),
   and nothing moves. (Stronger than the 40 % of charts.css: a face is shown whole or not at all.) */
.t-donut-center { position: absolute; inset: 27%; display: grid; place-items: center; pointer-events: none; }
.t-donut-face { grid-area: 1 / 1; display: flex; flex-direction: column; align-items: center; margin: 0; text-align: center; }
.t-chart.t-chart--donut .t-donut-face { opacity: 0; transition: opacity var(--t-chart-calm) ease; }
.t-chart.t-chart--donut .t-donut-face.is-rest { opacity: 1; }
.t-chart.t-chart--donut:is(.is-focused, .is-spotlit) .t-donut-face.is-rest { opacity: 0; }
.t-chart.t-chart--donut.is-focused .t-donut-face.is-pointed,
.t-chart.t-chart--donut.is-spotlit:not(.is-focused) .t-donut-face.is-spoken { opacity: 1; }
.t-donut-figure { font-family: var(--t-font-heading, var(--t-font-body)); font-size: 2.5rem; font-weight: 700; line-height: 1; letter-spacing: -0.02em; white-space: nowrap; font-variant-numeric: tabular-nums; transition: color var(--t-chart-pull) ease; }
.t-donut-name { display: -webkit-box; max-width: 9rem; margin-top: 0.375rem; overflow: hidden; color: var(--t-chart-muted); font-size: 0.875rem; line-height: 1.25; text-wrap: balance; -webkit-box-orient: vertical; -webkit-line-clamp: 3; }

/* The legend: a swatch, the label (it wraps), the value. */
.t-donut-legend { display: grid; gap: 0.125rem; margin: 0; padding: 0; list-style: none; }
.t-donut-row { display: grid; grid-template-columns: 0.75rem minmax(0, 1fr) auto; align-items: baseline; gap: 0.75rem; padding: 0.5rem 0; border-bottom: 1px solid var(--t-chart-rule); font-size: 1rem; line-height: 1.3; }
.t-donut-row:last-child { border-bottom: 0; }
.t-donut-swatch { align-self: start; margin-top: calc((1.3em - 0.75rem) / 2); width: 0.75rem; height: 0.75rem; border-radius: 3px; background: var(--c); transition: background-color var(--t-chart-pull) ease; }
.t-chart.is-focused .t-donut-swatch { transition-duration: var(--t-chart-calm); }
.t-donut-label { text-wrap: pretty; }
.t-donut-value { font-weight: 650; white-space: nowrap; font-variant-numeric: tabular-nums; transition: color var(--t-chart-pull) ease; }

/* The focus pull: the highlighted part takes the accent, in the ring, its swatch and the centre. */
.t-chart.is-pulled .t-donut-arc.is-hl { fill: var(--t-chart-accent); }
.t-chart.is-pulled .t-donut-row.is-hl .t-donut-swatch { background: var(--t-chart-accent); }
.t-chart.is-pulled .t-donut-row.is-hl .t-donut-label { font-weight: 650; }
.t-chart.is-pulled :is(.t-donut-row, .t-donut-face).is-hl :is(.t-donut-value, .t-donut-figure) { color: var(--t-chart-accent); }
/* The voice and the pointer: the part named or pointed at takes the accent while the rest steps back
   (the highlight gives its accent up meanwhile: one part in colour at a time). */
.t-chart.is-spotlit:not(.is-focused) .t-donut-arc.is-spoken,
.t-chart.is-focused .t-donut-arc.is-pointed { fill: var(--t-chart-accent); }
.t-chart.is-spotlit:not(.is-focused) .t-donut-row.is-spoken .t-donut-swatch,
.t-chart.is-focused .t-donut-row.is-pointed .t-donut-swatch { background: var(--t-chart-accent); }
.t-chart.is-focused .t-donut-arc.is-hl:not(.is-pointed) { fill: var(--t-donut-hl); }
.t-chart.is-focused .t-donut-row.is-hl:not(.is-pointed) .t-donut-swatch { background: var(--t-donut-hl); }
.t-chart.is-focused .t-donut-row.is-hl:not(.is-pointed) .t-donut-value { color: inherit; }
/* The entrance is written frame by frame; the centre's faces still cross-fade as the voice moves on. */
.t-chart.is-entering :is(.t-donut-arc, .t-donut-row, .t-donut-swatch) { transition: none; }

@container (max-width: 560px) {
  .t-donut-layout { grid-template-columns: minmax(0, 1fr); justify-items: center; gap: 1.5rem; }
  .t-donut-ring { width: min(100%, 15rem); }
  .t-donut-legend { width: 100%; }
  .t-donut-figure { font-size: 2.125rem; }
}

/* ── levels (D60): one silhouette, a funnel or a pyramid ──
   Rows are grid cells of equal height (the tallest note sets it); each holds a trapezoid stretched to
   it whose stroke, of the fill's colour, rounds its corners at any size (core charts/levels.ts). The
   column of the shape keeps the sizes the core measured its words against (19 rem wide, 9 narrow). */
.t-levels {
  --t-levels-shape: clamp(19rem, 46cqi, 22rem);
  --t-levels-gap: 0.5rem;
  --t-levels-r: max(5px, var(--t-chart-radius));
  --t-levels-soft: color-mix(in oklab, var(--t-chart-accent) 30%, var(--t-chart-paper));
  display: grid;
  grid-template-columns: var(--t-levels-shape) minmax(0, 34rem);
  grid-auto-rows: minmax(3.25rem, 1fr);
  gap: var(--t-levels-gap) 1.75rem;
}
.t-levels.is-sized { column-gap: 4.75rem; }
.t-levels.is-bare { grid-template-columns: var(--t-levels-shape); justify-content: center; }
.t-levels-row { position: relative; display: grid; place-items: center; min-width: 0; padding: 0 0.75rem; --t-levels-fill: var(--t-levels-soft); }
.t-levels-svg { position: absolute; top: var(--t-levels-r); left: var(--t-levels-r); width: calc(100% - 2 * var(--t-levels-r)); height: calc(100% - 2 * var(--t-levels-r)); overflow: visible; }
.t-levels-svg polygon {
  fill: var(--t-levels-fill); stroke: var(--t-levels-fill);
  stroke-width: calc(2 * var(--t-levels-r)); stroke-linejoin: round; vector-effect: non-scaling-stroke;
  transition: fill var(--t-chart-pull) ease, stroke var(--t-chart-pull) ease;
}
.t-levels-in { position: relative; display: none; font-size: 0.9375rem; font-weight: 650; line-height: 1.2; white-space: nowrap; transition: color var(--t-chart-pull) ease; }
.t-levels-row.is-in-wide .t-levels-in { display: block; }
/* The drop from the stage above, in the gap, just beyond the silhouette's edge. */
.t-levels-drop {
  position: absolute; top: calc(var(--t-levels-gap) / -2); left: calc(50% + var(--edge) * 50% + 0.5rem);
  transform: translateY(-50%);
  color: var(--t-chart-muted); font-size: 0.8125rem; font-weight: 550; line-height: 1; white-space: nowrap;
}
.t-levels-note { align-self: center; min-width: 0; }
.t-levels-head { margin: 0; font-size: 0.9375rem; line-height: 1.3; text-wrap: balance; }
.t-levels-note.is-in-wide :is(.t-levels-dup, .t-levels-head--dup) { display: none; }
.t-levels-name { font-weight: 600; }
.t-levels-num { margin-left: 0.25rem; font-weight: 650; white-space: nowrap; transition: color var(--t-chart-pull) ease; }
.t-levels-text { margin: 0.1875rem 0 0; color: var(--t-chart-muted); font-size: 0.875rem; line-height: 1.4; text-wrap: pretty; }
.t-levels-head + .t-levels-text { margin-top: 0.1875rem; }
.t-levels-texts { display: none; margin: 1.25rem 0 0; padding: 0; list-style: none; }
.t-levels-texts li { margin: 0.5rem 0 0; color: var(--t-chart-muted); font-size: 0.875rem; line-height: 1.4; }
.t-levels-texts b { margin-right: 0.25rem; color: var(--t-chart-ink); font-weight: 600; }
.t-chart :is(.t-levels-in, .t-levels-num, .t-levels-drop) { font-variant-numeric: tabular-nums; }

/* With a highlight, every level stands quiet (one grey silhouette) until the pull gives the one that
   matters the colour. */
.t-chart:has(.t-levels-row.is-hl) .t-levels-row { --t-levels-fill: var(--t-chart-quiet); }
.t-chart.is-pulled .t-levels-row.is-hl,
.t-chart.is-spotlit .t-levels-row.is-spoken { --t-levels-fill: var(--t-chart-accent); }
.t-chart.is-pulled .t-levels-row.is-hl .t-levels-in,
.t-chart.is-spotlit .t-levels-row.is-spoken .t-levels-in { color: var(--t-chart-on-accent, var(--t-chart-paper)); }
.t-chart.is-pulled :is(.t-levels-note.is-hl .t-levels-name, .t-levels-texts .is-hl b) { font-weight: 700; }
.t-chart.is-pulled .t-levels-note.is-hl .t-levels-num { color: var(--t-chart-accent); }

@container (max-width: 560px) {
  .t-levels { --t-levels-shape: clamp(9rem, 44cqi, 13rem); column-gap: 1rem; }
  .t-levels.is-sized { column-gap: 3.75rem; }
  .t-levels.is-bare { grid-template-columns: var(--t-levels-shape) minmax(0, 1fr); justify-content: stretch; }
  .t-levels-row { padding: 0 0.5rem; }
  .t-levels-row.is-in-wide .t-levels-in { display: none; }
  .t-levels-row.is-in-narrow .t-levels-in { display: block; }
  .t-levels-note.is-in-wide .t-levels-dup { display: inline; }
  .t-levels-note.is-in-wide .t-levels-head--dup { display: block; }
  .t-levels-note.is-in-narrow :is(.t-levels-dup, .t-levels-head--dup) { display: none; }
  .t-levels-head { font-size: 0.875rem; }
  .t-levels-text { font-size: 0.8125rem; line-height: 1.35; }
  .t-levels.is-texts-under .t-levels-text { display: none; }
  .t-levels.is-texts-under + .t-levels-texts { display: block; }
  .t-levels-drop { left: calc(50% + var(--edge) * 50% + 0.375rem); font-size: 0.75rem; }
}

/* ── matrix (D60) ──
   The y axis (its words turned), the plot, the x axis under it. The plot holds four tiles (names in
   their outer corners), the cross, the dots (14 px) and their labels on the side the core chose
   (data-side; data-nside under 560 px), 6 px from the dot: charts/matrix.ts places them with these
   sizes. Under 560 px the plot is square; if a label could not fit there (.t-matrix--legend), the dots
   carry numbers and the labels go into the legend under the plot. */
.t-matrix { display: grid; grid-template-columns: 1.375rem minmax(0, 1fr); column-gap: 0.625rem; row-gap: 0.5rem; max-width: 42rem; margin: 0 auto; }
.t-matrix-axis { display: flex; justify-content: space-between; align-items: center; gap: 0.75rem; color: var(--t-chart-muted); font-size: 0.8125rem; font-weight: 550; line-height: 1.2; }
.t-matrix-axis-name { color: var(--t-chart-ink); font-weight: 650; }
.t-matrix-axis span:empty { visibility: hidden; }
.t-matrix-y { grid-column: 1; grid-row: 1; writing-mode: vertical-rl; rotate: 180deg; white-space: nowrap; }
.t-matrix-x { grid-column: 2; grid-row: 2; }
.t-matrix-plot { grid-column: 2; grid-row: 1; position: relative; aspect-ratio: 4 / 3; touch-action: pan-y; }

.t-matrix-quads { position: absolute; inset: 0; display: grid; grid-template: 1fr 1fr / 1fr 1fr; }
.t-matrix-q { display: flex; padding: 0.75rem; background: color-mix(in oklab, var(--t-chart-ink) 4.5%, var(--t-chart-paper)); transition: background-color var(--t-chart-pull) ease; }
.t-matrix-q.is-tl { border-top-left-radius: var(--t-chart-radius); }
.t-matrix-q.is-tr { border-top-right-radius: var(--t-chart-radius); justify-content: flex-end; text-align: right; }
.t-matrix-q.is-bl { border-bottom-left-radius: var(--t-chart-radius); align-items: flex-end; }
.t-matrix-q.is-br { border-bottom-right-radius: var(--t-chart-radius); justify-content: flex-end; align-items: flex-end; text-align: right; }
.t-matrix-q-name { max-width: 84%; color: color-mix(in oklab, var(--t-chart-muted) 85%, var(--t-chart-paper)); font-size: 0.71875rem; font-weight: 700; line-height: 1.25; letter-spacing: 0.08em; text-transform: uppercase; transition: color var(--t-chart-pull) ease; }
.t-matrix-cross { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
.t-matrix-cross line { stroke: color-mix(in oklab, var(--t-chart-ink) 24%, transparent); stroke-width: 1.5; vector-effect: non-scaling-stroke; transform-box: view-box; transform-origin: 50% 50%; }

.t-matrix-dot {
  position: absolute; z-index: 2; width: 14px; height: 14px; margin: -7px 0 0 -7px; border-radius: 50%;
  display: grid; place-items: center;
  background: color-mix(in oklab, var(--t-chart-ink) 78%, var(--t-chart-paper));
  box-shadow: 0 0 0 3px var(--t-chart-paper);
  font-style: normal;
  transition: background-color var(--t-chart-pull) ease, box-shadow var(--t-chart-calm) var(--t-ease-out), opacity var(--t-chart-calm) ease;
}
.t-matrix-dot span { display: none; }
.t-matrix-label {
  position: absolute; z-index: 1; width: max-content; max-width: 10rem;
  font-size: 0.875rem; font-weight: 600; line-height: 1.25; text-wrap: balance; pointer-events: none;
  transition: color var(--t-chart-pull) ease, opacity var(--t-chart-calm) ease;
}
.t-matrix-label[data-side="r"] { transform: translate(13px, -50%); }
.t-matrix-label[data-side="l"] { transform: translate(calc(-100% - 13px), -50%); text-align: right; }
.t-matrix-label[data-side="t"] { transform: translate(-50%, calc(-100% - 13px)); text-align: center; }
.t-matrix-label[data-side="b"] { transform: translate(-50%, 13px); text-align: center; }
.t-matrix-label[data-side="rt"] { transform: translate(5px, calc(-100% - 5px)); }
.t-matrix-label[data-side="rb"] { transform: translate(5px, 5px); }
.t-matrix-label[data-side="lt"] { transform: translate(calc(-100% - 5px), calc(-100% - 5px)); text-align: right; }
.t-matrix-label[data-side="lb"] { transform: translate(calc(-100% - 5px), 5px); text-align: right; }
.t-matrix-legend { display: none; }

/* Pointed at, or said: a soft halo around the dot (no scale, no bounce). */
.t-chart .t-matrix-dot:is(.is-pointed, .is-spoken) { box-shadow: 0 0 0 3px var(--t-chart-paper), 0 0 0 5.5px color-mix(in oklab, var(--t-chart-ink) 28%, transparent); }

/* With a highlight, the dots stand quiet until the pull gives the one that matters the accent. */
.t-chart:has(.t-matrix-dot.is-hl) .t-matrix-dot { background: color-mix(in oklab, var(--t-chart-ink) 55%, var(--t-chart-paper)); }
.t-chart.is-pulled .t-matrix-dot.is-hl { background: var(--t-chart-accent); }
.t-chart.is-pulled .t-matrix-dot:not(.is-hl) { background: color-mix(in oklab, var(--t-chart-ink) 42%, var(--t-chart-paper)); }
.t-chart.is-pulled .t-matrix-label.is-hl { font-weight: 700; }
.t-chart.is-pulled .t-matrix-label:not(.is-hl) { color: color-mix(in oklab, var(--t-chart-ink) 78%, var(--t-chart-paper)); }
.t-chart.is-spotlit .t-matrix-dot.is-spoken { background: var(--t-chart-accent); }
/* A quadrant that carries the message. */
.t-chart.is-pulled .t-matrix-q.is-hl { background: color-mix(in oklab, var(--t-chart-accent) 13%, var(--t-chart-paper)); }
.t-chart.is-pulled .t-matrix-q.is-hl .t-matrix-q-name { color: color-mix(in oklab, var(--t-chart-accent) 82%, var(--t-chart-ink)); }
.t-chart.is-entering .t-matrix :is(.t-matrix-q, .t-matrix-q-name) { transition: none; }

@container (max-width: 560px) {
  .t-matrix { column-gap: 0.5rem; }
  .t-matrix-plot { aspect-ratio: 1; }
  .t-matrix-axis { font-size: 0.75rem; }
  .t-matrix-q { padding: 0.5625rem; }
  .t-matrix-q-name { font-size: 0.65625rem; letter-spacing: 0.06em; }
  .t-matrix-label { font-size: 0.8125rem; max-width: 7rem; }
  .t-matrix-label[data-nside="r"] { transform: translate(13px, -50%); text-align: left; }
  .t-matrix-label[data-nside="l"] { transform: translate(calc(-100% - 13px), -50%); text-align: right; }
  .t-matrix-label[data-nside="t"] { transform: translate(-50%, calc(-100% - 13px)); text-align: center; }
  .t-matrix-label[data-nside="b"] { transform: translate(-50%, 13px); text-align: center; }
  .t-matrix-label[data-nside="rt"] { transform: translate(5px, calc(-100% - 5px)); text-align: left; }
  .t-matrix-label[data-nside="rb"] { transform: translate(5px, 5px); text-align: left; }
  .t-matrix-label[data-nside="lt"] { transform: translate(calc(-100% - 5px), calc(-100% - 5px)); text-align: right; }
  .t-matrix-label[data-nside="lb"] { transform: translate(calc(-100% - 5px), 5px); text-align: right; }
  /* Labels that could not fit: numbered dots and a legend. */
  .t-matrix--legend .t-matrix-label { display: none; }
  .t-matrix--legend .t-matrix-dot { width: 1.5rem; height: 1.5rem; margin: -0.75rem 0 0 -0.75rem; color: var(--t-chart-paper); font-size: 0.75rem; font-weight: 700; line-height: 1; font-variant-numeric: tabular-nums; }
  .t-matrix--legend .t-matrix-dot span { display: block; }
  .t-chart.is-pulled .t-matrix--legend .t-matrix-dot.is-hl { color: var(--t-chart-on-accent, var(--t-chart-paper)); }
  .t-matrix--legend + .t-matrix-legend { display: grid; gap: 0.625rem; margin: 1.125rem 0 0; padding: 0; list-style: none; }
  .t-matrix-key { display: grid; grid-template-columns: 1.5rem 1fr; column-gap: 0.75rem; align-items: start; font-size: 0.9375rem; line-height: 1.35; }
  .t-matrix-key b { display: grid; place-items: center; width: 1.5rem; height: 1.5rem; border-radius: 50%; color: var(--t-chart-paper); background: color-mix(in oklab, var(--t-chart-ink) 78%, var(--t-chart-paper)); font-size: 0.75rem; font-weight: 700; line-height: 1; transition: background-color var(--t-chart-pull) ease; }
  .t-matrix-key > span { padding-top: 0.125rem; font-weight: 600; }
  .t-matrix-key small { display: block; margin-top: 0.125rem; color: var(--t-chart-muted); font-size: 0.8125rem; font-weight: 400; line-height: 1.4; }
  .t-chart:has(.t-matrix-key.is-hl) .t-matrix-key b { background: color-mix(in oklab, var(--t-chart-ink) 55%, var(--t-chart-paper)); }
  .t-chart.is-pulled .t-matrix-key.is-hl b { color: var(--t-chart-on-accent, var(--t-chart-paper)); background: var(--t-chart-accent); }
}

/* ── milestones (D60) ──
   A grid of equal columns over five rows: titles above (alternating only), dates above, the line
   with its dots, titles (or dates, alternating) below, titles below (alternating). Each element
   says its column (--c) and how many it may take (--span). Dots are rings on the paper; with a
   highlight the pull fills its dot and colours its date. Pointing is soothing: the dot's ring takes
   the accent and grows a pixel or two over 220 ms, the other events step back to 40 %. */
.t-ms {
  --t-ms-dot: 0.875rem;
  position: relative;
  display: grid;
  grid-template-columns: repeat(var(--columns, var(--n)), minmax(0, 1fr));
  grid-template-rows: auto auto var(--t-ms-dot) auto auto;
  padding-top: 0.25rem;
}
.t-ms-line {
  grid-row: 3; grid-column: 1 / -1; align-self: center;
  height: 2px; border-radius: 1px;
  background: var(--t-chart-quiet);
  transform-origin: 0 50%;
}
.t-ms-dot {
  position: relative; z-index: 1;
  grid-row: 3; grid-column: var(--c); justify-self: start; align-self: center;
  width: var(--t-ms-dot); height: var(--t-ms-dot);
  border-radius: 50%;
  background: var(--t-chart-paper);
  box-shadow: inset 0 0 0 2.5px var(--t-chart-accent);
  transition: opacity var(--t-chart-calm) ease, scale var(--t-chart-calm) var(--t-ease-out), box-shadow var(--t-chart-calm) ease, background-color var(--t-chart-pull) ease;
}
.t-ms-date {
  grid-row: 2; grid-column: var(--c) / span var(--span);
  margin: 0 0 0.5rem; padding-right: 1rem;
  font-family: var(--t-font-heading, var(--t-font-body));
  font-size: 1.0625rem; font-weight: 700; line-height: 1.2; letter-spacing: -0.005em;
  font-variant-numeric: tabular-nums;
  overflow-wrap: break-word;
  transition: opacity var(--t-chart-calm) ease, color var(--t-chart-pull) ease;
}
.t-ms-label { grid-row: 4; grid-column: var(--c) / span var(--span); margin-top: 0.875rem; padding-right: 1.25rem; }
.t-ms-title {
  margin: 0;
  font-family: var(--t-font-heading, var(--t-font-body));
  font-size: 1rem; font-weight: 650; line-height: 1.3;
  text-wrap: balance; overflow-wrap: break-word;
}
.t-ms-text { margin: 0.3125rem 0 0; color: var(--t-chart-muted); font-size: 0.875rem; line-height: 1.45; text-wrap: pretty; overflow-wrap: break-word; }

/* Alternating: above the line the title stands over its date, below the date comes first; texts
   go into the tip. */
.t-ms.is-alternate .t-ms-label.is-above { grid-row: 1; align-self: end; margin: 0 0 0.25rem; }
.t-ms.is-alternate .t-ms-date.is-below { grid-row: 4; margin: 0.5rem 0 0; }
.t-ms.is-alternate .t-ms-label.is-below { grid-row: 5; margin: 0.25rem 0 0; }
.t-ms.is-alternate .t-ms-text { display: none; }

/* With a highlight: every dot stands quiet until the pull fills the one that carries the idea. */
.t-chart:has(.t-ms-dot.is-hl) .t-ms-dot { box-shadow: inset 0 0 0 2.5px var(--t-chart-quiet); }
.t-chart.is-pulled .t-ms-dot.is-hl { background: var(--t-chart-accent); box-shadow: inset 0 0 0 2.5px var(--t-chart-accent); }
.t-chart.is-pulled .t-ms-date.is-hl { color: var(--t-chart-accent); }

/* Pointed at, or talked about: the ring takes the accent and grows a little, softly. The other
   dots step back by their colours, not their opacity, so the line never shows through them. */
.t-chart.is-focused .t-ms-dot:not(.is-pointed),
.t-chart.is-spotlit:not(.is-focused) .t-ms-dot:not(.is-spoken) { opacity: 1; box-shadow: inset 0 0 0 2.5px color-mix(in oklab, var(--t-chart-ink) 12%, var(--t-chart-paper)); }
.t-chart.is-pulled.is-focused .t-ms-dot.is-hl:not(.is-pointed),
.t-chart.is-pulled.is-spotlit:not(.is-focused) .t-ms-dot.is-hl:not(.is-spoken) { background: color-mix(in oklab, var(--t-chart-accent) 40%, var(--t-chart-paper)); box-shadow: inset 0 0 0 2.5px transparent; }
.t-chart:has(.t-ms-dot) .t-ms-dot:is(.is-pointed, .is-spoken) { scale: 1.2; box-shadow: inset 0 0 0 2.5px var(--t-chart-accent); }
.t-chart.is-spotlit:not(.is-pulled) .t-ms-dot.is-spoken { background: var(--t-chart-accent); }
.t-chart.is-entering .t-ms-line { transition: none; }

@container (max-width: 560px) {
  /* Down the left: dates, the line with its dots, titles and texts. */
  .t-ms {
    grid-template-columns: minmax(0, max-content) var(--t-ms-dot) minmax(0, 1fr);
    grid-template-rows: repeat(var(--n), auto);
    column-gap: 0.875rem; row-gap: 1.25rem;
    padding-top: 0;
  }
  .t-ms-line { grid-row: 1 / -1; grid-column: 2; justify-self: center; align-self: stretch; width: 2px; height: auto; margin-top: 0.5rem; transform-origin: 50% 0; }
  .t-ms-dot { grid-row: var(--c); grid-column: 2; justify-self: center; align-self: start; margin-top: 0.1875rem; }
  .t-ms .t-ms-date, .t-ms.is-alternate .t-ms-date.is-below { grid-row: var(--c); grid-column: 1; max-width: 6.5rem; margin: 0; padding: 0; text-align: right; font-size: 1rem; line-height: 1.25; }
  .t-ms .t-ms-label, .t-ms.is-alternate .t-ms-label:is(.is-above, .is-below) { grid-row: var(--c); grid-column: 3; align-self: start; margin: 0; padding: 0; }
  .t-ms.is-alternate .t-ms-text { display: block; }
  /* The texts are written: no tip. */
  .t-chart--milestones .t-chart-tip { display: none; }
}

/* ── process (D60) ──
   Steps in equal columns, each a circle over its title and text; a link from each circle to the next
   runs between them, clear of both. Without a highlight every circle is full of the accent; with one, they all stand
   quiet (a ring) until the pull fills the one that matters. Pointing is soothing: the circle's ring
   takes the accent over 220 ms, the other steps step back to 40 %. */
.t-process {
  --t-process-dot: 2.75rem;
  --t-process-gap: 1.5rem;
  --t-process-row: 1.25rem;
  display: grid;
  grid-template-columns: repeat(var(--n), minmax(0, 1fr));
  column-gap: var(--t-process-gap);
  padding-top: 0.25rem;
}
.t-process-step { position: relative; display: flex; flex-direction: column; align-items: center; min-width: 0; text-align: center; }
.t-process-link {
  --t-process-clear: 0.375rem;
  position: absolute; z-index: 0;
  top: calc(var(--t-process-dot) / 2 + 0.25rem - 1px);
  left: calc(50% + var(--t-process-dot) / 2 + var(--t-process-clear));
  width: calc(100% + var(--t-process-gap) - var(--t-process-dot) - 2 * var(--t-process-clear)); height: 2px;
  border-radius: 1px;
  background: var(--t-chart-tint);
  transform-origin: 0 50%;
  transition: background-color var(--t-chart-pull) ease, opacity var(--t-chart-calm) ease;
}
/* Links step back with the steps when one is pointed at or talked about. */
.t-chart:is(.is-focused, .is-spotlit) .t-process-link { opacity: 0.5; }
.t-process-n {
  position: relative; z-index: 1;
  display: grid; place-items: center; flex: none;
  width: var(--t-process-dot); height: var(--t-process-dot);
  margin: 0.25rem 0 0.875rem;
  border-radius: 50%;
  color: var(--t-chart-on-accent, var(--t-chart-paper));
  background: var(--t-chart-accent);
  font-family: var(--t-font-heading, var(--t-font-body));
  font-size: 1.0625rem; font-weight: 700; line-height: 1;
  font-variant-numeric: tabular-nums;
  transition: opacity var(--t-chart-calm) ease, color var(--t-chart-pull) ease, background-color var(--t-chart-pull) ease, box-shadow var(--t-chart-calm) var(--t-ease-out);
}
.t-process-title {
  margin: 0; max-width: 18rem;
  font-family: var(--t-font-heading, var(--t-font-body));
  font-size: 1.0625rem; font-weight: 650; line-height: 1.25; letter-spacing: -0.005em;
  text-wrap: balance; overflow-wrap: break-word;
}
.t-process-text {
  margin: 0.375rem 0 0; max-width: 18rem;
  color: var(--t-chart-muted);
  font-size: 0.9375rem; line-height: 1.45;
  text-wrap: pretty; overflow-wrap: break-word;
}

/* With a highlight: every circle stands quiet (a ring on the paper), then the pull fills the one
   that carries the idea. */
.t-chart:has(.t-process-n.is-hl) .t-process-link { background: var(--t-chart-quiet); }
.t-chart:has(.t-process-n.is-hl) .t-process-n {
  color: var(--t-chart-ink);
  background: var(--t-chart-paper);
  box-shadow: inset 0 0 0 2px var(--t-chart-quiet);
}
.t-chart.is-pulled .t-process-n.is-hl {
  color: var(--t-chart-on-accent, var(--t-chart-paper));
  background: var(--t-chart-accent);
  box-shadow: inset 0 0 0 2px var(--t-chart-accent);
}
.t-chart.is-pulled .t-process-n:not(.is-hl) { color: var(--t-chart-muted); }
.t-chart.is-pulled .t-process-title.is-hl { font-weight: 700; }

/* Pointed at, or talked about: the ring takes the accent (a quiet circle), softly. */
.t-chart:has(.t-process-n.is-hl) .t-process-n:is(.is-pointed, .is-spoken):not(.is-hl) {
  color: var(--t-chart-ink);
  box-shadow: inset 0 0 0 2px var(--t-chart-accent);
}
.t-chart.is-spotlit:not(.is-pulled) .t-process-n.is-spoken {
  color: var(--t-chart-on-accent, var(--t-chart-paper));
  background: var(--t-chart-accent);
  box-shadow: inset 0 0 0 2px var(--t-chart-accent);
}
.t-chart.is-entering .t-process-link { transition: none; }

@container (max-width: 560px) {
  .t-process {
    --t-process-dot: 2.25rem;
    grid-template-columns: minmax(0, 1fr);
    row-gap: var(--t-process-row);
    padding-top: 0;
  }
  .t-process-step {
    display: grid; grid-template-columns: var(--t-process-dot) minmax(0, 1fr);
    column-gap: 0.875rem; align-items: start; text-align: left;
  }
  .t-process-n { grid-row: 1 / span 2; margin: 0; font-size: 0.9375rem; }
  .t-process-title { grid-column: 2; max-width: none; padding-top: 0.4375rem; }
  .t-process-text { grid-column: 2; max-width: none; margin-top: 0.25rem; }
  /* The link runs down from this circle to the next one, through the gap between the steps. */
  .t-process-link {
    top: calc(var(--t-process-dot) + var(--t-process-clear)); left: calc(var(--t-process-dot) / 2 - 1px);
    bottom: calc(var(--t-process-clear) - var(--t-process-row));
    width: 2px; height: auto;
    transform-origin: 50% 0;
  }
}

/* ── proportion (D60) ── The figure beside a grid of icons; under 560 px the figure goes above. Icons
   keep their shape at any width (a person 3:5, a dot, a square); a lit icon holds its accent as a
   layer (.t-prop-ink) over its quiet shape, which the entrance fades in, in turn. */
.t-prop-layout { display: grid; grid-template-columns: minmax(8rem, max-content) minmax(0, 1fr); align-items: center; gap: 1.5rem 2.75rem; }
.t-prop-figure { max-width: 15rem; }
.t-prop-big { margin: 0; color: var(--t-chart-accent); font-family: var(--t-font-heading, var(--t-font-body)); font-size: 4rem; font-weight: 700; line-height: 0.95; letter-spacing: -0.03em; text-wrap: balance; font-variant-numeric: tabular-nums; }
.t-prop-label { margin: 0.625rem 0 0; color: var(--t-chart-muted); font-size: 1rem; line-height: 1.35; text-wrap: pretty; }
.t-prop-grid { display: grid; grid-template-columns: repeat(var(--cols), minmax(0, 1fr)); gap: 0.375rem 0.3125rem; width: min(100%, calc(var(--cols) * 2.25rem)); }
.t-prop-icon { position: relative; display: block; background: var(--t-chart-quiet); }
.t-prop-ink { position: absolute; inset: 0; background: var(--t-chart-accent); }
.t-prop--person .t-prop-icon {
  aspect-ratio: 3 / 5;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 20'%3E%3Ccircle cx='6' cy='3.2' r='3'/%3E%3Cpath d='M1.4 9.2a4.6 4.6 0 0 1 9.2 0v4.3a1.2 1.2 0 0 1-1.2 1.2h-.6l-.5 4.1a1 1 0 0 1-1 .9H4.7a1 1 0 0 1-1-.9l-.5-4.1h-.6a1.2 1.2 0 0 1-1.2-1.2z'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 20'%3E%3Ccircle cx='6' cy='3.2' r='3'/%3E%3Cpath d='M1.4 9.2a4.6 4.6 0 0 1 9.2 0v4.3a1.2 1.2 0 0 1-1.2 1.2h-.6l-.5 4.1a1 1 0 0 1-1 .9H4.7a1 1 0 0 1-1-.9l-.5-4.1h-.6a1.2 1.2 0 0 1-1.2-1.2z'/%3E%3C/svg%3E") center / contain no-repeat;
}
.t-prop--circle .t-prop-icon { aspect-ratio: 1; border-radius: 50%; overflow: hidden; }
.t-prop--square .t-prop-icon { aspect-ratio: 1; border-radius: 3px; overflow: hidden; }
.t-prop--circle .t-prop-grid, .t-prop--square .t-prop-grid { gap: 0.3125rem; width: min(100%, calc(var(--cols) * 2rem)); }

/* Pointing at the figure (or the lit icons): the lit icons lift by 2 px, softly. */
.t-chart .t-prop-icon.is-lit { transition: translate var(--t-chart-calm) var(--t-ease-out); }
.t-chart.is-focused .t-prop-icon.is-lit.is-pointed { translate: 0 -2px; }
.t-chart.is-entering .t-prop-icon { transition: none; }

@container (max-width: 560px) {
  .t-prop-layout { grid-template-columns: minmax(0, 1fr); gap: 1.25rem; }
  .t-prop-figure { max-width: none; }
  .t-prop-big { font-size: 3rem; }
}
@media (prefers-reduced-motion: reduce) {
  .t-chart.is-focused .t-prop-icon.is-lit.is-pointed { translate: none; }
}

/* Dialogue characters (docs/dialogues.md, characters; @elabora/player character/). The sizes are the
   dialogue's; these rules only make a character work without a rule of its own. */
.t-character { display: block; max-width: 100%; height: auto; overflow: visible; }
.t-character.t-character-portrait { width: 100%; height: 100%; overflow: hidden; }
/* The blink's eyelids stay hidden until the character's own animation shows them (opacity, not display:
   the animation overrides it). */
.t-character [data-part="eyes-closed"] { opacity: 0; }
/* Paused: every animation of the character stops where it is. Reduced motion: none plays, each part
   rests in its base pose (a gesture's final pose). */
.t-character [data-part="character"][data-paused], .t-character [data-part="character"][data-paused] * { animation-play-state: paused !important; }
.t-character [data-part="character"][data-reduced-motion], .t-character [data-part="character"][data-reduced-motion] * { animation: none !important; transition: none !important; }
/* Pictures: the expression's picture, or the speaker's initial. */
.t-character-picture { position: relative; display: block; width: 100%; height: 100%; }
.t-character-picture > img { display: block; width: 100%; height: 100%; object-fit: cover; }
.t-character-initial { display: grid; place-items: center; aspect-ratio: 1; font-weight: 600; color: var(--t-muted); }

/* Dialogues (D61; docs/dialogues.md, « What the learner sees »). The behaviour (dialogue/view.ts)
   fills the template's thread (data-t-log) and the room under it (data-t-options), and sets
   data-t-look (messaging, scene) on the dialogue. Colours come from the theme's dialog.* tokens
   (--t-dialog-*), each with its default from the charter. Motion follows the player's rules (« Motion »,
   player.css): rows come in a fade, what leaves goes in a fade, nothing grows to fill the window; in
   slides nothing moves the slide (the thread scrolls in its box, the room keeps the height of the
   tallest set of options). On phones a scene is shown as messaging. Nothing here assumes a light or
   a dark theme: quiet states are the theme's own colours mixed with transparency. */
.t-dialogue-root {
  --t-dl-bubble: var(--t-dialog-bubble, color-mix(in srgb, var(--t-text) 5%, var(--t-surface)));
  --t-dl-learner: var(--t-dialog-learner, color-mix(in srgb, var(--t-accent) 12%, var(--t-surface)));
  --t-dl-text: var(--t-dialog-text, var(--t-text));
  --t-dl-said: var(--t-dialog-word-spoken, var(--t-dl-text));
  /* The words still to be said: the ink of the words said, faint on whatever bubble it is on. */
  --t-dl-unsaid: var(--t-dialog-word-unspoken, color-mix(in srgb, var(--t-dl-said) 38%, transparent));
  --t-dl-note: var(--t-dialog-note, var(--t-primary));
  --t-dl-line: color-mix(in srgb, var(--t-text) 12%, transparent);
  --t-dl-radius: calc(var(--t-radius, 8px) + 8px);
  --t-dl-avatar: 2.5rem;
  --t-dl-indent: calc(var(--t-dl-avatar) + 0.625rem);
  position: relative; isolation: isolate; display: flex; flex-direction: column; gap: 0.875rem; color: var(--t-dl-text);
}

/* ── The thread ─────────────────────────────────────────────────────────── */
.t-dialogue-log {
  position: relative; display: flex; flex-direction: column; gap: 0.375rem; min-height: 10rem; margin: 0;
  padding: 1.25rem 1.25rem 1rem; border: 1px solid var(--t-dl-line); border-radius: var(--t-dl-radius); background: var(--t-surface);
}
/* Slides: a box of fixed size (the room the slide leaves, --t-dialog-fill), its thread anchored at the
   bottom, scrolled by the learner. */
/* Scrollbars in the theme's ink, thin, on a dark theme as on a light one. */
.t-dialogue-root .t-dialogue-log, .t-dialogue-root .t-dialogue-debrief { scrollbar-width: thin; scrollbar-color: color-mix(in srgb, var(--t-text) 28%, transparent) transparent; }
[data-presentation="slides"] .t-dialogue-root .t-dialogue-log { height: var(--t-dialog-fill, 24rem); min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
.t-dialogue-log > :first-child { margin-top: auto; }
.t-dialogue-log:focus-visible { outline: 3px solid var(--t-focus); outline-offset: 2px; }
/* What measures what fits and how tall the room must be: never seen. */
.t-dialogue-measure { position: absolute !important; inset-inline-start: 0; top: 0; height: auto !important; max-height: none !important; visibility: hidden; pointer-events: none; overflow: visible !important; contain: layout; }

.t-dialogue-row { display: flex; align-items: flex-end; gap: 0.625rem; min-width: 0; transition: opacity 220ms var(--t-ease-out), translate 220ms var(--t-ease-out); }
@starting-style { .t-dialogue-row { opacity: 0; translate: 0 calc(0.375rem * var(--t-move)); } }
.t-dialogue-root[data-t-quiet] .t-dialogue-row { transition: none; }
.t-dialogue-row.is-leaving, .t-dialogue-row.is-turning { opacity: 0; transition: opacity 180ms ease; }
.t-dialogue-row[data-side="right"] { flex-direction: row-reverse; }
.t-dialogue-row[data-first]:not(:first-child) { margin-top: 0.625rem; }

/* A character's round portrait, beside the first bubble of a series (the same SVG, framed on its face). */
.t-dialogue-avatar { flex: none; width: var(--t-dl-avatar); height: var(--t-dl-avatar); border-radius: 50%; overflow: hidden; background: color-mix(in srgb, var(--t-dl-speaker, var(--t-text)) 12%, var(--t-surface)); }
.t-dialogue-row:not([data-first]) .t-dialogue-avatar { visibility: hidden; }
.t-dialogue-avatar .t-character-initial { width: 100%; height: 100%; font-size: 1rem; color: color-mix(in srgb, var(--t-dl-speaker, var(--t-text)) 70%, var(--t-text)); }
.t-dialogue-root:not([data-t-learner-look]) .t-dialogue-row[data-role="learner"] .t-dialogue-avatar { display: none; }

.t-dialogue-bubble {
  position: relative; min-width: 0; max-width: min(34rem, 80%); padding: 0.625rem 1rem 0.6875rem;
  border-radius: 1.125rem 1.125rem 1.125rem 0.375rem; background: var(--t-dl-bubble);
}
.t-dialogue-row[data-side="right"] .t-dialogue-bubble { border-radius: 1.125rem 1.125rem 0.375rem 1.125rem; background: var(--t-dl-learner); }
.t-dialogue-row:not([data-first])[data-side="left"] .t-dialogue-bubble { border-top-left-radius: 0.375rem; }
.t-dialogue-row:not([data-first])[data-side="right"] .t-dialogue-bubble { border-top-right-radius: 0.375rem; }
/* The name above the first bubble of a series, in the speaker's colour. */
.t-dialogue-row[data-first] .t-dialogue-bubble { margin-top: 1.25rem; }
.t-dialogue-name { position: absolute; bottom: calc(100% + 0.1875rem); inset-inline-start: 0.375rem; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 0.8125rem; font-weight: 650; line-height: 1.2; color: color-mix(in srgb, var(--t-dl-speaker, var(--t-muted)) 72%, var(--t-dl-text)); }
.t-dialogue-row[data-side="right"] .t-dialogue-name { inset-inline: auto 0.375rem; }
/* A series names its speaker once (a scene names every bubble: its page may begin with any). */
.t-dialogue-row:not([data-first]) .t-dialogue-name { display: none; }
/* Lines of even length, a narration's as a bubble's; a bubble as wide as its lines (fitLines). */
.t-dialogue-text, .t-dialogue-narration { margin: 0; line-height: 1.5; overflow-wrap: anywhere; text-wrap: balance; }
.t-dialogue-text { max-width: 100%; }

/* What the voice brings: each word passes to the ink as it is said (ink), or appears with its
   letters (appear). Only colour and opacity: the bubble has its final size from the start. A line
   without a voice is whole at once (its words are all .is-said). */
.t-dialogue-ink .t-w { transition: color 120ms linear, opacity 120ms linear; }
.t-dialogue-root[data-t-reveal="ink"] .t-dialogue-ink .t-w:not(.is-said) { color: var(--t-dl-unsaid); }
.t-dialogue-ink .t-w.is-said { color: var(--t-dl-said); }
.t-dialogue-root[data-t-reveal="appear"] .t-dialogue-ink .t-w:not(.is-said), .t-dialogue-ink .t-l.is-out { opacity: 0; }
.t-dialogue-ink .t-l { transition: opacity 60ms linear; }

/* A narration: centred, without a bubble. */
.t-dialogue-row[data-role="narration"] { justify-content: center; padding: 0.375rem 2rem; }
.t-dialogue-said { max-width: 32rem; }
.t-dialogue-narration { text-align: center; font-style: italic; font-size: 0.9375rem; }

/* The trainer's note: an aside, in the thread but in neither side's lane (centred, without a box);
   its quality in a pill of its colour (--q: success, accent, error; else dialog.note), an icon and a
   word, never colour alone. */
.t-dialogue-row[data-role="note"] { justify-content: center; padding: 0.5rem 1.5rem 0.25rem; }
.t-dialogue-note { --q: var(--t-dl-note); max-width: 30rem; text-align: center; }
.t-dialogue-row[data-quality="good"] .t-dialogue-note { --q: var(--t-success); }
.t-dialogue-row[data-quality="ok"] .t-dialogue-note { --q: var(--t-accent); }
.t-dialogue-row[data-quality="bad"] .t-dialogue-note { --q: var(--t-error); }
.t-dialogue-note-head { display: flex; justify-content: center; margin: 0 0 0.375rem; font-size: 0.8125rem; font-weight: 650; line-height: 1.3; }
.t-dialogue-note .t-dialogue-quality { padding: 0.1875rem 0.6875rem 0.1875rem 0.5rem; border-radius: 999px; background: color-mix(in srgb, var(--q) 13%, transparent); }
.t-dialogue-note-body { font-size: 0.9375rem; line-height: 1.5; text-wrap: balance; }
.t-dialogue-note-body > :last-child { margin-bottom: 0; }
.t-dialogue-quality { display: inline-flex; align-items: center; gap: 0.25rem; font-weight: 600; }
.t-dialogue-quality .t-icon svg { width: 1rem; height: 1rem; stroke-width: 2.2; }
.t-dialogue-quality[data-quality="good"] .t-icon { color: var(--t-success); }
.t-dialogue-quality[data-quality="ok"] .t-icon { color: var(--t-accent); }
.t-dialogue-quality[data-quality="bad"] .t-icon { color: var(--t-error); }

/* A first choice gone back on: one grey line on the learner's side. */
.t-dialogue-row[data-role="first-choice"] { justify-content: flex-end; flex-direction: column; align-items: flex-end; gap: 0.125rem; }
.t-dialogue-first { display: flex; align-items: center; gap: 0.375rem; max-width: min(34rem, 80%); margin: 0.25rem 0 0; font-size: 0.8125rem; color: var(--t-muted); }
.t-dialogue-first-label { flex: none; font-weight: 600; }
.t-dialogue-first-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-decoration: line-through; text-decoration-color: color-mix(in srgb, var(--t-muted) 55%, transparent); }
.t-dialogue-link { display: inline-flex; align-items: center; gap: 0.375rem; min-height: 2.25rem; margin: 0.125rem 0 0; padding: 0 0.625rem; border: 0; border-radius: 999px; color: var(--t-primary); background: none; font: inherit; font-size: 0.875rem; font-weight: 600; cursor: pointer; transition: background-color 180ms var(--t-ease-out); }
.t-dialogue-link:hover { background: color-mix(in srgb, var(--t-primary) 8%, transparent); }
.t-dialogue-link .t-icon svg, .t-dialogue-action .t-icon svg { width: 1rem; height: 1rem; }

/* The end of a run: a quiet line across the thread. */
.t-dialogue-row[data-role="end"] { flex-direction: column; align-items: stretch; gap: 0.375rem; padding: 0.5rem 0 0.25rem; }
.t-dialogue-end { display: flex; align-items: center; gap: 0.75rem; margin: 0; font-size: 0.8125rem; font-weight: 650; color: var(--t-muted); }
.t-dialogue-end::before, .t-dialogue-end::after { content: ""; flex: 1; height: 1px; background: var(--t-dl-line); }
.t-dialogue-end-text { max-width: 32rem; margin: 0 auto; text-align: center; font-size: 0.9375rem; }

/* A bubble's tools: play a voice the browser refused, « Reprendre d'ici » on a past answer (shown when
   the row is pointed at or focused, always on touch screens). They sit beside the bubble on its free
   side, out of the flow: when they show, no bubble narrows and the thread does not move. A row that may
   show one (a voiced line, an answer the learner may go back to) keeps its room from the start: its
   bubble leaves the portrait, the gap and the button inside the row, however narrow. */
.t-dialogue-bubble, .t-dialogue-said { position: relative; }
.t-dialogue-tools { position: absolute; top: 50%; inset-inline-start: calc(100% + 0.375rem); translate: 0 -50%; display: flex; align-items: center; gap: 0.125rem; }
.t-dialogue-row[data-side="right"] .t-dialogue-tools { inset-inline: auto calc(100% + 0.375rem); }
.t-dialogue-row[data-tools] .t-dialogue-bubble { max-width: min(34rem, 80%, calc(100% - 5.75rem)); }
.t-dialogue-tool { display: inline-grid; place-items: center; width: 2.25rem; height: 2.25rem; padding: 0; border: 0; border-radius: 50%; color: var(--t-muted); background: transparent; cursor: pointer; transition: opacity 180ms ease, background-color 180ms var(--t-ease-out), scale var(--t-dur-press) var(--t-ease-out); }
.t-dialogue-tool:hover { background: color-mix(in srgb, var(--t-text) 7%, transparent); color: var(--t-text); }
.t-dialogue-tool:active { scale: 0.94; }
.t-dialogue-tool .t-icon svg { width: 1.125rem; height: 1.125rem; }
.t-dialogue-listen { color: var(--t-on-primary); background: var(--t-primary); }
.t-dialogue-listen:hover { color: var(--t-on-primary); background: color-mix(in srgb, var(--t-primary) 88%, var(--t-text)); }
.t-dialogue-resume { color: var(--t-text); background: var(--t-surface); box-shadow: inset 0 0 0 1px var(--t-dl-line); opacity: 0; }
.t-dialogue-row:hover .t-dialogue-resume, .t-dialogue-row:focus-within .t-dialogue-resume { opacity: 1; }
.t-dialogue-resume:hover { background: var(--t-surface); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--t-primary) 50%, var(--t-surface)); }
@media (hover: none) { .t-dialogue-resume { opacity: 1; } }

/* « … » in the box of the bubble to come (messaging, a line without a voice). */
.t-dialogue-typing .t-dialogue-text { visibility: hidden; }
.t-dialogue-dots { position: absolute; inset-inline-start: 1rem; top: 1.0625rem; display: flex; gap: 0.25rem; }
.t-dialogue-dots i { width: 0.375rem; height: 0.375rem; border-radius: 50%; background: var(--t-dl-unsaid); opacity: 0.35; animation: t-dialogue-dot 1.2s ease-in-out infinite; }
.t-dialogue-dots i:nth-child(2) { animation-delay: 0.15s; }
.t-dialogue-dots i:nth-child(3) { animation-delay: 0.3s; }
@keyframes t-dialogue-dot { 0%, 70%, 100% { opacity: 0.35; } 35% { opacity: 1; } }

/* « Nouveau message »: the learner scrolled up the thread and a bubble came. */
.t-dialogue-new { position: absolute; z-index: 2; inset-inline-start: 50%; top: calc(var(--t-dl-log-top, 0px) + var(--t-dl-log-height, 10rem) - 3.25rem); translate: -50% 0; display: inline-flex; align-items: center; gap: 0.25rem; height: 2.25rem; padding: 0 0.875rem 0 0.625rem; border: 0; border-radius: 999px; color: var(--t-on-primary); background: var(--t-primary); font: inherit; font-size: 0.8125rem; font-weight: 600; cursor: pointer; box-shadow: 0 6px 18px color-mix(in srgb, var(--t-text) 18%, transparent); transition: opacity 200ms var(--t-ease-out), translate 200ms var(--t-ease-out); }
@starting-style { .t-dialogue-new { opacity: 0; translate: -50% calc(0.375rem * var(--t-move)); } }
.t-dialogue-new .t-icon svg { width: 1rem; height: 1rem; }

/* ── The room under the thread: options, a turn's controls, the end ──────── */
.t-dialogue-options { display: flex; flex-direction: column; align-items: stretch; gap: 0.5rem; outline: none; }
.t-dialogue-options:focus { outline: none; }
.t-dialogue-final { display: inline-flex; align-items: center; gap: 0.375rem; margin: 0; font-size: 0.8125rem; font-weight: 650; color: var(--t-muted); }
.t-dialogue-final .t-icon svg { width: 0.9375rem; height: 0.9375rem; }
.t-dialogue-prompt { margin: 0 0 0.125rem; font-size: 1rem; font-weight: 650; line-height: 1.4; }
.t-dialogue-choices { display: flex; flex-direction: column; gap: 0.5rem; }
.t-dialogue-choice {
  display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; width: 100%; min-height: 3rem; margin: 0;
  padding: 0.6875rem 1.125rem; text-align: start; font: inherit; line-height: 1.4; color: var(--t-text);
  background: var(--t-surface); border: 1.5px solid color-mix(in srgb, var(--t-text) 16%, var(--t-surface)); border-radius: 0.875rem; cursor: pointer;
  transition: border-color 180ms var(--t-ease-out), background-color 180ms var(--t-ease-out), opacity 200ms ease, scale var(--t-dur-press) var(--t-ease-out);
}
.t-dialogue-choice:hover:not([aria-disabled="true"]) { border-color: color-mix(in srgb, var(--t-primary) 55%, var(--t-surface)); background: color-mix(in srgb, var(--t-primary) 4%, var(--t-surface)); }
.t-dialogue-choice:active:not([aria-disabled="true"]) { scale: 0.99; }
.t-dialogue-choice[aria-disabled="true"] { cursor: not-allowed; opacity: 0.5; }
.t-dialogue-choice.is-leaving { opacity: 0; pointer-events: none; }
.t-dialogue-choice.is-chosen { opacity: 0; pointer-events: none; border-color: var(--t-primary); background: var(--t-dl-learner); transition-duration: 180ms, 180ms, 240ms, 160ms; }
.t-dialogue-options[data-t-state="choosing"] .t-dialogue-choice:not([aria-disabled="true"]) { animation: t-dialogue-in 240ms var(--t-ease-out) both; }
.t-dialogue-options[data-t-state="choosing"] .t-dialogue-choice:nth-child(2) { animation-delay: 40ms; }
.t-dialogue-options[data-t-state="choosing"] .t-dialogue-choice:nth-child(3) { animation-delay: 80ms; }
.t-dialogue-options[data-t-state="choosing"] .t-dialogue-choice:nth-child(n+4) { animation-delay: 120ms; }
.t-dialogue-root[data-t-quiet] .t-dialogue-choice { animation: none !important; }
@keyframes t-dialogue-in { from { opacity: 0; translate: 0 calc(0.25rem * var(--t-move)); } }
.t-dialogue-choice-text { min-width: 0; }
/* An option's mark goes under its text when both do not fit side by side (a phone). */
.t-dialogue-choice:has(.t-dialogue-explored) { flex-wrap: wrap; row-gap: 0.25rem; }
.t-dialogue-choice:has(.t-dialogue-explored) .t-dialogue-choice-text { flex: 1 1 14rem; }
.t-dialogue-explored, .t-dialogue-unavailable { display: inline-flex; align-items: center; gap: 0.25rem; flex: none; font-size: 0.75rem; font-weight: 600; color: var(--t-muted); }
.t-dialogue-explored .t-icon svg { width: 0.875rem; height: 0.875rem; }

.t-dialogue-turn { display: flex; align-items: center; gap: 0.125rem; min-height: 2.75rem; animation: t-dialogue-fade 240ms ease both; }
@keyframes t-dialogue-fade { from { opacity: 0; } }
.t-dialogue-turn .t-dialogue-tool { width: 2.5rem; height: 2.5rem; }
.t-dialogue-turn-space { flex: 1; }
.t-dialogue-next, .t-dialogue-action {
  display: inline-flex; align-items: center; gap: 0.3125rem; min-height: 2.5rem; padding: 0 1rem; border: 1.5px solid var(--t-dl-line);
  border-radius: 999px; color: var(--t-text); background: var(--t-surface); font: inherit; font-size: 0.9375rem; font-weight: 600; cursor: pointer;
  transition: background-color 180ms var(--t-ease-out), border-color 180ms var(--t-ease-out), color 180ms var(--t-ease-out), scale var(--t-dur-press) var(--t-ease-out);
}
.t-dialogue-next { padding-inline-end: 0.625rem; }
.t-dialogue-next .t-icon svg { width: 1.125rem; height: 1.125rem; }
.t-dialogue-next:hover, .t-dialogue-action:hover { border-color: color-mix(in srgb, var(--t-primary) 45%, var(--t-surface)); }
.t-dialogue-next:active, .t-dialogue-action:active { scale: 0.97; }
/* « Suite » while the dialogue goes on by itself (a voice speaks, a pause): quiet, without its
   outline, its words in the theme's muted ink (still 4.5:1); a click ends the line there. When the
   dialogue waits for the learner (a text without a voice was shown): the theme's filled button. */
.t-dialogue-next { transition-timing-function: ease; transition-duration: 240ms; }
.t-dialogue-next:not(.is-waiting) { color: var(--t-muted); border-color: transparent; background: transparent; }
.t-dialogue-next:not(.is-waiting):hover { color: var(--t-text); border-color: var(--t-dl-line); }
.t-dialogue-next.is-waiting { color: var(--t-on-primary); background: var(--t-primary); border-color: var(--t-primary); }
.t-dialogue-next.is-waiting:hover { background: color-mix(in srgb, var(--t-primary) 88%, var(--t-text)); border-color: transparent; }
.t-dialogue-endbar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.5rem 1rem; animation: t-dialogue-fade 240ms ease both; }
.t-dialogue-count { margin: 0; font-size: 0.875rem; font-weight: 600; color: var(--t-muted); }
.t-dialogue-endbar-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-inline-start: auto; }
.t-dialogue-action { font-size: 0.875rem; }

/* The start card (begins click), over the empty thread. */
.t-dialogue-start { position: absolute; z-index: 1; inset-inline: 0; top: var(--t-dl-log-top, 0px); height: var(--t-dl-log-height, 10rem); display: grid; place-content: center; justify-items: center; gap: 0.875rem; padding: 1rem; text-align: center; }
.t-dialogue-start-title { margin: 0; max-width: 28rem; font-family: var(--t-font-heading); font-size: 1.25rem; font-weight: 650; line-height: 1.3; }
.t-dialogue-start-btn { display: inline-flex; align-items: center; gap: 0.375rem; }
.t-dialogue-start-btn .t-icon svg { width: 1.125rem; height: 1.125rem; }
.t-dialogue-options .t-dialogue-start { position: static; height: auto; }

/* ── A panel over the dialogue (modal.ts): the History, the debrief ──────── */
/* The rest of the dialogue under a veil, dark on any theme; a click on it closes the panel. */
.t-dialogue-veil { position: absolute; z-index: 4; inset: 0; border-radius: var(--t-dl-radius); background: rgb(10 13 18 / 0.42); transition: opacity 220ms ease; }
@starting-style { .t-dialogue-veil { opacity: 0; } }
.t-dialogue-veil[hidden] { display: none; }
.t-dialogue-close { display: inline-grid; place-items: center; width: 2.25rem; height: 2.25rem; padding: 0; border: 0; border-radius: 50%; color: var(--t-muted); background: var(--t-surface); cursor: pointer; transition: background-color 180ms var(--t-ease-out), color 180ms var(--t-ease-out); }
.t-dialogue-close:hover { color: var(--t-text); background: color-mix(in srgb, var(--t-text) 7%, var(--t-surface)); }
.t-dialogue-close .t-icon svg { width: 1.125rem; height: 1.125rem; }
.t-dialogue-history-close { display: none; }

/* ── The debrief ────────────────────────────────────────────────────────── */
.t-dialogue-debrief { transition: opacity 240ms var(--t-ease-out); }
@starting-style { .t-dialogue-debrief { opacity: 0; } }
/* Slides (and scenes): a panel over the thread, its box. */
.t-dialogue-root[data-t-debrief-open] > .t-dialogue-debrief {
  position: absolute; z-index: 5; inset-inline: 0; top: var(--t-dl-log-top, 0px); height: var(--t-dl-log-height, 24rem);
  overflow-y: auto; overscroll-behavior: contain; border: 1px solid var(--t-dl-line); border-radius: var(--t-dl-radius); background: var(--t-surface);
  box-shadow: 0 18px 48px rgb(10 13 18 / 0.22);
}
/* Its close button stays in its corner while it scrolls. */
.t-dialogue-debrief > .t-dialogue-close { position: sticky; z-index: 1; top: 0.625rem; display: grid; margin: 0.625rem 0.625rem -2.875rem auto; }
.t-dialogue-root[data-t-debrief-open] .t-dialogue-debrief-title { padding-inline-end: 2.5rem; }
.t-dialogue-debrief-card { padding: 1.375rem 1.5rem 1.5rem; border: 1px solid var(--t-dl-line); border-radius: var(--t-dl-radius); background: var(--t-surface); }
.t-dialogue-root[data-t-debrief-open] .t-dialogue-debrief-card { border: 0; border-radius: 0; background: none; }
.t-dialogue-debrief-title { margin: 0 0 0.375rem; font-family: var(--t-font-heading); font-size: 1.375rem; font-weight: 650; line-height: 1.25; }
.t-dialogue-debrief-text { margin: 0 0 0.75rem; }
.t-dialogue-debrief-text > :last-child { margin-bottom: 0; }
.t-dialogue-score { margin: 0 0 0.75rem; color: var(--t-muted); }
.t-dialogue-score strong { margin-inline-start: 0.25rem; color: var(--t-text); }
.t-dialogue-debrief-head { margin: 1.125rem 0 0.5rem; font-size: 0.875rem; font-weight: 700; }
.t-dialogue-decisions { display: flex; flex-direction: column; gap: 0.625rem; margin: 0; padding: 0; list-style: none; counter-reset: t-dialogue-decision; }
.t-dialogue-decision { position: relative; padding: 0.75rem 0.875rem 0.75rem 2.75rem; border-radius: 0.75rem; background: var(--t-dl-bubble); counter-increment: t-dialogue-decision; }
.t-dialogue-decision::before { content: counter(t-dialogue-decision); position: absolute; inset-inline-start: 0.875rem; top: 0.75rem; display: grid; place-items: center; width: 1.375rem; height: 1.375rem; border-radius: 50%; font-size: 0.75rem; font-weight: 700; color: var(--t-muted); background: var(--t-surface); }
.t-dialogue-decision p { margin: 0; }
.t-dialogue-decision-prompt { font-size: 0.8125rem; font-weight: 600; color: var(--t-muted); }
.t-dialogue-decision-choice { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.25rem 0.625rem; margin-top: 0.125rem !important; font-weight: 600; }
.t-dialogue-decision-choice .t-dialogue-quality { align-self: center; font-size: 0.8125rem; }
.t-dialogue-decision-kept { margin-top: 0.125rem !important; font-size: 0.875rem; color: var(--t-muted); }
.t-dialogue-decision-note { margin-top: 0.375rem; font-size: 0.9375rem; }
.t-dialogue-decision-note > :last-child { margin-bottom: 0; }
.t-dialogue-others { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0; padding: 0; list-style: none; }
.t-dialogue-others li { display: inline-flex; align-items: baseline; gap: 0.375rem; padding: 0.375rem 0.75rem; border: 1px dashed var(--t-dl-line); border-radius: 999px; font-size: 0.875rem; }
.t-dialogue-others li[data-found] { border-style: solid; }
.t-dialogue-other-title { font-weight: 600; }
.t-dialogue-other-state { font-size: 0.8125rem; color: var(--t-muted); }
/* « Changer ce choix » under each decision, « Recommencer » at the foot: the debrief is where the
   learner acts, without closing it first. */
.t-dialogue-change { margin: 0.375rem 0 -0.25rem -0.625rem; }
.t-dialogue-debrief-foot { display: flex; margin-top: 1.25rem; }

/* ── Going back (moves.ts) ──────────────────────────────────────────────── */
/* Where the thread goes on: « Vous reprenez ici », « Nouvel essai », in the theme's colour between
   two hairlines; it stays until the path is cut before it. */
.t-dialogue-row[data-role="marker"] { padding: 0.375rem 0; }
/* A break in the thread, as a date between messages: its words between two lines, in the muted colour,
   without an icon or a link's colour (it would read as one more button). */
.t-dialogue-marker { display: flex; align-items: center; gap: 0.75rem; width: 100%; margin: 0; font-size: 0.75rem; font-weight: 600; letter-spacing: 0.01em; color: var(--t-muted); }
.t-dialogue-marker::before, .t-dialogue-marker::after { content: ""; flex: 1; min-width: 1.5rem; height: 1px; background: color-mix(in srgb, var(--t-muted) 45%, transparent); }
/* The choice taken back, among the options of its decision. */
/* The option taken back: a dot in the primary colour where « déjà exploré » has its tick, as wide. */
.t-dialogue-previous::before { content: ""; flex: none; width: 0.875rem; height: 0.875rem; background: radial-gradient(circle, var(--t-primary) 0 0.1875rem, transparent 0.21875rem); }

/* ── Scene: the backdrop, the cast large, a few bubbles near them ─────────── */
.t-block.t-dialogue-look--scene.t-w-full { max-width: var(--t-dialog-scene-width, 75rem); }
.t-dialogue-stage { position: relative; overflow: hidden; border-radius: var(--t-dl-radius); background: color-mix(in srgb, var(--t-text) 4%, var(--t-surface)); }
.t-dialogue-backdrop { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; transition: opacity 240ms ease; }
@starting-style { .t-dialogue-backdrop { opacity: 0; } }
.t-dialogue-backdrop.is-leaving { opacity: 0; }
.t-dialogue-actor { position: absolute; bottom: 0; height: 69%; aspect-ratio: 2 / 3; }
.t-dialogue-actor[data-position="left"] { inset-inline-start: 5.5%; }
.t-dialogue-actor[data-position="right"] { inset-inline-end: 5.5%; }
.t-dialogue-actor[data-position="center"] { inset-inline-start: 50%; translate: -50% 0; }
.t-dialogue-actor > .t-character { width: 100%; height: 100%; }
.t-dialogue-history-btn { display: none; }
/* Phones: a scene is a thread, its backdrop a band above it. */
.t-dialogue-root[data-t-look="scene"] .t-dialogue-stage { height: 5.5rem; }
.t-dialogue-root[data-t-look="scene"] .t-dialogue-actor { display: none; }

@media (min-width: 761px) {
  .t-dialogue-root[data-t-look="scene"] {
    container-type: inline-size; display: block; width: min(100%, calc(var(--t-dialog-fill, 200rem) * 16 / 9)); aspect-ratio: 16 / 9; margin-inline: auto;
  }
  .t-dialogue-root[data-t-look="scene"] .t-dialogue-stage { position: absolute; inset: 0; height: auto; box-shadow: 0 1px 2px color-mix(in srgb, var(--t-text) 6%, transparent), 0 18px 48px color-mix(in srgb, var(--t-text) 8%, transparent); }
  .t-dialogue-root[data-t-look="scene"] .t-dialogue-actor { display: block; }
  .t-dialogue-root[data-t-look="scene"] .t-dialogue-log {
    position: absolute; z-index: 1; inset-inline: 23%; top: 6.5%; height: 48%; min-height: 0; padding: 0; border: 0; border-radius: 0; background: none;
    gap: 0.75rem; overflow: hidden; font-size: clamp(1rem, 1.6cqi, 1.375rem);
  }
  .t-dialogue-root[data-t-look="scene"] .t-dialogue-log > :first-child { margin-top: 0; }
  .t-dialogue-root[data-t-look="scene"]:not([data-t-history]) .t-dialogue-row[data-t-paged] { display: none; }
  .t-dialogue-root[data-t-look="scene"] .t-dialogue-row[data-side="left"] { justify-content: flex-start; }
  .t-dialogue-root[data-t-look="scene"] .t-dialogue-row[data-side="right"] { flex-direction: row; justify-content: flex-end; }
  .t-dialogue-root[data-t-look="scene"] .t-dialogue-avatar { display: none; }
  .t-dialogue-root[data-t-look="scene"] .t-dialogue-row[data-first]:not(:first-child) { margin-top: 0; }
  .t-dialogue-root[data-t-look="scene"] .t-dialogue-bubble {
    max-width: 82%; margin: 0 0 0.875em; padding: 0.75em 1.1em 0.8em; border-radius: 1em; background: var(--t-surface);
    box-shadow: 0 1px 2px color-mix(in srgb, var(--t-text) 6%, transparent), 0 12px 28px color-mix(in srgb, var(--t-text) 9%, transparent);
  }
  .t-dialogue-root[data-t-look="scene"] .t-dialogue-row[data-side="right"] .t-dialogue-bubble { background: var(--t-dl-learner); }
  .t-dialogue-root[data-t-look="scene"] .t-dialogue-row[data-tools] .t-dialogue-bubble { max-width: min(82%, calc(100% - 2.75rem)); }
  .t-dialogue-root[data-t-look="scene"] .t-dialogue-row[data-role="character"][data-side="right"] .t-dialogue-bubble { background: var(--t-surface); }
  .t-dialogue-root[data-t-look="scene"] .t-dialogue-bubble::after { content: ""; position: absolute; bottom: -0.8em; width: 1.4em; height: 0.85em; background: inherit; }
  .t-dialogue-root[data-t-look="scene"] .t-dialogue-row[data-side="left"] .t-dialogue-bubble::after { inset-inline-start: 2em; clip-path: polygon(0 0, 100% 0, 8% 100%); }
  .t-dialogue-root[data-t-look="scene"] .t-dialogue-row[data-side="right"] .t-dialogue-bubble::after { inset-inline-end: 2em; clip-path: polygon(0 0, 100% 0, 92% 100%); }
  .t-dialogue-root[data-t-look="scene"] .t-dialogue-row[data-side="center"] .t-dialogue-bubble::after { inset-inline-start: calc(50% - 0.7em); clip-path: polygon(0 0, 100% 0, 50% 100%); }
  .t-dialogue-root[data-t-look="scene"] .t-dialogue-name, .t-dialogue-root[data-t-look="scene"] .t-dialogue-row:not([data-first]) .t-dialogue-name { position: static; display: block; margin: 0 0 0.2em; font-size: 0.72em; }
  .t-dialogue-root[data-t-look="scene"][data-t-history] .t-dialogue-row:not([data-first]) .t-dialogue-name { display: none; }
  .t-dialogue-root[data-t-look="scene"] .t-dialogue-row[data-first] .t-dialogue-bubble { margin-top: 0; }
  .t-dialogue-root[data-t-look="scene"] .t-dialogue-text { line-height: 1.42; }
  .t-dialogue-root[data-t-look="scene"] .t-dialogue-row[data-role="narration"] { padding: 0; }
  .t-dialogue-root[data-t-look="scene"] .t-dialogue-said { padding: 0.45em 1.1em; border-radius: 999px; background: color-mix(in srgb, var(--t-surface) 90%, transparent); }
  .t-dialogue-root[data-t-look="scene"] .t-dialogue-narration { font-size: 0.85em; }
  /* Over the backdrop, a note keeps a surface of its own. */
  .t-dialogue-root[data-t-look="scene"] .t-dialogue-row[data-role="note"] { padding: 0; justify-content: center; }
  .t-dialogue-root[data-t-look="scene"] .t-dialogue-note { max-width: 74%; padding: 0.7em 1.15em 0.8em; font-size: 0.8em; border-radius: 1em; background: color-mix(in srgb, var(--t-surface) 94%, transparent); box-shadow: 0 1px 2px color-mix(in srgb, var(--t-text) 6%, transparent), 0 10px 22px color-mix(in srgb, var(--t-text) 9%, transparent); }
  .t-dialogue-root[data-t-look="scene"] .t-dialogue-row[data-role="first-choice"] { padding-inline-start: 0; justify-content: center; align-items: center; }
  .t-dialogue-root[data-t-look="scene"] .t-dialogue-first { background: color-mix(in srgb, var(--t-surface) 92%, transparent); }
  .t-dialogue-root[data-t-look="scene"] .t-dialogue-first { padding: 0.25rem 0.75rem; border-radius: 999px; }
  .t-dialogue-root[data-t-look="scene"] .t-dialogue-row[data-role="end"] { padding: 0.25rem 15%; }
  .t-dialogue-root[data-t-look="scene"] .t-dialogue-end { padding: 0.35em 1em; border-radius: 999px; background: color-mix(in srgb, var(--t-surface) 92%, transparent); }
  .t-dialogue-root[data-t-look="scene"] .t-dialogue-row[data-role="marker"] { justify-content: center; }
  /* Over the backdrop, the break keeps its lines on a strip as wide as a note (no pill: a pill is a button here). */
  .t-dialogue-root[data-t-look="scene"] .t-dialogue-marker { width: min(26rem, 74%); padding: 0.45em 1.25em; border-radius: 0.5em; background: color-mix(in srgb, var(--t-surface) 90%, transparent); }
  .t-dialogue-root[data-t-look="scene"] .t-dialogue-marker::before { background: linear-gradient(to right, transparent, color-mix(in srgb, var(--t-muted) 55%, transparent)); }
  .t-dialogue-root[data-t-look="scene"] .t-dialogue-marker::after { background: linear-gradient(to left, transparent, color-mix(in srgb, var(--t-muted) 55%, transparent)); }
  /* Its options in the room under the bubbles, between the characters, anchored at the bottom. */
  .t-dialogue-root[data-t-look="scene"] .t-dialogue-options {
    position: absolute; z-index: 1; inset-inline: 25%; top: 57%; bottom: 4.5%; justify-content: flex-end; min-height: 0 !important; font-size: clamp(0.9375rem, 1.25cqi, 1.1875rem);
  }
  .t-dialogue-root[data-t-look="scene"] .t-dialogue-prompt { align-self: flex-start; padding: 0.3em 0.75em; border-radius: 999px; font-size: 1em; background: color-mix(in srgb, var(--t-surface) 90%, transparent); box-shadow: 0 1px 4px color-mix(in srgb, var(--t-text) 10%, transparent); }
  .t-dialogue-root[data-t-look="scene"] .t-dialogue-choice { min-height: 0; padding: 0.7em 1.15em; border-radius: 0.85em; font-size: 1em; box-shadow: 0 1px 2px color-mix(in srgb, var(--t-text) 6%, transparent); }
  .t-dialogue-root[data-t-look="scene"] .t-dialogue-turn, .t-dialogue-root[data-t-look="scene"] .t-dialogue-endbar { padding: 0.375rem 0.5rem; border-radius: 999px; background: color-mix(in srgb, var(--t-surface) 88%, transparent); }
  .t-dialogue-root[data-t-look="scene"] .t-dialogue-count { padding-inline-start: 0.5rem; }
  /* « Historique »: the whole thread over the scene, as messaging. */
  .t-dialogue-root[data-t-look="scene"] .t-dialogue-history-btn {
    position: absolute; z-index: 3; top: 3.5%; inset-inline-end: 2.2%; display: inline-flex; align-items: center; gap: 0.3125rem; height: 2.25rem; padding: 0 0.875rem 0 0.6875rem;
    border: 0; border-radius: 999px; color: var(--t-text); background: color-mix(in srgb, var(--t-surface) 90%, transparent); font: inherit; font-size: 0.875rem; font-weight: 600; cursor: pointer;
    box-shadow: 0 1px 2px color-mix(in srgb, var(--t-text) 10%, transparent); transition: background-color 180ms var(--t-ease-out);
  }
  .t-dialogue-root[data-t-look="scene"] .t-dialogue-history-btn .t-icon svg { width: 1rem; height: 1rem; }
  .t-dialogue-root[data-t-look="scene"] .t-dialogue-history-btn[aria-expanded="true"] { background: var(--t-surface); }
  .t-dialogue-root[data-t-look="scene"][data-t-history] .t-dialogue-log {
    z-index: 5; inset-inline: 18%; top: 4%; height: 92%; padding: 3.25rem 1.25rem 1rem; gap: 0.375rem; overflow-y: auto; border-radius: var(--t-dl-radius);
    background: var(--t-surface); box-shadow: 0 18px 48px rgb(10 13 18 / 0.22); font-size: 1rem;
    animation: t-dialogue-fade 220ms ease both;
  }
  .t-dialogue-root[data-t-look="scene"][data-t-history] .t-dialogue-history-close:not([hidden]) { position: absolute; z-index: 6; top: calc(4% + 0.625rem); inset-inline-end: calc(18% + 0.625rem); display: inline-grid; }
  .t-dialogue-root[data-t-look="scene"][data-t-history] .t-dialogue-bubble { box-shadow: none; margin: 0; background: var(--t-dl-bubble); font-size: 1rem; }
  .t-dialogue-root[data-t-look="scene"][data-t-history] .t-dialogue-row[data-role="learner"] .t-dialogue-bubble { background: var(--t-dl-learner); }
  .t-dialogue-root[data-t-look="scene"][data-t-history] .t-dialogue-bubble::after { display: none; }
  /* In the History, the notes and the narration as in messaging, without their surface. */
  .t-dialogue-root[data-t-look="scene"][data-t-history] :is(.t-dialogue-note, .t-dialogue-said) { background: none; box-shadow: none; }
  .t-dialogue-root[data-t-look="scene"][data-t-history] .t-dialogue-note { font-size: 1rem; }
  .t-dialogue-root[data-t-look="scene"] .t-dialogue-new { display: none; }
  .t-dialogue-root[data-t-look="scene"] .t-dialogue-start { inset: 0; top: 0; height: auto; z-index: 2; background: color-mix(in srgb, var(--t-surface) 30%, transparent); }
  .t-dialogue-root[data-t-look="scene"] .t-dialogue-start-title { padding: 0.5rem 1.25rem; border-radius: 999px; background: color-mix(in srgb, var(--t-surface) 92%, transparent); }
  .t-dialogue-root[data-t-look="scene"][data-t-debrief-open] > .t-dialogue-debrief { inset: 4% 14% 16%; height: auto; }
}

/* The learner asks for less motion: the dots rest, rows and options come in a fade only (--t-move). */
@media (prefers-reduced-motion: reduce) {
  .t-dialogue-dots i { animation: none; opacity: 0.6; }
  .t-dialogue-ink .t-w, .t-dialogue-ink .t-l { transition: none; }
}

}
