/* Hide LiaScript's per-quiz "Show Solution" button (the .lia-quiz__resolve
   element rendered by Quiz/View.elm `viewSolutionButton`). */
.lia-quiz__resolve { display: none !important; }

/* Quiz controls in the brand colour. LiaScript renders the radio/checkbox
   as native inputs with `appearance: none`, drawing them off the
   `--color-highlight` variable: an orange border when unchecked; checkbox
   `:checked` = orange fill behind a white icon-font checkmark; radio
   `:checked` = a thick `0.8rem` border that reads as a filled dot. We just
   recolour the border (and checkbox fill) — no inset shadow, which would
   sit over the white checkmark. The matching/gap dropdown is NOT a native
   `<select>` but a custom `.lia-dropdown` widget: `.lia-dropdown__selected`
   holds the label + chevron, and its border keys off `--color-highlight`
   (grey by default). `.lia-select` is the rare native select, kept for
   completeness. */
.lia-radio,
.lia-checkbox {
  accent-color: #fb6b00 !important;
  border-color: #fb6b00 !important;
}
.lia-radio:checked,
.lia-checkbox:checked {
  background-color: #fb6b00 !important;
  border-color: #fb6b00 !important;
}
.lia-dropdown,
.lia-select {
  border: 1px solid #fb6b00 !important;
  border-radius: 6px !important;
}
.lia-select { accent-color: #fb6b00 !important; color: #fb6b00 !important; }
.lia-dropdown__selected { color: #fb6b00 !important; }
.lia-dropdown__option:hover { background-color: rgba(251, 107, 0, 0.1) !important; }
/* Quiz "Check" button — LiaScript ships it as `.lia-btn--outline
   .lia-quiz__check` (orange outline, transparent fill, ORANGE text).
   Make it a filled brand-orange pill with a soft brand shadow. The label
   colour must be forced white on the button AND any child element (and
   via -webkit-text-fill-color) — otherwise LiaScript's outline rule keeps
   the text orange, leaving it invisible on the orange fill. */
.lia-quiz__check {
  background-color: #fb6b00 !important;
  border: 1px solid #fb6b00 !important;
  border-radius: 999px !important;
  box-shadow: 0 6px 18px rgba(251, 107, 0, 0.40) !important;
  display: block !important;
  width: 200px !important;
  transition: box-shadow 0.2s ease, transform 0.2s ease;
}
.lia-quiz__check,
.lia-quiz__check * {
  color: #ffffff !important;
  -webkit-text-fill-color: #ffffff !important;
}
.lia-quiz__check:hover {
  box-shadow: 0 10px 24px rgba(251, 107, 0, 0.55) !important;
  transform: translateY(-1px);
}

/* Replace LiaScript's default top-bar bird icon (`<img class="lia_header__logo"
   src="icon.svg">`) with the Mentorpiece logo. The `logo:` metadata field
   only ends up in the share dialog — LiaScript's header img is wired
   straight to `Const.icon` for the standard course view, so the only way
   to swap it is via CSS. `content: url(...)` repoints the `<img>` to a
   new image without changing the DOM, which keeps LiaScript's layout
   calculations (size, positioning) intact.
   The logo is inlined as a `data:` URL because LiaScript injects this
   stylesheet inline into its own document — a relative `url("assets/…")`
   would resolve against the LiaScript app origin (liascript.github.io or
   wherever it's hosted), not the course folder, and 404. A data URL has
   no resolution context to get wrong. */
img.lia_header__logo {
  content: url("data:image/svg+xml;base64,PHN2ZyBpZD0i0KHQu9C+0LlfMSIgZGF0YS1uYW1lPSLQodC70L7QuSAxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA5OC4wNCA2My45MyI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOiNlZTcyMWU7fS5jbHMtMntmaWxsOiMxZDFkMWI7fTwvc3R5bGU+PC9kZWZzPjxwYXRoIGNsYXNzPSJjbHMtMSIgZD0iTTU3LjQ4LDI5LjcxYzAtNy4xNy0yLjM1LTE0LjQ1LTcuODMtMTQuNDUtMy44NSwwLTYuODYsMi44Ni04LDYuMTdhMTEuMTcsMTEuMTcsMCwwLDAtLjU0LDMuNEw0MC45LDU5LjcxSDM0LjI3bC4xOS0zNC4xOWMwLTUuOTQtMi42Mi0xMC4yNi03Ljc5LTEwLjI2LTQuMjQsMC03LjMzLDMuNC04LjQxLDYuNzlhOS40OCw5LjQ4LDAsMCwwLS41NCwzLjMyTDE4LDU5LjI4SDExLjM0bC0uMjUtMzguNjJjMC0zLjg1LS4wOC03LS4zMS0xMC4xaDUuOTRsLjMxLDZoLjIzQTEyLjg3LDEyLjg3LDAsMCwxLDI5LDkuNzFhMTEsMTEsMCwwLDEsMTAuNTcsNy40OGguMTVhMTUuNTMsMTUuNTMsMCwwLDEsNC4xNy00Ljg2LDEyLjc1LDEyLjc1LDAsMCwxLDguMjUtMi42MmM0Ljk0LDAsMTEuNywxLjA4LDExLjcsMTQiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xMC43OCAtOS43MSkiLz48cGF0aCBjbGFzcz0iY2xzLTIiIGQ9Ik02NCw1OS4yOEg1Ny42MlYzNEw3Ni4zOSwxNmExOS43NSwxOS43NSwwLDAsMSwxMC43OS01LjI5LDE4LjU1LDE4LjU1LDAsMCwxLDExLDEuNzFBMTkuMzIsMTkuMzIsMCwwLDEsMTA4LjA2LDM1YTE4LjU5LDE4LjU5LDAsMCwxLTE4LjQsMTMuMkM4MSw0OCw3NC4zNSw0Mi43OSw3MiwzNC4zNGw2LjEtMS43M2ExMi4wNiwxMi4wNiwwLDAsMCwxMS43Nyw5LjI2YzkuNDMuMjUsMTItOC4zLDEyLjE1LTguNjZhMTIuOTQsMTIuOTQsMCwwLDAtNi42MS0xNS4xNEExMi4zLDEyLjMsMCwwLDAsODgsMTdhMTMuMzYsMTMuMzYsMCwwLDAtNy4yMywzLjZMNjQsMzYuNzFaIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTAuNzggLTkuNzEpIi8+PHBvbHlnb24gY2xhc3M9ImNscy0yIiBwb2ludHM9IjY2Ljc0IDQ5LjIxIDYwLjQgNDkuMTYgNjAuODEgMjQuOCA2Ny41MiAxOC41OSA2Ni43NCA0OS4yMSIvPjxyZWN0IGNsYXNzPSJjbHMtMiIgeD0iNjAuMDciIHk9IjAuNDkiIHdpZHRoPSI2LjM0IiBoZWlnaHQ9IjEzLjM1Ii8+PHBhdGggY2xhc3M9ImNscy0yIiBkPSJNMTYuNjIsNjYuODFoMXY2Ljc2SDE2LjU3VjY4LjQ4bC4wOC4zTDE1LDcyLjU0aC0uNzRsLTEuNjktMy42Ny4wOS0uMzl2NS4wOUgxMS41NlY2Ni44MWgxbDIsNC4zNVoiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xMC43OCAtOS43MSkiLz48cGF0aCBjbGFzcz0iY2xzLTIiIGQ9Ik0yMi4zOCw2Ni44MWgxLjA5djYuNzZIMjIuMzhabS41NSwwaDMuNzl2Ljg3SDIyLjkzWm0wLDNoMy4zNHYuODZIMjIuOTNabTAsMi45MmgzLjc5di44N0gyMi45M1oiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xMC43OCAtOS43MSkiLz48cGF0aCBjbGFzcz0iY2xzLTIiIGQ9Ik0zMS4xNCw2Ni44MWgxTDM1LjIxLDcybC0uMTUuMTJWNjYuODFoMS4wN3Y2Ljc1aC0xbC0zLjA4LTUuMDguMTUtLjEydjUuMkgzMS4xNFoiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xMC43OCAtOS43MSkiLz48cGF0aCBjbGFzcz0iY2xzLTIiIGQ9Ik00MC41LDY2LjgxaDQuODJ2Ljg3SDQwLjVabTEuODYuNTVoMS4xdjYuMjFoLTEuMVoiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xMC43OCAtOS43MSkiLz48cGF0aCBjbGFzcz0iY2xzLTIiIGQ9Ik01MC4zLDczLjM4YTEuOTMsMS45MywwLDAsMS0uODQtLjczLDIsMiwwLDAsMS0uMy0xLjFWNjguODNhMiwyLDAsMCwxLC4zLTEuMTFBMS45MSwxLjkxLDAsMCwxLDUwLjMsNjdhMy4zNiwzLjM2LDAsMCwxLDIuNTksMCwxLjkxLDEuOTEsMCwwLDEsLjg0LjcyLDIsMiwwLDAsMSwuMywxLjExdjIuNzJhMiwyLDAsMCwxLS4zLDEuMSwxLjkzLDEuOTMsMCwwLDEtLjg0LjczLDMuNDgsMy40OCwwLDAsMS0yLjU5LDBabTItLjc4YTEsMSwwLDAsMCwuNDYtLjQxLDEuMTIsMS4xMiwwLDAsMCwuMTYtLjYyVjY4LjhhMS4xNywxLjE3LDAsMCwwLS4xNi0uNjIsMSwxLDAsMCwwLS40Ni0uNCwxLjY1LDEuNjUsMCwwLDAtLjctLjE0LDEuNzEsMS43MSwwLDAsMC0uNy4xNCwxLjEyLDEuMTIsMCwwLDAtLjQ2LjQsMS4yNywxLjI3LDAsMCwwLS4xNi42MnYyLjc3YTEuMjEsMS4yMSwwLDAsMCwuMTYuNjIsMS4xNCwxLjE0LDAsMCwwLC40Ni40MSwxLjcxLDEuNzEsMCwwLDAsLjcuMTRBMS42NSwxLjY1LDAsMCwwLDUyLjI5LDcyLjZaIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTAuNzggLTkuNzEpIi8+PHBhdGggY2xhc3M9ImNscy0yIiBkPSJNNTguNTksNjYuODFoMS4xdjYuNzZoLTEuMVptLjQ5LDNoMi4xNGExLjIxLDEuMjEsMCwwLDAsLjUyLS4xMS43Ni43NiwwLDAsMCwuMzUtLjMxLjkuOSwwLDAsMCwuMTItLjQ4di0uMzVhMSwxLDAsMCwwLS4xMi0uNDguNzUuNzUsMCwwLDAtLjM0LS4zMiwxLjEyLDEuMTIsMCwwLDAtLjUzLS4xMUg1OS4wOHYtLjg3aDIuMDZhMy4wNywzLjA3LDAsMCwxLDEuMTguMjEsMS43LDEuNywwLDAsMSwuNzYuNiwxLjU5LDEuNTksMCwwLDEsLjI3Ljkzdi4zOWExLjYyLDEuNjIsMCwwLDEtLjI3Ljk0LDEuNzcsMS43NywwLDAsMS0uNzcuNjIsMywzLDAsMCwxLTEuMTcuMjFINTkuMDhabTEuODEuNjZMNjIsNzAuMjlsMS42OCwzLjI4SDYyLjM4WiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEwLjc4IC05LjcxKSIvPjxwYXRoIGNsYXNzPSJjbHMtMiIgZD0iTTY4LjA5LDY2LjgxaDEuMXY2Ljc2aC0xLjFabS41OCwzLjI3aDIuMDdhMS4wNywxLjA3LDAsMCwwLC41MS0uMTIuNzMuNzMsMCwwLDAsLjMzLS4zMiwxLDEsMCwwLDAsLjEyLS40OXYtLjUyYTEsMSwwLDAsMC0uMTItLjUuNy43LDAsMCwwLS4zMy0uMzMsMS4wNywxLjA3LDAsMCwwLS41MS0uMTJINjguNjd2LS44N2gyYTIuNjIsMi42MiwwLDAsMSwxLjEzLjIyLDEuNjksMS42OSwwLDAsMSwuNzQuNjMsMS43NywxLjc3LDAsMCwxLC4yNiwxdi41NGExLjc2LDEuNzYsMCwwLDEtLjI2LDEsMS42NywxLjY3LDAsMCwxLS43NC42MkEyLjgxLDIuODEsMCwwLDEsNzAuNyw3MWgtMloiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xMC43OCAtOS43MSkiLz48cGF0aCBjbGFzcz0iY2xzLTIiIGQ9Ik03OC4zMiw3My41N2gtMS4xVjY2LjgxaDEuMVoiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xMC43OCAtOS43MSkiLz48cGF0aCBjbGFzcz0iY2xzLTIiIGQ9Ik04My4wNyw2Ni44MWgxLjF2Ni43NmgtMS4xWm0uNTUsMGgzLjc5di44N0g4My42MlptMCwzSDg3di44Nkg4My42MlptMCwyLjkyaDMuNzl2Ljg3SDgzLjYyWiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEwLjc4IC05LjcxKSIvPjxwYXRoIGNsYXNzPSJjbHMtMiIgZD0iTTkyLjg2LDczLjM4YTEuODUsMS44NSwwLDAsMS0uODItLjc0LDIuMTYsMi4xNiwwLDAsMS0uMjktMS4xM1Y2OC44N0EyLjE4LDIuMTgsMCwwLDEsOTIsNjcuNzRhMS44NSwxLjg1LDAsMCwxLC44Mi0uNzQsMi44NCwyLjg0LDAsMCwxLDEuMjUtLjI2LDMsMywwLDAsMSwxLjIuMjMsMS44OSwxLjg5LDAsMCwxLC43OS42OSwyLjE5LDIuMTksMCwwLDEsLjM0LDEuMDlIOTUuMzNhMS41NywxLjU3LDAsMCwwLS4yLS42MSwxLjEzLDEuMTMsMCwwLDAtLjQzLS4zOCwxLjM4LDEuMzgsMCwwLDAtLjU5LS4xMywxLjM0LDEuMzQsMCwwLDAtLjY2LjE1LDEuMTgsMS4xOCwwLDAsMC0uNDMuNDMsMS40LDEuNCwwLDAsMC0uMTUuNjZ2Mi42NGExLjQsMS40LDAsMCwwLC4xNS42NiwxLDEsMCwwLDAsLjQzLjQyLDEuMzQsMS4zNCwwLDAsMCwuNjYuMTUsMS40NiwxLjQ2LDAsMCwwLC42LS4xMiwxLjE4LDEuMTgsMCwwLDAsLjQyLS4zOCwxLjU2LDEuNTYsMCwwLDAsLjItLjYyaDEuMTFhMi4zNCwyLjM0LDAsMCwxLS4zNCwxLjEsMS44MywxLjgzLDAsMCwxLS44LjY4LDIuNzUsMi43NSwwLDAsMS0xLjE5LjIzQTIuODUsMi44NSwwLDAsMSw5Mi44Niw3My4zOFoiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xMC43OCAtOS43MSkiLz48cGF0aCBjbGFzcz0iY2xzLTIiIGQ9Ik0xMDAuODQsNjYuODFoMS4xdjYuNzZoLTEuMVptLjU1LDBoMy43OXYuODdoLTMuNzlabTAsM2gzLjM0di44NmgtMy4zNFptMCwyLjkyaDMuNzl2Ljg3aC0zLjc5WiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEwLjc4IC05LjcxKSIvPjwvc3ZnPg==") !important;
  /* Adaptive sizing: `clamp(min, preferred, max)` ties the logo height
     to the viewport so it shrinks on small/mobile screens and grows on
     large displays. The preferred value `max(4.5vh, 2.8vw)` takes the
     larger of "4.5% of viewport height" and "2.8% of viewport width" —
     that way ultra-wide monitors (where vh would stay small even with
     a giant screen) also get a proportional logo. Clamped between 32px
     (mobile floor) and 80px (4K-display ceiling) to keep the wordmark
     legible at every scale. Width auto-scales from the replaced
     image's intrinsic aspect ratio. */
  height: clamp(32px, max(4.5vh, 2.8vw), 80px) !important;
  max-height: 80px !important;
  width: auto !important;
}

/* Sidebar TOC: active section in brand orange.
   LiaScript flags the current TOC entry with the `lia-active` class
   (added to the `.lia-toc__link` for the section that matches the
   viewed slide id — see Lia/Index/View.elm's `itemLink`). The default
   theme tints it the theme accent (typically teal); paint it brand
   orange so the navigation highlight matches the rest of the chrome.
   The vertical accent bar on the left of the active entry is drawn by
   LiaScript via `border-left` (or `box-shadow` / `::before` depending
   on version) — override every plausible carrier so the orange wins
   without us having to know which property the current LiaScript build
   uses. */
.lia-toc__link.lia-active,
.lia-active {
  color: #fb6b00 !important;
  border-color: #fb6b00 !important;
  border-left-color: #fb6b00 !important;
  box-shadow: inset 4px 0 0 0 #fb6b00 !important;
}
.lia-toc__link.lia-active::before,
.lia-active::before {
  background-color: #fb6b00 !important;
  border-color: #fb6b00 !important;
}

/* LiaScript chrome — buttons + pagination — recoloured to brand orange.
   The default theme paints these teal/cyan. Targets:
   * `.lia-btn` / `.lia-btn--transparent` — the top-right toolbar
     icons (bookmark, settings, EN language, share, info) and the
     `#lia-btn-toc` hamburger that opens the sidebar.
   * `.lia-pagination__content` — the page indicator pill at the bottom
     centre that shows the slide number between prev/next arrows.
   SVG icons inside the buttons use `currentColor`, so setting `color`
   cascades into stroke/fill. The few that hardcode their own fill get
   the explicit `fill`/`stroke` overrides below. */
.lia-btn,
.lia-btn--transparent,
.lia-btn--icon,
#lia-btn-toc {
  color: #fb6b00 !important;
}
.lia-btn svg,
.lia-btn--transparent svg,
.lia-btn--icon svg,
#lia-btn-toc svg {
  fill: currentColor !important;
  stroke: currentColor !important;
  color: #fb6b00 !important;
}
/* The visible pill is `.lia-pagination__content` — LiaScript's orange flex
   bar (prev | number | next). Style ONLY that element. The wrapping
   `.lia-pagination` is a full-width layout container with NO fill of its
   own; a broad `[class^="lia-pagination"]` selector painted it orange too,
   rendering a big lumpy blob behind the real pill. The inner
   `.lia-pagination__current` (page number) has no background of its own, so
   it just shows the pill orange through it — no override needed.

   Fully-rounded pill (`999px`), with one soft brand shadow. The ~15px bottom
   margin keeps that shadow from being clipped at the container/iframe bottom
   edge in site/LMS embeds where the pill is the last element.

   Centring: the pill lives in `.lia-slide__footer`, a flex container that
   left-aligns its children (`align-items: flex-start`, and on large screens
   `flex-direction: row` with the default `justify-content: flex-start`),
   stranding the pill at the bottom-left on wide viewports. Centre the footer's
   content on both axes and keep the pill a compact `fit-content` box. The fill
   stays on `__content`, so this re-centres without reintroducing the blob. */
.lia-slide__footer {
  align-items: center !important;
  justify-content: center !important;
}
.lia-pagination {
  width: fit-content !important;
  max-width: fit-content !important;
  margin-inline: auto !important;
}
.lia-pagination__content {
  background-color: #fb6b00 !important;
  color: #ffffff !important;
  border-radius: 999px !important;
  box-shadow: 0 8px 22px rgba(251, 107, 0, 0.45) !important;
  width: fit-content !important;
  max-width: fit-content !important;
  margin: 5px auto 15px !important;
}
.lia-pagination__content * {
  color: #ffffff !important;
}

/* Reading-progress bar — repaint the default theme-tinted fill to a
   neutral dark grey so it reads as a quiet progress indicator instead
   of competing with the brand-orange accents. The bar is a `<div>` with
   class `lia-progress` whose `width` is set inline proportional to how
   far the reader has scrolled (Lia/Settings/View.elm). */
.lia-progress {
  background-color: #c7c6c6 !important;
}

/* Brand-orange border on fenced code blocks. LiaScript wraps every fenced
   block in `.lia-code` (and `.lia-code--block` for stand-alone listings);
   targeting both keeps the rule resilient if the version-suffixed class
   changes. `!important` and the explicit colour beat LiaScript's own
   per-theme border rule, which would otherwise repaint the edge on
   theme switch. The inner Ace-editor container (`.lia-code__input`) and
   the Ace root itself (`.ace_editor`) each carry their own theme border;
   stripping those keeps the visible frame to a single orange line
   instead of the double-line "old + new" effect. */
/* `<pre class="code-block">` — code snippets emitted as raw HTML (instead of
   a ``` fence) when they contain heading-shaped `# …` lines that would
   otherwise pollute LiaScript's navigation. Styled to match the fenced-code
   frame: orange edge, rounded, monospace, horizontally scrollable. */
.lia-slide__container pre.code-block {
  border: 1px solid #fb6b00;
  border-radius: 6px;
  margin: 20px 0;
  padding: 12px 16px;
  overflow-x: auto;
  white-space: pre;
  font-family: monospace;
  font-size: 0.9em;
  line-height: 1.45;
  background-color: rgba(0, 0, 0, 0.03);
}

.lia-code,
.lia-code--block {
  border: 1px solid #fb6b00 !important;
  border-radius: 6px;
  /* Outer breathing room so the orange edge doesn't sit flush against
     the surrounding body text. Inner padding pushes the Ace-editor
     content away from the border on every side — without it Ace
     mounts its first character literally on the orange line. */
  margin: 20px 0;
  padding: 12px 16px;
}
.lia-code .lia-code__input,
.lia-code .ace_editor,
.lia-code--block .lia-code__input,
.lia-code--block .ace_editor {
  border: none !important;
  box-shadow: none !important;
}

/* Numbered-list markers as filled orange circles (Rise source styling).
   LiaScript's default `<ol>` markers render as small inline "1.", "2.", …
   in the theme accent colour (typically teal) — visually different from
   the Rise source, where each item starts with a solid orange disc and
   white bold number. Replace the native marker with a CSS counter
   rendered through `::before`, sized as a 36px circle.

   The `<li>` itself stays in normal block flow (no `display: flex`) so
   nested content — a paragraph followed by a `<ul>` sub-list — stacks
   vertically the way a reader expects. The circle is absolutely
   positioned inside the padded gutter the `<li>` reserves for it. An
   earlier flex-based layout put the paragraph and the nested sub-list
   side-by-side as flex items, which collapsed sub-bullets into a column
   to the right of their parent. */
/* All list selectors are scoped to `.lia-slide__container`, LiaScript's
   wrapper around the rendered course markdown (see Lia/View.elm). That
   keeps our brand markers off the toolbar/menu lists that LiaScript
   renders outside the slide container — those use `<ul><li>` with
   `lia-*` classes and previously picked up a stray orange ::before dot
   in the corner of every service button. An earlier attempt scoped via
   `:not([class*="lia"])` but LiaScript also classes the BODY-content
   `<ul>`/`<li>` with `lia-*`, so it killed our styling on every real
   in-course list as well. */
.lia-slide__container ol {
  /* `list-style: none` hides the native marker but ALSO turns off the
     browser-maintained `list-item` counter — which is the one that
     honours `<ol start="N">` correctly across every engine. Replace it
     with `list-style-type: ""` (CSS Lists Level 3): no visible marker,
     counter still ticks. */
  list-style-type: "";
  padding-left: 0;
  margin: 20px 0;
}
.lia-slide__container ol > li {
  position: relative;
  padding-left: 56px;
  margin: 12px 0;
  min-height: 36px;
}
.lia-slide__container ol > li::before {
  /* `counter(list-item)` is the built-in per-list counter — it resets
     automatically on every `<ol>` and respects the `start` attribute,
     so a `<ol start="3">` lands the first item on "3" everywhere
     without any `attr()` heroics. */
  content: counter(list-item);
  position: absolute;
  left: 0;
  top: 0;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background-color: #fb6b00;
  color: #ffffff;
  font-weight: bold;
  font-size: 15px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* Unordered-list markers as small orange discs (Rise source styling).
   Default LiaScript `<ul>` markers are a small typographic bullet in the
   theme accent colour; Rise renders an orange filled disc with a hanging
   indent (multi-line items keep their text aligned, not collapsed back
   under the dot). Same flex-based scaffolding as the `<ol>` rule above —
   the marker is a fixed-width `::before` so wrapped lines preserve the
   indent automatically. `margin-top: 0.55em` slides the disc's centre
   onto the first line's optical midline; using `flex-start` (not
   `center`) keeps multi-line items aligned to the first line rather
   than centring the dot against the whole block. */
.lia-slide__container ul {
  list-style: none;
  padding-left: 0;
  margin: 20px 0;
}
.lia-slide__container ul > li {
  position: relative;
  padding-left: 28px;
  margin: 12px 0;
}
.lia-slide__container ul > li::before {
  content: "";
  position: absolute;
  left: 4px;
  top: 0.55em;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background-color: #fb6b00;
}

/* GFM tables — orange brand header, light grid for the body.
   `_render_html_tables` rewrites Rise's raw `<table>` blocks into GFM
   tables whose first row becomes a `<th>` header. LiaScript's default
   table styling is essentially unstyled (browser defaults — left-aligned,
   no header tint), which reads as plain inside the Mentorpiece design.
   The override gives the header row a brand-orange fill with white bold
   centred text, and the body cells a hairline border so the grid is
   legible without being heavy. `border-collapse: collapse` keeps the
   outer header bar visually continuous (no double border under it). */
table {
  border-collapse: collapse;
  width: 100%;
  margin: 20px 0;
  /* Rounded corners + soft brand-tinted shadow, matching `.impact-a`
     and the other callout cards. `overflow: hidden` clips the inner
     cells (especially the orange `<th>` header bar) to the rounded
     frame — without it the header would extend square-cornered past
     the rounded table edge. */
  border-radius: 16px;
  overflow: hidden;
  box-shadow: 0 6px 18px rgba(251, 107, 0, 0.18);
}
/* `!important` on background-color — LiaScript ships its own
   `th { background: ... }` per theme. Without the bang the bg stays
   theme-coloured (often white) and our white text becomes invisible.
   Scoped to real header cells: `<th>` anywhere (the GFM common case),
   plus `<td>` inside an explicit `<thead>` (for renderers that drop
   `<th>` but still mark the header semantically). Earlier we also
   matched `tr:first-child td/th`, but `:first-child` is per-parent —
   inside a `<thead><tr></tr></thead><tbody><tr></tr><tr></tr></tbody>`
   structure it ALSO matched the first `<tr>` of `<tbody>`, painting
   the first data row orange too. */
table th,
table thead td {
  background-color: #fb6b00 !important;
  color: #ffffff !important;
  font-weight: bold;
  padding: 12px 16px;
  text-align: center;
  vertical-align: middle;
  border: none;
}
table td {
  border: 1px solid rgba(0, 0, 0, 0.08);
  padding: 12px 16px;
  text-align: center;
  vertical-align: middle;
}

/* Lone-bold paragraphs render as in-page subheadings.
   Rise authors write subsection titles as plain `<p><strong>Title</strong></p>`
   — they look like body text by default, but the author meant them as a
   visual break inside the page. LiaScript treats every `#` heading as a
   navigable section (so `####` would split into a new page), so the
   only inline-heading option is HTML. Auto-promote the existing shape
   instead of touching every paragraph: `:has(> strong:only-child)`
   matches any `<p>` whose sole *element* child is `<strong>`, and we
   nudge the typography to look like a sub-heading.

   `:has()` is Chrome 105+, Safari 15.4+, Firefox 121+. Older renderers
   fall back to plain bold-paragraph appearance — still readable, just
   not as heading-like.

   Trade-off: paragraphs that happen to have one inline `**bold**` span
   in the middle of running text (`Some <strong>bold</strong> word`)
   also match `strong:only-child` (CSS counts only element siblings,
   not text nodes around the strong). They'd pick up the heading
   typography. If that turns out to be a frequent false-positive, the
   converter can emit `<p class="subheading">` explicitly instead.

   `li` is in the exclusion list because a list item with a bold lead-in
   (`1. **Narrow AI.** These are systems…`) renders as
   `<li><p><strong>Narrow AI.</strong> These are systems…</p></li>` — the
   `<strong>` is the only *element* child, so the paragraph would falsely
   promote to a sub-heading and bold the entire item. A real sub-heading
   is never nested inside a list, so suppressing the rule under `li` kills
   the false-positive without losing any genuine inline heading. */
.lia-slide__container p:has(> strong:only-child):not(
  :is(.note, .impact-a, .impact-b, .impact-d, .accordion, .sim-button, details, li) p
) {
  font-size: 1.15em;
  font-weight: 700;
  margin: 28px 0 6px;
}

/* Body images get a subtle corner softening and a light gray drop
   shadow. Scoped to `.lia-slide__container img` so LiaScript chrome
   imagery isn't affected. The values are deliberately small — earlier
   we used 8px radius and a heavier shadow, but LiaScript overlays its
   own corner-bracket "media controls" on images, which clashed with a
   strong rounded frame. A 4px radius is just enough to read as
   intentional without fighting those overlays, and a softer
   black-at-10%-alpha shadow stays neutral. */
.lia-slide__container img {
  /* 16px radius matches `.impact-a`/`.note`/`.sim-button` so images
     share the same corner softness as the surrounding callout cards. */
  border-radius: 16px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.10);
}
/* Suppress LiaScript's decorative corner brackets on figure wrappers.
   `<figure class="lia-figure">` wraps every image; LiaScript draws four
   dark corner-mark decorations on it. They could live as pseudo-element
   content, as background images on the figure wrapper, or as a
   border-image. Strip every property that could carry them — pseudo
   `content`/`display`, plus `background`, `background-image`,
   `border-image`, `clip-path`, and `mask-image` on the wrapper and
   the inner media container. (The zoom-on-hover behaviour driven by
   `.lia-figure__zoom` is unaffected; we're only erasing the visual
   bracket decorations, not the interaction handler.) */
.lia-figure,
.lia-figure__media {
  background: none !important;
  background-image: none !important;
  border-image: none !important;
  clip-path: none !important;
  mask-image: none !important;
  -webkit-mask-image: none !important;
}
.lia-figure::before,
.lia-figure::after,
.lia-figure__media::before,
.lia-figure__media::after {
  display: none !important;
  content: none !important;
  background: none !important;
}

/* Single-class styled blocks. Author writes a single wrapper div, then plain
   paragraphs inside (or a <summary> for accordion). CSS picks first/last
   paragraphs for headings and renders icons / rules via ::before. */

/* impact-a — centered orange callout, bold first paragraph = caption */
.impact-a {
  background-color: rgba(251, 107, 0, 0.1) !important;
  padding: 45px 60px;
  text-align: center;
  margin: 20px 0;
  /* Border radius and shadow match `.note` and `.sim-button` so every
     orange-tinted callout reads as one consistent family. */
  border-radius: 16px;
  border: 1px solid rgba(251, 107, 0, 0.3);
  box-shadow: 0 6px 18px rgba(251, 107, 0, 0.18);
}
.impact-a > p {
  color: var(--color-text, inherit) !important;
  font-size: 18px;
  line-height: 1.6;
}
.impact-a > p:first-child {
  color: #fb6b00 !important;
  font-weight: bold;
  font-size: 20px;
  margin-bottom: 16px;
}
/* Body paragraphs and lists read left-aligned — only the caption stays
   centered (via the container's `text-align: center`). Same pattern as
   impact-b's body-alignment rule below. */
.impact-a > p:not(:first-of-type),
.impact-a > ul,
.impact-a > ol {
  text-align: left;
}
/* Match list-item text to the body-paragraph styling (colour + size).
   Without this the list items fall back to LiaScript's lighter/smaller
   default, looking out of place against the 18px `--color-text` body. */
.impact-a li {
  color: var(--color-text, inherit) !important;
  font-size: 18px;
  line-height: 1.6;
}

/* impact-b — gray centered card with orange rule + serif title */
.impact-b {
  background-color: rgba(0, 0, 0, 0.02) !important;
  padding: 40px 20px;
  text-align: center;
  margin: 30px 0;
  /* Matches the rest of the callout family's corner softness without
     touching the rest of impact-b's identity (orange ::before rule,
     centered serif title, gray background). */
  border-radius: 16px;
}
.impact-b::before {
  content: "";
  display: block;
  width: 40px;
  height: 3px;
  background-color: #fb6b00;
  margin: 0 auto 20px auto;
}
.impact-b > p {
  color: var(--color-text, #000) !important;
  font-size: 18px;
  line-height: 1.6;
  max-width: 800px;
  margin: 8px auto;
  opacity: 0.9;
}
.impact-b > p:first-of-type {
  font-size: 22px;
  font-weight: bold;
  margin-bottom: 15px;
  font-family: serif;
  opacity: 1;
}
/* Body paragraphs and lists read left-aligned — only the title and the
   orange ::before rule stay centered (via the container's text-align). */
.impact-b > p:not(:first-of-type),
.impact-b > ul,
.impact-b > ol {
  text-align: left;
}
/* Match list-item text to the body-paragraph styling (same colour, size,
   and muted opacity) — `<li>` doesn't match the `> p` rules, so without
   this it falls back to LiaScript's lighter/smaller default. Same fix as
   `.impact-a li`. */
.impact-b li {
  color: var(--color-text, #000) !important;
  font-size: 18px;
  line-height: 1.6;
  opacity: 0.9;
}

/* impact-d — gray card with orange top border + italic orange first line */
.impact-d {
  background-color: rgba(0, 0, 0, 0.03) !important;
  padding: 40px 50px;
  margin: 20px 0;
  border-top: 4px solid #fb6b00;
  /* Bottom corners only — the orange `border-top` accent reads
     better as a flat bar than a curved-then-clipped one, so keep the
     top edge square and round only the bottom corners. */
  border-radius: 0 0 16px 16px;
}
.impact-d > p {
  color: var(--color-text, #000) !important;
  line-height: 1.6;
}
/* Match list-item colour to the body paragraphs (`<li>` doesn't match
   the `> p` rule). impact-d body has no explicit font-size, so the
   default size is already consistent — only colour needs aligning. */
.impact-d li {
  color: var(--color-text, #000) !important;
  line-height: 1.6;
}
/* Rise's "Statement D" block renders its whole body in a bold, emphasized
   voice — the source markup only wraps runs in `<em>`, the weight comes
   from Rise's block styling. Match that rendering: bold the body
   paragraphs and list items (italic is preserved from the Markdown `*…*`).
   `strong` is pinned to the same weight on purpose: LiaScript's base CSS
   styles `b, strong { font-weight: 600 }`, so bullets/Result authored as
   `***…***` would render semibold (600) and look lighter than the plain
   paragraphs at 700 — forcing 700 here keeps one uniform bold across the
   block. The legal `footer` variant is excluded — regular-weight legal
   text, not an emphasized statement. */
.impact-d:not(.footer) > p,
.impact-d:not(.footer) li,
.impact-d:not(.footer) strong {
  font-weight: 700;
}
.impact-d > p:first-child {
  color: #fb6b00 !important;
  font-weight: bold;
  font-style: italic;
  font-size: 18px;
  margin-bottom: 8px;
}
/* Footer modifier — the recurring "Monthly updates…" legal info uses
   impact-d's frame but should read as black, not the orange highlight
   reserved for emphasized examples. The italic styling and font-size
   bump from .impact-d > p:first-child also don't apply here: the footer
   is body legal text, not a callout caption. */
.impact-d.footer > p:first-child {
  color: var(--color-text, #000) !important;
  font-style: normal;
  font-size: inherit;
}
/* LiaScript's default link colour is teal; the footer's links should
   match the orange accent used everywhere else in the impact-d frame. */
.impact-d.footer a {
  color: #fb6b00 !important;
}
/* Content hyperlinks — brand orange, overriding LiaScript's teal
   `--color-highlight`. Uses `:link`/`:visited` (specificity 0,2,1) so it
   beats LiaScript's own link rules WITHOUT `!important`; that in turn lets
   the `.sim-button`/`.open-button` CTA pills keep their white `!important`
   label (an `!important` here would turn the button text orange). Visited
   links get a muted, darker orange so they read as "already seen" — the
   browser only allows `:visited` to be re-COLOURED (privacy limits it to
   colour properties), so the distinction is colour, not underline/weight. */
.lia-slide__container a:link {
  color: #fb6b00;
}
.lia-slide__container a:visited {
  color: #a86a3c;
}
.lia-slide__container a:hover {
  color: #c45500;
}
/* The Rise source wraps the Creative Commons paragraph in a 1.2rem span
   while the rest of the footer sits in a 1.4rem span. The converter
   drops inline span sizes by design (see frontend conversion notes), so
   reinstate the size ratio via CSS on the last paragraph of the block. */
.impact-d.footer > p:last-of-type {
  font-size: calc(1em * 1.2 / 1.4);
}

/* note — circular "i" badge on the left (from ::before), content on the right.
   `gap` is split: column gap stays at 20px (separates the badge from the
   body text), row gap drops to 10px to tighten the vertical rhythm.
   Earlier we had `gap: 20px` for both axes — combined with the 20px top
   margin the global `<ul>` rule adds, the space between the note's
   header `<p>` and a body `<ul>` ballooned to ~40px. */
.note {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 10px 20px;
  align-items: start;
  background-color: rgba(251, 107, 0, 0.1) !important;
  /* Soft 30%-alpha border to match `.sim-button` — the previous solid
     `#fb6b00` outline read as much heavier/more saturated than the
     surrounding callouts. */
  border: 1px solid rgba(251, 107, 0, 0.3);
  /* Matches the original `.sim-button` radius for a unified callout look. */
  border-radius: 16px;
  /* Brand-tinted soft shadow lifts the card off the page surface. */
  box-shadow: 0 6px 18px rgba(251, 107, 0, 0.18);
  padding: 25px;
  margin: 20px 0;
}
.note::before {
  content: "i";
  grid-column: 1;
  grid-row: 1 / -1;
  align-self: start;
  width: 32px;
  height: 32px;
  border: 2px solid #fb6b00;
  border-radius: 50%;
  text-align: center;
  line-height: 32px;
  color: #fb6b00;
  font-family: serif;
  font-weight: bold;
  font-style: italic;
  font-size: 20px;
}
.note > * {
  grid-column: 2;
  color: var(--color-text, #000) !important;
  line-height: 1.6;
  margin: 4px 0;
}
/* The global `<ul>`/`<ol>` rules add a 20px top/bottom margin (good for
   stand-alone lists, too much inside a tight note). Override it here so
   the bullet sits close to the note's header line. */
.note > ul,
.note > ol {
  margin: 4px 0;
}

/* quote — Rise "quote" block (family `quote`). Rendered by `_emit_quote` as
   `<div class="quote">` holding the quotation paragraph(s) and, when present,
   an attribution paragraph. Mirrors Rise variant "a": a centred serif pull
   quote framed by hairline rules top and bottom, the quote text large with
   guillemets, and the attribution below it in a quieter grey. The guillemets
   are CSS `::before`/`::after` on the first paragraph (kept out of the text
   so the raw quotation stays clean and searchable). When a quote has no
   attribution the single paragraph is both first and last child; the
   attribution styling is scoped to `:last-child:not(:first-child)` so it
   only kicks in when there really is a separate attribution line. */
.quote {
  margin: 28px 0;
  padding: 24px 0;
  border-top: 1px solid rgba(0, 0, 0, 0.12);
  border-bottom: 1px solid rgba(0, 0, 0, 0.12);
  text-align: center;
}
.quote > p {
  color: var(--color-text, #000);
  margin: 0 auto;
  max-width: 46rem;
  font-size: 1.5em;
  line-height: 1.4;
  font-weight: 600;
}
/* Speaker avatar (mentor photo on the "Textbook authors" cards): a centred
   round thumbnail above the quote. The `<img>` sits in its own paragraph. */
.quote > p:has(img) {
  font-size: inherit;
  font-weight: inherit;
}
.quote img {
  display: block;
  width: 96px;
  height: 96px;
  margin: 0 auto 10px;
  border-radius: 50%;
  object-fit: cover;
}
/* Attribution line — the last paragraph when it isn't also the only one. */
.quote > p:last-child:not(:first-child) {
  margin-top: 14px;
  font-size: 0.95em;
  font-weight: 400;
  color: #6b6b6b;
}

/* timeline — Rise "interactive-fullscreen" timeline block (`_emit_interactive_fullscreen`).
   Each phase is a `.timeline-item` with an orange phase label (the date,
   e.g. "Сейчас"/"Затем"), a bold step title, and body text. The left accent
   bar evokes Rise's vertical timeline connector. The title is the second
   paragraph and picks up the global lone-bold sub-heading styling; the phase
   label is the first paragraph, recoloured brand orange here. */
.timeline-item {
  border-left: 3px solid #fb6b00;
  /* Light grey fill that fades to transparent toward the right, so each phase
     reads as its own box while staying airy (the orange bar is the left
     accent). Rounded on the right; the left edge is the bar. */
  background: linear-gradient(to right, rgba(0, 0, 0, 0.05), rgba(0, 0, 0, 0));
  border-radius: 0 8px 8px 0;
  padding: 14px 20px 14px 22px;
  margin: 18px 0;
}
.timeline-item > p:first-child {
  color: #fb6b00;
  font-weight: 700;
  margin: 0 0 6px;
}

/* flashcard — Rise "flashcard" block (`_emit_flashcard`). Interactive flip
   cards: `<details class="flashcard">` with the prompt in `<summary>` (always
   visible) and the answer revealed on click. Laid out as inline-block cards so
   a set flows into a responsive grid, echoing Rise's card layout; an orange
   top edge ties them to the brand callouts. A `↻` affordance on the summary
   signals the card flips. (`.flashcard` as a plain `<div>` — a front-only card
   — keeps the same framing.) */
.flashcard {
  display: inline-block;
  vertical-align: top;
  box-sizing: border-box;
  width: calc(33.333% - 16px);
  min-width: 220px;
  margin: 8px;
  padding: 16px 18px;
  border: 1px solid rgba(251, 107, 0, 0.3);
  border-top: 3px solid #fb6b00;
  border-radius: 12px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.06);
}
details.flashcard > summary {
  position: relative;
  list-style: none;
  cursor: pointer;
  font-weight: 700;
  padding-right: 24px;
  /* LiaScript paints `<summary>` with a theme-tinted (teal/green) background
     and its link/accent text colour; `!important` strips the background and
     forces the prompt to plain black so it reads as a card title, not a link. */
  background: none !important;
  background-color: transparent !important;
  color: var(--color-text, #000) !important;
}
details.flashcard > summary::-webkit-details-marker {
  display: none;
}
details.flashcard > summary::after {
  content: "↻";
  position: absolute;
  top: 0;
  right: 0;
  color: #fb6b00;
  font-size: 1.1em;
}
details.flashcard[open] > summary {
  margin-bottom: 10px;
  border-bottom: 1px solid rgba(251, 107, 0, 0.25);
  padding-bottom: 8px;
  /* When the card flips open the separator rule would otherwise fade in from
     the summary's text colour (black). Animate it from full brand orange to
     the resting light orange instead, so it flashes orange — never black. */
  animation: flashcard-rule 0.6s ease;
}
@keyframes flashcard-rule {
  from {
    border-bottom-color: #fb6b00;
  }
  to {
    border-bottom-color: rgba(251, 107, 0, 0.25);
  }
}
details.flashcard > p,
details.flashcard > summary ~ * {
  color: #fb6b00;
  font-size: 0.95em;
}
.flashcard > p:first-child {
  font-weight: 700;
}

/* accordion — <details>/<summary> with a clearly-tappable expand affordance.
   A solid orange disc with a white plus glyph (built from two crossed
   `background` gradients) sits on the right of the summary row; the disc
   rotates 135° into a minus on `[open]`. Hairline chevrons don't read as
   actionable for many readers — a filled brand-coloured target with a
   morphing state does. The whole summary row also darkens on hover so the
   bar (not just the disc) registers as a single clickable surface. */
.accordion {
  border: 1px solid rgba(251, 107, 0, 0.3);
  /* Corner radius and shadow match `.impact-a` so every orange-tinted
     callout — including this collapsible disclosure — shares the same
     framing language. `overflow: hidden` clips the inner content to
     the rounded frame so the open accordion respects the curve. */
  border-radius: 16px;
  margin: 20px 0;
  background-color: transparent !important;
  overflow: hidden;
  box-shadow: 0 6px 18px rgba(251, 107, 0, 0.18);
}
.accordion > summary {
  position: relative;
  background-color: rgba(251, 107, 0, 0.1) !important;
  /* `!important` — LiaScript styles bare <summary> with its link/accent
     colour (teal), which would override a plain `color:` rule. */
  color: var(--color-text, #000) !important;
  padding: 15px 56px 15px 20px; /* extra right padding reserves space for the indicator */
  font-weight: bold;
  cursor: pointer;
  list-style: none;
  outline: none;
  transition: background-color 200ms ease;
  -webkit-tap-highlight-color: transparent;
}
.accordion > summary::-webkit-details-marker { display: none; }
.accordion > summary::marker { display: none; }

/* Circular indicator pinned to the right side of the summary row */
.accordion > summary::after {
  content: "";
  position: absolute;
  top: 50%;
  right: 14px;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background-color: #fb6b00;
  /* Plus sign: two crossed bars drawn with linear-gradients, centred in the circle */
  background-image:
    linear-gradient(#fff, #fff),
    linear-gradient(#fff, #fff);
  background-size: 12px 2px, 2px 12px;
  background-position: center center, center center;
  background-repeat: no-repeat;
  transform: translateY(-50%) rotate(0deg);
  transition: transform 220ms cubic-bezier(0.4, 0, 0.2, 1),
              background-color 200ms ease,
              box-shadow 200ms ease;
  box-shadow: 0 0 0 0 rgba(251, 107, 0, 0);
  flex-shrink: 0;
}

/* Whole-row hover affordance + indicator emphasis */
.accordion > summary:hover {
  background-color: rgba(251, 107, 0, 0.18) !important;
}
.accordion > summary:hover::after {
  background-color: #e25f00;
  box-shadow: 0 0 0 4px rgba(251, 107, 0, 0.18);
}
.accordion > summary:focus-visible {
  background-color: rgba(251, 107, 0, 0.18) !important;
}
.accordion > summary:focus-visible::after {
  box-shadow: 0 0 0 4px rgba(251, 107, 0, 0.28);
}

/* Open state: rotate the plus into a minus (the vertical bar rotates away) */
.accordion[open] {
  padding-bottom: 16px;
}
.accordion[open] > summary {
  margin-bottom: 8px;
}
.accordion[open] > summary::after {
  transform: translateY(-50%) rotate(135deg);
}

.accordion > *:not(summary) {
  margin: 8px 20px;
  color: var(--color-text, #000);
  line-height: 1.6;
}


/* CTA blocks. Two card flavours share one layout + pill button:
     * `.sim-button`  — brand-orange EXERCISE card. The recurring training
       title + subtitle are injected by CSS (`::before`), so the only
       authored/converted content is the exercise name + the button:

           <div class="sim-button">

           Non-LLM metric Precision

           <a href="url">TRY PRACTICAL EXERCISE</a>

           </div>

     * `.open-button` — neutral grey card for generic CTAs (e.g. the
       cheat-sheet "OPEN" links), with full authored content — first <p>
       = uppercase title, last <p> = italic dash caption:

           <div class="open-button">

           AI Cheat Sheet for QAs

           <a href="url">OPEN</a>

           </div>

   No inner wrapper div, no class on the link. */
.sim-button,
.open-button {
  display: grid;
  /* Two equal columns: text on the left, button column on the right.
     The button is centered horizontally within its column (`justify-self`
     below) so it sits in the middle of the empty space rather than
     flush against the right edge. */
  grid-template-columns: 1fr 1fr;
  align-items: center;
  /* row-gap 0 so vertical spacing is governed by paragraph margins only;
     column-gap 32px keeps the text and pill button comfortably apart. */
  column-gap: 32px;
  row-gap: 0;
  margin: 30px 0;
  padding: 24px 32px;
  /* Matches `.note` so all callouts share the same corner softness. */
  border-radius: 16px;
}
/* Orange card — exercise CTA. */
.sim-button {
  background-color: rgba(251, 107, 0, 0.22);
  border: 1px solid rgba(251, 107, 0, 0.3);
  box-shadow: 0 6px 18px rgba(251, 107, 0, 0.18);
}
/* Grey card — generic/secondary CTA. Same pill button, but a neutral
   fill/border/shadow so it reads as the quieter action next to the
   orange exercise cards. */
.open-button {
  background-color: rgba(0, 0, 0, 0.05);
  border: 1px solid rgba(0, 0, 0, 0.12);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.10);
}
/* Shared pill button (orange on both cards). */
.sim-button > a,
.open-button > a {
  grid-column: 2;
  /* `grid-row: 1 / -1` only spans explicit rows; we don't define any, so
     the row references stay implicit and `-1` collapses to a single cell.
     `span 99` forces the button to occupy every implicit row regardless
     of how many paragraphs the text column has, which is what makes
     `align-self: center` actually center it. */
  grid-row: 1 / span 99;
  align-self: center;
  justify-self: center;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background-color: #fb6b00;
  color: #ffffff !important;
  padding: 14px 32px;
  border-radius: 999px;
  text-decoration: none !important;
  font-weight: bold;
  text-transform: uppercase;
  font-size: 14px;
  letter-spacing: 0.5px;
  box-shadow: 0 10px 28px rgba(251, 107, 0, 0.55);
  transition: all 0.2s ease;
}
/* Exercise CTA keeps the ✨ spark; the generic OPEN card gets a trailing ↗
   "external/open" arrow instead (matching the Google-Docs "Open ↗" control).
   Both pseudo-elements are flex items in the inline-flex `<a>`, so the
   button's `gap: 8px` spaces them from the label automatically. */
.sim-button > a::before {
  content: "✨";
}
.open-button > a::after {
  content: "↗";
}
/* Download cards use a down-right arrow (↘) — a "save/download" cue — instead
   of the ↗ "open externally" arrow on the generic OPEN cards. */
.open-button.download > a::after {
  content: "↘";
}
.sim-button > a:hover,
.open-button > a:hover {
  box-shadow: 0 14px 32px rgba(251, 107, 0, 0.65);
  transform: translateY(-2px);
}

/* open-button content — full authored paragraphs (first = uppercase
   title, last = italic dash caption). */
.open-button > p {
  grid-column: 1;
  margin: 4px 0;
}
.open-button > p:first-of-type {
  text-transform: uppercase;
  font-weight: bold;
  font-size: 15px;
  letter-spacing: 0.5px;
  margin-bottom: 8px;
}
.open-button > p:last-of-type:not(:first-of-type) {
  font-style: italic;
  /* `color-mix` lets us mute the theme-aware text colour without using
     `opacity:` (which would dim the ::before dash). Falls back to a
     mid-gray that's legible against both light and dark backgrounds. */
  color: #888;
  color: color-mix(in srgb, var(--color-text, #000) 70%, transparent);
  font-size: 14px;
  margin-top: 8px;
}
.open-button > p:last-of-type:not(:first-of-type)::before {
  content: "— ";
  color: #fb6b00;
  font-style: normal;
  font-weight: bold;
  margin-right: 2px;
}

/* Embedded previews — Rise "embed" blocks rendered as live iframes by
   `_emit_multimedia`. `.embed-video` is a responsive 16:9 frame (YouTube);
   `.embed-doc` is a fixed-height frame (Google Docs/Sheets/Slides). Both get
   the brand corner softening so they sit consistently among the callouts. */
.embed-video {
  position: relative;
  width: 100%;
  padding-bottom: 56.25%; /* 16:9 */
  height: 0;
  margin: 24px 0;
}
.embed-video iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  border-radius: 12px;
}
.embed-doc {
  margin: 24px 0;
  display: flex;
  flex-direction: column;
}
.embed-doc iframe {
  width: 100%;
  height: 520px;
  border: 1px solid rgba(0, 0, 0, 0.12);
  border-radius: 12px;
}
/* Small "Open ↗" button under the doc preview — opens the full document in a
   new tab (the iframe is view-only / can be cramped). Right-aligned, with a
   gap above it so it doesn't sit flush against the frame. */
.embed-doc .embed-open {
  align-self: flex-end;
  margin-top: 12px;
  padding: 4px 14px;
  font-size: 13px;
  font-weight: 600;
  color: #fb6b00 !important;
  border: 1px solid #fb6b00;
  border-radius: 999px;
  text-decoration: none;
}
.embed-doc .embed-open:hover {
  background-color: #fb6b00;
  color: #ffffff !important;
}

/* sim-button content — the recurring training title + subtitle are
   injected via two pseudo-elements (a single `::before` + `::first-line`
   two-tone doesn't render bold/uppercase reliably across engines):
     * the container's `::before` carries the bold-uppercase TITLE;
     * the exercise-name paragraph's own `::before` carries the regular
       SUBTITLE as a block line above the name.
   The single authored paragraph is the exercise name (bold). */
.sim-button::before {
  content: "🧠 Time for training!";
  grid-column: 1;
  text-transform: uppercase;
  font-weight: bold;
  font-size: 15px;
  letter-spacing: 0.5px;
  margin-bottom: 6px;
}
.sim-button > p {
  grid-column: 1;
  text-transform: none;
  font-weight: bold;
  font-style: normal;
  color: var(--color-text, #000);
  font-size: 15px;
  letter-spacing: normal;
  margin: 4px 0;
}
.sim-button > p::before {
  content: "To build practical skills, complete the exercise in the Mentorpiece AI Simulator:";
  display: block;
  font-style: normal;
  font-weight: normal;
  color: var(--color-text, #000);
  margin-bottom: 6px;
}
