mark.cm-hl {
  --cm-hl-bg: rgba(245, 158, 11, 0.32);
  color: inherit;
  padding: 0;
  border-radius: 2px;
  cursor: pointer;
  /* Paint the highlight as a centered band a little SHORTER than the line box instead of a
     full-height fill, so a highlight that wraps across two lines shows clear vertical space
     between the lines (box-decoration-break: clone gives each wrapped fragment its own band).
     Zero padding keeps the mark from reflowing the text it wraps. */
  background-color: transparent;
  background-image: linear-gradient(var(--cm-hl-bg), var(--cm-hl-bg));
  background-repeat: no-repeat;
  background-position: 0 50%;
  background-size: 100% 1em;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}
mark.cm-hl:hover { --cm-hl-bg: rgba(245, 158, 11, 0.5); }
mark.cm-hl.active { --cm-hl-bg: rgba(245, 158, 11, 0.7); outline: 2px solid var(--cp-warning); outline-offset: 1px; }
mark.cm-hl.cm-hl-gap {
  display: contents;
  background: transparent;
  background-image: none;
  box-shadow: none;
  padding: 0;
  cursor: inherit;
}
html[data-theme="dark"] mark.cm-hl { --cm-hl-bg: rgba(251, 191, 36, 0.28); }
html[data-theme="dark"] mark.cm-hl:hover { --cm-hl-bg: rgba(251, 191, 36, 0.42); }
html[data-theme="dark"] mark.cm-hl.active { --cm-hl-bg: rgba(251, 191, 36, 0.6); }
/* Code-block highlights: the mark lives inside <pre>/<code>. Keep a solid full-height fill (a
   short band would leave the monospace baseline looking clipped) and the tighter box. */
pre mark.cm-hl, code mark.cm-hl {
  padding: 0 2px;
  border-radius: 3px;
  background-color: var(--cm-hl-bg);
  background-image: none;
}
/* Composing preview: the amber highlight shown over the selected text while a new-comment
   composer is open, before it is saved. It looks like the saved highlight (same amber band,
   CMH-SEL-02) with a dashed outline cue that it is provisional. It carries no data-cid, so it is
   inert (no hover bubble, no click-to-open). It uses the same short-band paint as mark.cm-hl so
   the preview and the saved highlight are visually identical (only the dashed outline differs),
   and the band never reflows the line. The dashed outline is drawn outside the box (no reflow). */
mark.cm-preview {
  --cm-hl-bg: rgba(245, 158, 11, 0.32);
  color: inherit;
  padding: 0;
  border-radius: 2px;
  background-color: transparent;
  background-image: linear-gradient(var(--cm-hl-bg), var(--cm-hl-bg));
  background-repeat: no-repeat;
  background-position: 0 50%;
  background-size: 100% 1em;
  outline: 1px dashed rgba(245, 158, 11, 0.9);
  outline-offset: 1px;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}
html[data-theme="dark"] mark.cm-preview { --cm-hl-bg: rgba(251, 191, 36, 0.28); }
pre mark.cm-preview, code mark.cm-preview {
  padding: 0 2px;
  border-radius: 3px;
  background-color: var(--cm-hl-bg);
  background-image: none;
}

:root {
  --cm-sidebar-w: 400px;
  --cp-chrome-font: 0.85rem;
  --cp-chrome-help-font: 0.86rem;
  --cp-chrome-topic-font: 0.9rem;
  --cp-chrome-code-font: 0.78rem;
  --cp-chrome-body-font: 0.82rem;
  --cp-chrome-small-font: 0.72rem;
  --cp-chrome-tiny-font: 0.66rem;
  --cp-chrome-gap: 0.4rem;
  --cp-chrome-wide-gap: 0.6rem;
  --cp-chrome-button-gap: 0.35rem;
  --cp-chrome-button-y: 0.35rem;
  --cp-chrome-button-x: 0.7rem;
  --cp-chrome-action-x: 0.6rem;
  --cp-chrome-control-y: 0.4rem;
  --cp-chrome-control-x: 0.85rem;
  --cp-chrome-add-y: 0.3rem;
  --cp-chrome-add-x: 0.85rem;
  --cp-chrome-shell-y: 0.35rem;
  --cp-chrome-shell-x: 0.5rem;
  --cp-chrome-pill-y: 0.1rem;
  --cp-chrome-pill-x: 0.5rem;
  --cp-chrome-card-y: 0.7rem;
  --cp-chrome-card-x: 0.8rem;
  --cp-chrome-card-gap: 0.45rem;
  --cp-chrome-primary-y: 0.5rem;
  --cp-chrome-primary-x: 1.15rem;
  --cp-chrome-primary-font: 0.92rem;
  --cp-chrome-header-y: clamp(0.75rem, 3vw, 1rem);
  --cp-chrome-header-x: clamp(0.75rem, 3vw, 1.1rem);
  --cp-chrome-modal-x: 1.2rem;
  --cp-chrome-side-toc-left: 0.75rem;
  --cp-chrome-sort-y: 0.2rem;
  --cp-chrome-sort-x: 0.42rem;
  --cp-chrome-toc-link-y: 0.2rem;
  --cp-chrome-toc-link-x: 0.45rem;
  --cp-chrome-toc-button-pad: 0.3rem;
  --cp-chrome-scroll-y: 0.25rem;
  --cp-chrome-caret-gap: 0.2rem;
  --cp-chrome-search-top: 0.25rem;
  --cp-chrome-search-y: 0.3rem;
  --cp-chrome-search-x: 0.55rem;
  --cp-chrome-search-clear: 1.55rem;
  --cp-chrome-quote-y: 0.3rem;
  --cp-chrome-quote-x: 0.55rem;
  --cp-chrome-toast-x: 1.1rem;
  --cp-chrome-menu-item-y: 0.45rem;
}

body[data-cm-density="compact"] {
  --cp-chrome-font: 0.8rem;
  --cp-chrome-help-font: 0.81rem;
  --cp-chrome-topic-font: 0.84rem;
  --cp-chrome-code-font: 0.74rem;
  --cp-chrome-body-font: 0.78rem;
  --cp-chrome-small-font: 0.66rem;
  --cp-chrome-tiny-font: 0.62rem;
  --cp-chrome-gap: 0.3rem;
  --cp-chrome-wide-gap: 0.45rem;
  --cp-chrome-button-gap: 0.25rem;
  --cp-chrome-button-y: 0.28rem;
  --cp-chrome-button-x: 0.55rem;
  --cp-chrome-action-x: 0.5rem;
  --cp-chrome-control-y: 0.32rem;
  --cp-chrome-control-x: 0.7rem;
  --cp-chrome-add-y: 0.24rem;
  --cp-chrome-add-x: 0.7rem;
  --cp-chrome-shell-y: 0.25rem;
  --cp-chrome-shell-x: 0.4rem;
  --cp-chrome-pill-y: 0.06rem;
  --cp-chrome-pill-x: 0.38rem;
  --cp-chrome-card-y: 0.55rem;
  --cp-chrome-card-x: 0.65rem;
  --cp-chrome-card-gap: 0.32rem;
  --cp-chrome-primary-y: 0.38rem;
  --cp-chrome-primary-x: 0.9rem;
  --cp-chrome-primary-font: 0.86rem;
  --cp-chrome-header-y: clamp(0.6rem, 2.4vw, 0.82rem);
  --cp-chrome-header-x: clamp(0.6rem, 2.4vw, 0.9rem);
  --cp-chrome-modal-x: 1rem;
  --cp-chrome-side-toc-left: 0.6rem;
  --cp-chrome-sort-y: 0.16rem;
  --cp-chrome-sort-x: 0.34rem;
  --cp-chrome-toc-link-y: 0.16rem;
  --cp-chrome-toc-link-x: 0.36rem;
  --cp-chrome-toc-button-pad: 0.24rem;
  --cp-chrome-scroll-y: 0.18rem;
  --cp-chrome-caret-gap: 0.15rem;
  --cp-chrome-search-top: 0.2rem;
  --cp-chrome-search-y: 0.24rem;
  --cp-chrome-search-x: 0.45rem;
  --cp-chrome-search-clear: 1.38rem;
  --cp-chrome-quote-y: 0.24rem;
  --cp-chrome-quote-x: 0.45rem;
  --cp-chrome-toast-x: 0.9rem;
  --cp-chrome-menu-item-y: 0.36rem;
}

body[data-cm-density="comfortable"] {
  --cp-chrome-font: 0.9rem;
  --cp-chrome-help-font: 0.91rem;
  --cp-chrome-topic-font: 0.96rem;
  --cp-chrome-code-font: 0.82rem;
  --cp-chrome-body-font: 0.86rem;
  --cp-chrome-small-font: 0.76rem;
  --cp-chrome-tiny-font: 0.7rem;
  --cp-chrome-gap: 0.5rem;
  --cp-chrome-wide-gap: 0.75rem;
  --cp-chrome-button-gap: 0.45rem;
  --cp-chrome-button-y: 0.42rem;
  --cp-chrome-button-x: 0.85rem;
  --cp-chrome-action-x: 0.72rem;
  --cp-chrome-control-y: 0.48rem;
  --cp-chrome-control-x: 1rem;
  --cp-chrome-add-y: 0.36rem;
  --cp-chrome-add-x: 1rem;
  --cp-chrome-shell-y: 0.45rem;
  --cp-chrome-shell-x: 0.65rem;
  --cp-chrome-pill-y: 0.14rem;
  --cp-chrome-pill-x: 0.6rem;
  --cp-chrome-card-y: 0.85rem;
  --cp-chrome-card-x: 0.95rem;
  --cp-chrome-card-gap: 0.55rem;
  --cp-chrome-primary-y: 0.6rem;
  --cp-chrome-primary-x: 1.35rem;
  --cp-chrome-primary-font: 0.98rem;
  --cp-chrome-header-y: clamp(0.9rem, 3.4vw, 1.15rem);
  --cp-chrome-header-x: clamp(0.9rem, 3.4vw, 1.25rem);
  --cp-chrome-modal-x: 1.35rem;
  --cp-chrome-side-toc-left: 0.9rem;
  --cp-chrome-sort-y: 0.24rem;
  --cp-chrome-sort-x: 0.5rem;
  --cp-chrome-toc-link-y: 0.24rem;
  --cp-chrome-toc-link-x: 0.55rem;
  --cp-chrome-toc-button-pad: 0.36rem;
  --cp-chrome-scroll-y: 0.3rem;
  --cp-chrome-caret-gap: 0.25rem;
  --cp-chrome-search-top: 0.3rem;
  --cp-chrome-search-y: 0.36rem;
  --cp-chrome-search-x: 0.65rem;
  --cp-chrome-search-clear: 1.72rem;
  --cp-chrome-quote-y: 0.36rem;
  --cp-chrome-quote-x: 0.65rem;
  --cp-chrome-toast-x: 1.3rem;
  --cp-chrome-menu-item-y: 0.54rem;
}

.cm-toolbar {
  position: fixed; top: 1rem; right: 1rem; z-index: 100;
  display: flex; gap: var(--cp-chrome-gap);
  background: var(--cp-panel-strong); backdrop-filter: blur(8px);
  border: 1px solid var(--cp-border); border-radius: 999px;
  padding: var(--cp-chrome-shell-y) var(--cp-chrome-shell-x); box-shadow: var(--cp-shadow);
  align-items: center; font-size: var(--cp-chrome-body-font);
}
.cm-toolbar button {
  background: transparent; border: none; color: var(--cp-text);
  font-family: inherit; font-size: var(--cp-chrome-font); padding: var(--cp-chrome-button-y) var(--cp-chrome-button-x);
  border-radius: 999px; cursor: pointer; display: inline-flex;
  align-items: center; gap: var(--cp-chrome-button-gap);
}
.cm-toolbar button:hover { background: var(--cp-accent-soft); color: var(--cp-accent); }
/* When the panel is collapsed, the Show button gets a distinct filled bubble so it
   stands out from the encapsulating toolbar pill (it is the primary way to reopen). */
body:not(.sidebar-open) .cm-toolbar #btnToggleSidebar {
  background: var(--cp-accent-soft); color: var(--cp-accent); font-weight: 600;
}
body:not(.sidebar-open) .cm-toolbar #btnToggleSidebar:hover {
  background: var(--cp-accent); color: var(--cp-accent-fg);
}
.cm-toolbar .pill-count, .cm-sidebar header .pill-count {
  background: var(--cp-accent); color: var(--cp-accent-fg);
  border-radius: 999px; padding: var(--cp-chrome-pill-y) var(--cp-chrome-pill-x);
  font-size: var(--cp-chrome-small-font); font-weight: 600; min-width: 1.4rem; text-align: center;
}

.cm-sidebar {
  position: fixed; top: 0; right: 0; bottom: 0;
  width: var(--cm-sidebar-w, 400px); min-width: min(16rem, calc(100vw - 24px)); max-width: calc(100vw - 24px);
  background: var(--cp-bg-elevated); border-left: 1px solid var(--cp-border);
  box-shadow: var(--cp-shadow);
  display: flex; flex-direction: column;
  transform: translateX(100%); transition: transform 0.22s ease;
  z-index: 90;
}
body.sidebar-open .cm-sidebar { transform: translateX(0); }
.cm-sidebar-resize {
  position: absolute; left: 0; top: 0; bottom: 0; width: 8px; z-index: 3;
  cursor: ew-resize; touch-action: none; background: rgba(0, 0, 0, 0.01);
}
.cm-sidebar-resize::before {
  content: ""; position: absolute; left: 0; top: 0.75rem; bottom: 0.75rem; width: 2px;
  border-radius: 999px; background: transparent; transition: background 0.15s;
}
.cm-sidebar-resize:hover::before,
.cm-sidebar-resize:focus-visible::before,
body.cm-sidebar-resizing .cm-sidebar-resize::before { background: var(--cp-accent); }
.cm-sidebar-resize:focus-visible { outline: 2px solid var(--cp-accent); outline-offset: 2px; }
body.cm-sidebar-resizing { cursor: ew-resize; user-select: none; }
body.cm-sidebar-resizing .cm-sidebar { transition: none; }
/* When the panel is open, hide the floating toolbar entirely - every action it
   offers is present in the panel header, so there is no reason to keep a pill
   hovering over the document content. It returns when the panel is closed. */
body.sidebar-open .cm-toolbar { display: none; }

/* Mobile chrome polish (visual-audit findings):
   - Reserve space under the fixed toolbar so a flush page title is never drawn
     beneath the pill (only affects a title that sits at the very top).
   - Open the comments panel as a full-width sheet (no unreadable document sliver
     behind it) and drop the resize handle, which is meaningless at full width. */
@media (max-width: 700px) {
  body #commentRoot:not([data-cmh-mode="deck"]) > :first-child { margin-top: 3.2rem; }
}
@media (max-width: 640px) {
  .cm-sidebar { width: 100%; min-width: 100%; max-width: 100%; }
  .cm-sidebar-resize { display: none; }
}
/* === Layout recipe (centered max-width). Swap as needed. === */
body.sidebar-open .app { padding-right: 1.5rem; }
@media (min-width: 1100px) {
  body.sidebar-open .app {
    max-width: none; margin: 0;
    padding-left: 2rem;
    padding-right: calc(var(--cm-sidebar-w, 400px) + 2rem);
  }
}
@media (min-width: 1700px) {
  body.sidebar-open .app {
    padding-left: max(2rem, calc((100vw - var(--cm-toc-inset, 0px) - var(--cm-sidebar-w, 400px) - 1600px) / 2));
    padding-right: calc(var(--cm-sidebar-w, 400px) + max(2rem, calc((100vw - var(--cm-toc-inset, 0px) - var(--cm-sidebar-w, 400px) - 1600px) / 2)));
  }
}

.cm-sidebar header {
  padding: var(--cp-chrome-header-y) var(--cp-chrome-header-x); border-bottom: 1px solid var(--cp-border);
  display: flex; flex-direction: column; gap: var(--cp-chrome-gap);
}
.cm-sidebar .head-top { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-start; gap: var(--cp-chrome-gap) var(--cp-chrome-wide-gap); }
.cm-sidebar header h3 { margin: 0; font-size: 0.95rem; display: flex; align-items: center; gap: 0.5rem; flex: 1 1 8rem; min-width: 0; }
.cm-sidebar.is-narrow .head-top { align-items: stretch; }
.cm-sidebar.is-narrow .head-top h3 { flex-basis: 100%; }
.cm-ui-ico { flex: none; vertical-align: middle; }

/* Dependency-free styled tooltip (see setupTooltips). Dark bubble on both themes with
   a centered arrow; pointer-events:none so it never blocks the control it describes. */
.cm-tooltip {
  position: fixed; z-index: 400; max-width: 260px;
  background: #22272e; color: #fff;
  font-size: var(--cp-chrome-small-font); line-height: 1.35; padding: var(--cp-chrome-button-y) var(--cp-chrome-action-x);
  border-radius: 6px; box-shadow: 0 4px 16px rgba(0, 0, 0, 0.30);
  pointer-events: none; opacity: 0; transform: translateY(2px);
  transition: opacity 0.12s ease, transform 0.12s ease;
}
.cm-tooltip.is-visible { opacity: 1; transform: none; }
.cm-tooltip::after {
  content: ""; position: absolute; left: var(--cm-tip-arrow, 50%); margin-left: -5px;
  top: 100%; border: 5px solid transparent; border-top-color: #22272e;
}
.cm-tooltip.below::after { top: auto; bottom: 100%; border-top-color: transparent; border-bottom-color: #22272e; }
.cm-sidebar .head-top button,
.cm-sidebar .head-actions button {
  background: var(--cp-surface); border: 1px solid var(--cp-border); color: var(--cp-text);
  padding: var(--cp-chrome-button-y) var(--cp-chrome-action-x); border-radius: 0.5rem; cursor: pointer;
  font-family: inherit; font-size: var(--cp-chrome-body-font);
}
.cm-sidebar .head-top button:hover,
.cm-sidebar .head-actions button:hover { border-color: var(--cp-accent); color: var(--cp-accent); }
.cm-sidebar .head-top button.primary,
.cm-sidebar .head-actions button.primary { background: var(--cp-accent); color: var(--cp-accent-fg); border-color: var(--cp-accent); }
.cm-sidebar .head-top button.primary:hover,
.cm-sidebar .head-actions button.primary:hover { background: var(--cp-accent-hover); color: var(--cp-accent-fg); }
/* The Copy all action is the most-used control: make it visibly larger and bolder than the
   other header buttons so it is easy to find and click. */
.cm-sidebar .head-top #btnCopyAll {
  padding: var(--cp-chrome-primary-y) var(--cp-chrome-primary-x);
  font-size: var(--cp-chrome-primary-font);
  font-weight: 700;
  border-radius: 0.6rem;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.14);
}
/* Informational "Generated on / Last comment" line under the header. */
.cm-side-info { display: flex; flex-flow: row wrap; align-items: baseline; gap: 0.1rem var(--cp-chrome-button-x); font-size: var(--cp-chrome-tiny-font); color: var(--cp-text-soft); margin: 0.15rem 0 var(--cp-chrome-button-y); }
.cm-side-info > span { white-space: nowrap; }
/* Clear Comments wears a persistent warning treatment so it is not clicked by accident. */
/* Confirm dialog (used for destructive actions such as Clear Comments). */
.cm-modal-overlay {
  position: fixed; inset: 0; z-index: 300;
  display: flex; align-items: center; justify-content: center;
  background: rgba(0, 0, 0, 0.45);
}
.cm-modal {
  background: var(--cp-bg-elevated); color: var(--cp-text);
  border: 1px solid var(--cp-border); border-radius: 12px; box-shadow: var(--cp-shadow);
  max-width: 24rem; width: calc(100% - 3rem); padding: 1.1rem 1.2rem;
}
.cm-modal-msg { margin: 0 0 1rem; font-size: 0.9rem; line-height: 1.5; }
.cm-modal-actions { display: flex; justify-content: flex-end; gap: 0.5rem; }
.cm-modal-actions button {
  background: var(--cp-surface); border: 1px solid var(--cp-border); color: var(--cp-text);
  padding: 0.4rem 0.9rem; border-radius: 0.5rem; cursor: pointer;
  font-family: inherit; font-size: 0.82rem;
}
.cm-modal-actions button:hover { border-color: var(--cp-accent); color: var(--cp-accent); }
.cm-modal-actions button.cm-modal-default {
  background: var(--cp-accent); border-color: var(--cp-accent); color: var(--cp-accent-fg);
}
.cm-modal-actions button.cm-modal-default:hover { background: var(--cp-accent-hover); color: var(--cp-accent-fg); }
.cm-modal-actions button.danger {
  background: rgba(220, 38, 38, 0.12); border-color: var(--cp-danger); color: var(--cp-danger);
}
.cm-modal-actions button.danger:hover { background: rgba(220, 38, 38, 0.22); color: var(--cp-danger); }

/* Sidebar header meta row: document-type bubble, version, and Help. */
.cm-sidebar .head-meta { display: flex; flex-wrap: wrap; align-items: center; gap: var(--cp-chrome-gap); margin-bottom: 0.1rem; }
.cm-type-badge {
  font-size: var(--cp-chrome-tiny-font); font-weight: 600; letter-spacing: 0.02em;
  padding: var(--cp-chrome-pill-y) var(--cp-chrome-pill-x); border-radius: 999px; white-space: nowrap;
  border: 1px solid var(--cp-border); color: var(--cp-text-soft);
}
.cm-type-badge[data-doc-type="Portable"] { color: var(--cp-success); border-color: var(--cp-success); background: rgba(22, 163, 74, 0.12); }
.cm-type-badge[data-doc-type="Offline"] { color: var(--cp-accent); border-color: var(--cp-accent); background: var(--cp-accent-soft); }
.cm-type-badge[data-doc-type="Not portable"] { color: var(--cp-warning); border-color: var(--cp-warning); background: rgba(245, 158, 11, 0.12); cursor: help; }
.cm-version { font-size: var(--cp-chrome-tiny-font); color: var(--cp-text-soft); }
.cm-brand-icon { vertical-align: -3px; margin-right: 0.15rem; flex: none; }
.cm-brand-link { color: inherit; text-decoration: none; display: inline-flex; align-items: center; border-radius: 6px; }
.cm-brand-link:hover { text-decoration: underline; }
.cm-brand-link:focus-visible { outline: 2px solid var(--cp-accent); outline-offset: 2px; }
.cm-help-about .cm-brand-link { color: var(--cp-accent); text-decoration: underline; text-underline-offset: 2px; }
.cm-help-about .cm-brand-link:hover { color: var(--cp-accent-hover); }
.cm-toolbar-menu-head { display: flex; align-items: center; justify-content: space-between; gap: var(--cp-chrome-wide-gap); width: 100%; }
.cm-toolbar-menu-brand { display: inline-flex; align-items: center; justify-content: center; color: var(--cp-accent); }
.cm-toolbar-menu-brand .cm-brand-icon { width: 20px; height: 20px; margin: 0; }
.cm-toolbar-menu-head .cm-menu-version { align-self: center; white-space: nowrap; }
.cm-toolbar #btnCopyAllTop[aria-disabled="true"],
.cm-sidebar .head-primary #btnCopyAll[aria-disabled="true"] {
  opacity: 0.58; cursor: not-allowed; box-shadow: none;
}
.cm-toolbar #btnCopyAllTop[aria-disabled="true"]:hover,
.cm-sidebar .head-primary #btnCopyAll[aria-disabled="true"]:hover {
  background: var(--cp-surface); border-color: var(--cp-border); color: var(--cp-text-soft);
}
.cm-sidebar .head-meta .cm-brand-icon { width: 18px; height: 18px; }
.cm-sidebar .head-meta .cm-head-actions { margin-left: auto; display: inline-flex; flex-wrap: wrap; align-items: center; gap: var(--cp-chrome-button-gap); }
.cm-help-btn {
  background: var(--cp-surface); border: 1px solid var(--cp-border); color: var(--cp-text);
  padding: calc(var(--cp-chrome-button-y) * 0.6) var(--cp-chrome-action-x); border-radius: 0.5rem; cursor: pointer; font-family: inherit; font-size: var(--cp-chrome-small-font);
  display: inline-flex; align-items: center; gap: var(--cp-chrome-button-gap);
}
.cm-help-btn:hover { border-color: var(--cp-accent); color: var(--cp-accent); }
/* The Hide control sits next to Help; give it an accent-tinted fill (accent-soft
   background with accent text and border, solid accent on hover) so it stands out
   clearly and reads as distinct from the neutral Help button. */
.cm-hide-btn { background: var(--cp-accent-soft); border-color: var(--cp-accent); color: var(--cp-accent); }
.cm-hide-btn:hover { background: var(--cp-accent); border-color: var(--cp-accent); color: var(--cp-accent-fg); }
.cm-btn-chevron { flex: none; opacity: 0.65; margin-right: -0.1rem; }

/* Help dialog (reuses .cm-modal-overlay). */
.cm-modal.cm-help { max-width: 42rem; width: calc(100% - 3rem); max-height: calc(100vh - 4rem); display: flex; flex-direction: column; padding: 0; }
.cm-help-head { display: flex; align-items: center; justify-content: space-between; padding: 0.9rem var(--cp-chrome-modal-x); border-bottom: 1px solid var(--cp-border); }
.cm-help-head h2 { margin: 0; font-size: 1.05rem; }
.cm-help-close { background: transparent; border: none; color: var(--cp-text-soft); font-size: calc(var(--cp-chrome-font) * 1.65); line-height: 1; cursor: pointer; padding: 0 var(--cp-chrome-button-y); border-radius: 6px; }
.cm-help-close:hover { color: var(--cp-accent); background: var(--cp-accent-soft); }
.cm-help-body { padding: var(--cp-chrome-shell-x) var(--cp-chrome-modal-x) var(--cp-chrome-modal-x); overflow-y: auto; flex: 1 1 auto; min-height: 0; }
.cm-help-body h3 { font-size: 0.92rem; margin: 1rem 0 0.3rem; color: var(--cp-text); }
.cm-help-body p, .cm-help-body li { font-size: var(--cp-chrome-help-font); line-height: 1.5; color: var(--cp-text); }
.cm-help-body ul { margin: var(--cp-chrome-button-gap) 0; padding-left: 1.3rem; }
.cm-help-body kbd { background: var(--cp-surface); border: 1px solid var(--cp-border); border-radius: 4px; padding: 0 4px; font-family: inherit; font-size: 0.8em; }
/* Searchable, collapsible Help topics. */
.cm-help-search { display: flex; align-items: center; gap: var(--cp-chrome-gap); padding: var(--cp-chrome-card-y) var(--cp-chrome-modal-x); border-bottom: 1px solid var(--cp-border); color: var(--cp-text-soft); }
.cm-help-search-input { flex: 1 1 auto; min-width: 0; font: inherit; font-size: var(--cp-chrome-help-font); padding: var(--cp-chrome-control-y) var(--cp-chrome-action-x); border: 1px solid var(--cp-border); border-radius: 0.5rem; background: var(--cp-surface); color: var(--cp-text); }
.cm-help-search-input:focus { outline: none; border-color: var(--cp-accent); box-shadow: 0 0 0 2px var(--cp-accent-soft); }
.cm-help-topic { border-bottom: 1px solid var(--cp-border); }
.cm-help-topic > summary { cursor: pointer; list-style: none; padding: var(--cp-chrome-action-x) 0.2rem; font-weight: 600; font-size: var(--cp-chrome-topic-font); color: var(--cp-text); display: flex; align-items: center; gap: var(--cp-chrome-gap); }
.cm-help-topic > summary::-webkit-details-marker { display: none; }
.cm-help-topic > summary::before { content: "\25B8"; color: var(--cp-text-soft); font-size: 0.8em; transition: transform 0.12s ease; }
.cm-help-topic[open] > summary::before { transform: rotate(90deg); }
.cm-help-topic > summary:hover { color: var(--cp-accent); }
.cm-help-topic-body { padding: 0 0.2rem var(--cp-chrome-card-y) 1.3rem; }
/* Review-loop diagram in the "Getting started" help topic. Themed with the framework's
   --cp-* variables so it follows the light/dark theme like the rest of the UI. */
.cm-loop-figure { margin: 0.7rem 0 0.3rem; }
.cm-loop-figure svg { width: 100%; height: auto; max-width: 560px; display: block; }
.cm-loop-figure figcaption { margin-top: 0.35rem; font-size: 0.82rem; color: var(--cp-text-muted); }
.cm-loop-bg { fill: var(--cp-surface-soft); stroke: var(--cp-border); }
.cm-loop-node { fill: var(--cp-surface); stroke: var(--cp-accent); stroke-width: 1.5; }
.cm-loop-title { fill: var(--cp-accent); }
.cm-loop-sub { fill: var(--cp-text-muted); }
.cm-loop-arrow { stroke: var(--cp-accent); stroke-width: 1.8; fill: none; }
.cm-loop-head { fill: var(--cp-accent); }
.cm-help-noresults { color: var(--cp-text-soft); font-style: italic; padding: 0.9rem 0.2rem; }
/* About is a static, always-shown block (not a collapsible topic). */
.cm-help-about { border-top: 1px solid var(--cp-border); padding: 0.2rem 0.2rem 0.4rem; }
.cm-help-about h3 { margin: 0.6rem 0 0.3rem; font-size: 0.9rem; color: var(--cp-text); }

/* Table-of-contents side menu (wide screens only; runtime-generated, collapsible). */
.cm-side-toc {
  position: fixed; left: 1rem; top: 1rem; z-index: 90;
  width: var(--cm-side-toc-w, 17rem); max-height: calc(100vh - 2rem);
  display: none; flex-direction: column;
  background: var(--cp-panel-strong); backdrop-filter: blur(8px);
  border: 1px solid var(--cp-border); border-radius: 12px; box-shadow: var(--cp-shadow);
  padding: var(--cp-chrome-action-x) var(--cp-chrome-shell-x) var(--cp-chrome-action-x) var(--cp-chrome-side-toc-left); font-size: var(--cp-chrome-body-font);
}
@media (min-width: 1400px) {
  .cm-side-toc { display: flex; }
  /* Reserve gutter space so an expanded TOC never overlaps the (centered) content.
     Collapsing the TOC reclaims the full width. --cm-toc-inset is the space the TOC
     takes on the left; the sidebar-open recipe subtracts it so the centered content
     column keeps its full width between the nav pane and the comments sidebar. */
  body.cm-side-toc-on { padding-left: calc(var(--cm-side-toc-w, 17rem) + 2rem); --cm-toc-inset: calc(var(--cm-side-toc-w, 17rem) + 2rem); }
  body.cm-side-toc-on.cm-side-toc-collapsed { padding-left: 0; --cm-toc-inset: 0px; }
}
.cm-side-toc-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--cp-chrome-button-gap); }
.cm-side-toc-title { font-weight: 700; color: var(--cp-text); }
.cm-side-toc-toggle { background: transparent; border: none; color: var(--cp-text-soft); cursor: pointer; font-size: 1.05rem; line-height: 1; font-weight: 700; padding: 0.1rem 0.35rem; border-radius: 6px; }
.cm-side-toc-toggle:hover { color: var(--cp-accent); background: var(--cp-accent-soft); }
.cm-side-toc-list { list-style: none; margin: 0; padding: 0; overflow-y: auto; flex: 1 1 auto; }
.cm-side-toc-list li { margin: calc(var(--cp-chrome-pill-y) * 0.5) 0; }
.cm-side-toc-list li.is-sub { padding-left: 0.8rem; }
.cm-side-toc-list a { display: block; color: var(--cp-text-soft); text-decoration: none; padding: var(--cp-chrome-toc-link-y) var(--cp-chrome-toc-link-x); border-radius: 6px; border-left: 2px solid transparent; }
.cm-side-toc-list a:hover { color: var(--cp-accent); background: var(--cp-accent-soft); }
.cm-side-toc-list a.is-active { color: var(--cp-accent); border-left-color: var(--cp-accent); background: var(--cp-accent-soft); font-weight: 600; }
.cm-side-toc-top { display: inline-flex; align-items: center; justify-content: center; gap: var(--cp-chrome-button-gap); margin-top: var(--cp-chrome-gap); background: var(--cp-surface); border: 1px solid var(--cp-border); color: var(--cp-text); border-radius: 0.5rem; padding: var(--cp-chrome-toc-button-pad); cursor: pointer; font-family: inherit; font-size: var(--cp-chrome-small-font); }
.cm-side-toc-top:hover { border-color: var(--cp-accent); color: var(--cp-accent); }
.cm-side-toc-scroll { display: flex; gap: var(--cp-chrome-button-gap); }
.cm-side-toc-scroll .cm-side-toc-top { flex: 1 1 0; margin-top: var(--cp-chrome-gap); }
/* Bottom-right scroll-position bubble (runtime, cm-skip, absent from Plain export). */
.cm-scroll-progress {
  position: fixed; right: 1rem; bottom: 1rem; z-index: 95;
  background: var(--cp-panel-strong); backdrop-filter: blur(6px);
  border: 1px solid var(--cp-border); border-radius: 999px;
  padding: var(--cp-chrome-scroll-y) var(--cp-chrome-action-x); font-size: var(--cp-chrome-small-font); font-weight: 600;
  color: var(--cp-text-soft); box-shadow: var(--cp-shadow);
  min-width: 2.6rem; text-align: center; pointer-events: none;
}
body.sidebar-open .cm-scroll-progress { right: calc(var(--cm-sidebar-w, 400px) + 1rem); }
/* On narrow screens the bubble floats over body content (and the full-width sidebar
   sheet), so hide it there - the scroll bar is already the position cue on mobile. */
@media (max-width: 700px) { .cm-scroll-progress { display: none; } }
/* Collapsed: shrink to a single clear chevron box (the >> expand affordance). */
.cm-side-toc.is-collapsed { width: auto; padding: 0.25rem; }
.cm-side-toc.is-collapsed .cm-side-toc-head { margin-bottom: 0; }
.cm-side-toc.is-collapsed .cm-side-toc-title,
.cm-side-toc.is-collapsed .cm-side-toc-list,
.cm-side-toc.is-collapsed .cm-side-toc-scroll,
.cm-side-toc.is-collapsed .cm-side-toc-top { display: none; }

/* ===== Redesigned panel header (composite layout, issue #658) ===== */
.cm-sidebar .head-top { flex-wrap: nowrap; justify-content: space-between; align-items: center; gap: var(--cp-chrome-gap); }
.cm-sidebar .head-top h3 { flex: 0 1 auto; gap: 0.3rem; }
.cm-sidebar .head-chrome { display: inline-flex; align-items: center; gap: 0.45rem; flex: none; }

.cm-sidebar .head-ribbon { display: flex; align-items: stretch; gap: 0.2rem; position: relative; }
.cm-sidebar .head-ribbon > * { flex: 1 1 0; min-width: 0; }
.cm-sidebar .cm-ribbon-btn {
  display: inline-flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
  padding: 0.4rem 0.15rem; background: transparent; border: 1px solid transparent; border-radius: 0.5rem;
  color: var(--cp-text-soft); cursor: pointer; font-family: inherit; line-height: 1;
}
.cm-sidebar .cm-ribbon-btn:hover { background: var(--cp-accent-soft); color: var(--cp-accent); }
.cm-sidebar .cm-ribbon-cap { font-size: var(--cp-chrome-tiny-font); }
.cm-sidebar .cm-sidebar-export, .cm-sidebar .cm-sidebar-more { display: flex; position: relative; }

/* The Sort ribbon button cycles document -> newest-first -> oldest-first; a non-default sort
   keeps the accent highlight so the active state reads at a glance. */
.cm-sidebar .head-ribbon .cm-sort-cycle[data-sort="time-desc"],
.cm-sidebar .head-ribbon .cm-sort-cycle[data-sort="time-asc"] { color: var(--cp-accent); background: var(--cp-accent-soft); }
/* The Search ribbon button shows the accent while its filter field is open, like the active Sort state. */
.cm-sidebar .head-ribbon .cm-search-toggle[aria-expanded="true"] { color: var(--cp-accent); background: var(--cp-accent-soft); }

.cm-sidebar .head-primary { display: flex; gap: var(--cp-chrome-gap); }
.cm-sidebar .head-primary > button, .cm-sidebar .head-primary > .cm-sidebar-export { flex: 1 1 50%; min-width: 0; }
.cm-sidebar .head-primary > button { display: inline-flex; align-items: center; justify-content: center; gap: var(--cp-chrome-button-gap); padding: var(--cp-chrome-control-y) var(--cp-chrome-control-x); border-radius: 0.6rem; font-family: inherit; font-size: var(--cp-chrome-body-font); cursor: pointer; }
.cm-sidebar .head-primary #btnCopyAll { background: var(--cp-accent); color: var(--cp-accent-fg); border: 1px solid var(--cp-accent); font-weight: 700; font-size: var(--cp-chrome-primary-font); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.14); }
.cm-sidebar .head-primary #btnCopyAll:hover { background: var(--cp-accent-hover); color: var(--cp-accent-fg); }
/* Export is the secondary action beside Copy all: a themed surface button that hovers to the accent. */
.cm-sidebar .head-primary .cm-sidebar-export-toggle { width: 100%; display: inline-flex; align-items: center; justify-content: center; gap: var(--cp-chrome-button-gap); padding: var(--cp-chrome-control-y) var(--cp-chrome-control-x); border-radius: 0.6rem; font-family: inherit; font-size: var(--cp-chrome-body-font); cursor: pointer; background: var(--cp-surface); color: var(--cp-text); border: 1px solid var(--cp-border); }
.cm-sidebar .head-primary .cm-sidebar-export-toggle:hover { border-color: var(--cp-accent); color: var(--cp-accent); }
.cm-sidebar .head-primary .cm-sidebar-export-toggle[aria-expanded="true"] { border-color: var(--cp-accent); color: var(--cp-accent); background: var(--cp-accent-soft); }

/* Stacked, labelled metadata rows (Generated, then Last activity), followed by the identity row.
   The header is a flex column with a 0.4rem gap, so matching cm-side-info's internal gap to it and
   zeroing the margins gives an even rhythm across all three metadata lines. */
.cm-sidebar .cm-side-info { flex-flow: column nowrap; align-items: flex-start; gap: var(--cp-chrome-gap); margin: 0; border-top: 1px solid var(--cp-border); padding-top: var(--cp-chrome-gap); }
.cm-sidebar .cm-identity { margin-top: 0; font-size: var(--cp-chrome-tiny-font); }
/* The identity display line matches the tiny metadata rows above it, but its edit-mode name input
   keeps the larger small-font so the field stays comfortable to read and type in. */
.cm-sidebar .cm-identity .cm-identity-input { font-size: var(--cp-chrome-small-font); }

/* On phones every ribbon action (Sort/Search included) and both primary-row buttons (Copy all and
   the Export toggle, which is no longer a ribbon button) get a comfortable >=44px touch target. */
@media (max-width: 640px) {
  .cm-sidebar .cm-ribbon-btn,
  .cm-sidebar .head-primary > button,
  .cm-sidebar .head-primary .cm-sidebar-export-toggle { min-height: 44px; }
}
/* Attribution footer (runtime-generated, cm-skip) - appears whenever the layer is
   active, and is correctly absent from a Plain HTML export where the layer is removed.
   Its box tracks the .app content column (max-width 1480px minus the .app 1.5rem side
   padding) so the footer never sticks out past the content sections above it. */
.cm-footer {
  margin: var(--cp-chrome-shell-x) auto 1.25rem; width: calc(100% - 3rem); max-width: calc(1480px - 3rem); box-sizing: border-box; padding: var(--cp-chrome-action-x) 1rem;
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: var(--cp-chrome-gap);
  font-size: var(--cp-chrome-small-font); color: var(--cp-text-soft);
  border: 1px solid var(--cp-border); border-radius: 0.6rem; background: var(--cp-surface);
}
/* With the runtime footer present, the layout recipe's large bottom padding would leave
   a big empty gap above the footer; tighten it (plain-export docs keep the full padding). */
body.cm-has-footer .app { padding-bottom: 1.25rem; }
.cm-footer a { color: var(--cp-accent); text-decoration: none; }
.cm-footer a:hover { text-decoration: underline; }
.cm-footer-help { background: transparent; border: none; color: var(--cp-accent); cursor: pointer; font: inherit; padding: 0; text-decoration: none; }
.cm-footer-help:hover { text-decoration: underline; }
.cm-footer-ver { font-weight: 600; color: var(--cp-text); }
.cm-footer-sep { opacity: 0.5; }
/* Footer copy-session control (CMH-FOOT-04): a small icon button that copies the creating AI
   agent's session id. Accent-coloured to read as an action, with a subtle hover surface. */
.cm-footer-copy-session {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0.15rem; margin: 0; border: none; border-radius: 0.35rem;
  background: transparent; color: var(--cp-accent); cursor: pointer; line-height: 0;
}
.cm-footer-copy-session:hover { background: var(--cp-surface-soft, rgba(127,127,127,0.14)); }
.cm-footer-copy-session .cm-ui-ico { display: block; }
/* When the comments panel is open, track the .app content column exactly: the layout recipe
   (10-layout.css) insets .app by 2rem left / sidebar+2rem right from 1100px, and by a centered
   gutter from 1700px. Mirror those insets so the footer stays flush with the content sections
   in the sidebar-open layout too. Below 1100px the base centered rule already matches .app. */
@media (min-width: 1100px) {
  body.sidebar-open .cm-footer {
    max-width: none;
    width: auto;
    margin-left: 2rem;
    margin-right: calc(var(--cm-sidebar-w, 400px) + 2rem);
  }
}
@media (min-width: 1700px) {
  body.sidebar-open .cm-footer {
    margin-left: max(2rem, calc((100vw - var(--cm-toc-inset, 0px) - var(--cm-sidebar-w, 400px) - 1600px) / 2));
    margin-right: calc(var(--cm-sidebar-w, 400px) + max(2rem, calc((100vw - var(--cm-toc-inset, 0px) - var(--cm-sidebar-w, 400px) - 1600px) / 2)));
  }
}
/* TOC section numbers. */
.cm-side-toc-list .cm-toc-num { color: var(--cp-text-muted); font-variant-numeric: tabular-nums; }
.cm-side-toc-list a.is-active .cm-toc-num { color: var(--cp-accent); }
/* Side-TOC filter box (search-as-filter) and the hide rules it toggles. */
.cm-side-toc-search {
  width: 100%; box-sizing: border-box; margin: var(--cp-chrome-search-top) 0 var(--cp-chrome-shell-x); padding: var(--cp-chrome-search-y) var(--cp-chrome-shell-x);
  font: inherit; font-size: var(--cp-chrome-body-font); color: var(--cp-text); background: var(--cp-surface);
  border: 1px solid var(--cp-border); border-radius: 0.4rem;
}
.cm-side-toc-search:focus-visible { outline: 2px solid var(--cp-accent); outline-offset: 1px; }
.cm-side-toc.is-collapsed .cm-side-toc-search { display: none; }
.cm-side-toc-list li.cm-toc-li-hidden { display: none; }
#commentRoot section.cm-toc-filtered { display: none; }
/* Long content <pre> (logs, code) wrap instead of overflowing horizontally. Diff and
   mermaid blocks keep their own whitespace handling. */
#commentRoot pre:not(.cmh-diff):not(.cmh-diff-raw):not(.mermaid) { white-space: pre-wrap; overflow-wrap: anywhere; }
/* Top-level prose fills the content column (no readable-measure cap): paragraphs, like
   tables, figures, code, and callouts, use the full width of the 1480px content shell. */
/* Section headings are deep-links: a plain click or Enter/Space updates the URL to their
   anchor, and they are keyboard-focusable with a visible focus ring. */
#commentRoot .cm-anchored { cursor: pointer; }
#commentRoot .cm-anchored:hover { text-decoration-line: underline; text-decoration-style: dotted; text-underline-offset: 3px; }
#commentRoot .cm-anchored:focus-visible { outline: 3px solid var(--cp-accent); outline-offset: 3px; border-radius: 3px; }
/* Collapsible sections: caret on the heading toggles a class that hides the body. */
.cmh-sec-caret {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.9em; height: 1.9em; margin-right: var(--cp-chrome-caret-gap); vertical-align: middle;
  background: transparent; border: 0; border-radius: 6px; cursor: pointer;
  color: var(--cp-text-soft); padding: 0; line-height: 1;
}
.cmh-sec-caret::before { content: "\25BE"; font-size: 1.45em; }
.cmh-sec-caret[aria-expanded="false"]::before { content: "\25B8"; }
.cmh-sec-caret:hover { color: var(--cp-accent); background: var(--cp-accent-soft); }
.cmh-sec-caret:focus-visible { outline: 2px solid var(--cp-accent); outline-offset: 2px; color: var(--cp-accent); }
#commentRoot section.cmh-section-collapsed > .cmh-section-heading { cursor: pointer; }
#commentRoot section.cmh-section-collapsed > * { display: none; }
#commentRoot section.cmh-section-collapsed > .cmh-section-heading { display: revert; }

.cm-sidebar .list { flex: 1; overflow-y: auto; padding: var(--cp-chrome-card-y); display: flex; flex-direction: column; gap: var(--cp-chrome-gap); }
.cm-empty { text-align: center; padding: 2rem 1rem; color: var(--cp-text-muted); font-size: var(--cp-chrome-font); line-height: 1.55; }
.cm-empty kbd { background: var(--cp-surface); border: 1px solid var(--cp-border); border-radius: 4px; padding: 1px 5px; font-family: inherit; font-size: var(--cp-chrome-body-font); color: var(--cp-text); }

.cm-sidebar-export {
  position: relative;
}
.cm-sidebar .cm-sidebar-export > button,
.cm-sidebar .cm-sidebar-more > button {
  width: 100%;
}
/* The Export dropdown anchors to its own button (position:relative on .cm-sidebar-export) and the
   More dropdown to its own toggle; both are sized to their content and clamped to the VIEWPORT (not
   the narrow toggle wrapper, which would crush them) so they stay readable and never render
   off-screen. The Export menu (in the primary row) and the More menu both open from the right edge. */
.cm-sidebar-export-menu {
  position: absolute;
  z-index: 230;
  top: calc(100% + 0.35rem);
  left: 0;
  width: max-content;
  min-width: 11rem;
  max-width: min(18rem, calc(100vw - 1rem));
  max-height: min(60vh, 22rem, calc(100vh - 12rem));
  overflow-y: auto;
  padding: 0.3rem;
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  background: var(--cp-bg-elevated);
  border: 1px solid var(--cp-border);
  border-radius: 0.65rem;
  box-shadow: var(--cp-shadow);
}
.cm-sidebar-export-menu[hidden] { display: none; }
.cm-sidebar-more-menu { left: auto; right: 0; }
/* In the primary row the Export button is the right-hand action, so its menu opens from the right
   edge (extending left into the sidebar) rather than off the right of the viewport. */
.cm-sidebar .head-primary .cm-sidebar-export-menu { left: auto; right: 0; }
/* Clean menu-item buttons (matching the collapsed toolbar menu): transparent until hovered, a
   left-aligned icon + label, and an accent-soft highlight - not heavy full-width bordered buttons. */
.cm-sidebar .cm-sidebar-export-menu button {
  width: 100%;
  justify-content: flex-start;
  text-align: left;
  flex: none;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  display: flex;
  align-items: center;
  gap: var(--cp-chrome-gap);
  padding: var(--cp-chrome-menu-item-y) var(--cp-chrome-action-x);
  background: transparent;
  border: 1px solid transparent;
  border-radius: 8px;
  color: var(--cp-text);
  font-size: var(--cp-chrome-font);
  cursor: pointer;
}
.cm-sidebar .cm-sidebar-export-menu button:hover { background: var(--cp-accent-soft); color: var(--cp-accent); }
/* The provenance toggle is a setting, not an action: align it to the same left edge as the menu
   items, mute it, and separate it from the export buttons below with a hairline so the menu reads
   as "one setting, then the export actions". */
.cm-sidebar-export-menu > label {
  display: flex;
  align-items: flex-start;
  gap: var(--cp-chrome-gap);
  padding: var(--cp-chrome-menu-item-y) var(--cp-chrome-action-x);
  margin-bottom: 0.15rem;
  border-bottom: 1px solid var(--cp-border);
  color: var(--cp-text-soft);
  font-size: var(--cp-chrome-tiny-font);
  line-height: 1.35;
  cursor: pointer;
}
.cm-sidebar-export-menu > label input { flex: none; margin: 0.1rem 0 0; }
/* The More menu reuses the export-menu shell; mark Clear as destructive. */
.cm-sidebar-more-menu .cm-menu-group { padding: 0.3rem 0.45rem 0.15rem; font-size: var(--cp-chrome-tiny-font); letter-spacing: 0.08em; text-transform: uppercase; color: var(--cp-text-soft); font-weight: 700; }
.cm-sidebar-more-menu button.danger { color: var(--cp-danger); }
.cm-sidebar-more-menu button.danger:hover { background: var(--cp-danger-soft); color: var(--cp-danger); }

/* Comment search / filter row: a single text field with a leading magnifier, a clear (X)
   button, and a shown/total count. Filtered-out cards are hidden with an explicit class
   because .cm-card sets display:flex, which would otherwise win over the UA [hidden] rule. */
.head-search { display: flex; align-items: center; gap: var(--cp-chrome-gap); padding: 0.1rem var(--cp-chrome-button-y) var(--cp-chrome-shell-x); }
.head-search[hidden] { display: none; }
.cm-search-ico { flex: none; color: var(--cp-text-soft); }
.cm-search-input {
  flex: 1 1 auto; min-width: 0; font: inherit; font-size: var(--cp-chrome-body-font); padding: var(--cp-chrome-button-y) var(--cp-chrome-search-x);
  border: 1px solid var(--cp-border); border-radius: 0.5rem; background: var(--cp-surface); color: var(--cp-text);
}
.cm-search-input:focus { outline: none; border-color: var(--cp-accent); box-shadow: 0 0 0 2px var(--cp-accent-soft); }
.cm-search-clear {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: var(--cp-chrome-search-clear); height: var(--cp-chrome-search-clear); padding: 0; border: 1px solid var(--cp-border);
  border-radius: 0.5rem; background: var(--cp-surface); color: var(--cp-text-soft); cursor: pointer;
}
.cm-search-clear:hover { border-color: var(--cp-accent); color: var(--cp-accent); }
.cm-search-clear[hidden] { display: none; }
.cm-search-count { flex: none; font-size: var(--cp-chrome-tiny-font); color: var(--cp-text-soft); min-width: 2.2rem; text-align: right; font-variant-numeric: tabular-nums; }
.cm-search-count[hidden] { display: none; }
.cm-card.cm-hidden { display: none !important; }
.cm-search-empty[hidden] { display: none; }

.cm-card {
  background: var(--cp-surface); border: 1px solid var(--cp-border); border-radius: 10px;
  padding: var(--cp-chrome-card-y) var(--cp-chrome-card-x); display: flex; flex-direction: column; gap: var(--cp-chrome-card-gap);
  font-size: var(--cp-chrome-font); cursor: pointer;
}
.cm-card:hover { border-color: var(--cp-accent); }
.cm-card.active { border-color: var(--cp-warning); box-shadow: 0 0 0 2px rgba(245, 158, 11, 0.25); }
.cm-card .section {
  font-size: var(--cp-chrome-tiny-font); color: var(--cp-text-soft);
  text-transform: uppercase; letter-spacing: 0.04em;
}
.cm-card .section strong {
  color: var(--cp-accent); font-weight: 600;
  text-transform: none; letter-spacing: 0; font-size: var(--cp-chrome-body-font);
}
.cm-card .quote {
  border-left: 3px solid var(--cp-warning); padding: calc(var(--cp-chrome-button-y) * 0.75) var(--cp-chrome-action-x);
  color: var(--cp-text-muted); font-size: var(--cp-chrome-body-font); line-height: 1.5;
  background: rgba(245, 158, 11, 0.06); border-radius: 0 4px 4px 0;
  overflow: hidden;
  display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical;
}
.cm-card .quote .ctx { color: var(--cp-text-soft); font-style: italic; }
.cm-card .quote .quoted {
  color: var(--cp-text); font-style: normal; font-weight: 600;
  background: rgba(245, 158, 11, 0.18); padding: 0 3px; border-radius: 3px;
}
.cm-card .pin {
  font-size: var(--cp-chrome-tiny-font); color: var(--cp-text-soft);
  font-family: Consolas, "Courier New", Courier, monospace;
}
.cm-card .note { color: var(--cp-text); white-space: pre-wrap; word-wrap: break-word; }
.cm-card .meta { display: flex; align-items: center; justify-content: space-between; font-size: var(--cp-chrome-small-font); color: var(--cp-text-soft); }
.cm-card .meta .acts { display: flex; gap: var(--cp-chrome-button-gap); }
.cm-card .meta button { background: transparent; border: none; color: var(--cp-text-soft); cursor: pointer; padding: 2px 6px; border-radius: 4px; font-family: inherit; font-size: var(--cp-chrome-small-font); }
.cm-card .meta button:hover { background: var(--cp-accent-soft); color: var(--cp-accent); }
.cm-card .meta button.del:hover { background: rgba(220, 38, 38, 0.12); color: var(--cp-danger); }

/* On phones the card action buttons (jump/edit/delete) get a comfortable >=44px
   touch height without changing their compact look on desktop. */
@media (max-width: 640px) {
  .cm-card .meta .acts button { min-height: 44px; padding: 0.4rem 0.7rem; }
}

/* Stack the menu's options vertically (one pill below the next) with a small gap, so a deck's
   two comment-scope options ("Comment on deck" above "Comment on slide") read as a clear list
   rather than a side-by-side pair. */
.cm-menu { position: fixed; z-index: 200; display: flex; flex-direction: column; align-items: stretch; gap: 6px; }
.cm-menu button { justify-content: center; }

/* Add-comment affordances: the text-selection menu button and the floating
   image / link / diff / mermaid buttons all share ONE accent-pill look + hover, so the
   "Add Comment" control is visually identical wherever it appears. */
.cm-menu button, .cm-mermaid-add, .cm-diff-add, .cm-image-add, .cm-link-add, .cm-widget-add {
  background: var(--cp-accent); color: var(--cp-accent-fg);
  border: none; border-radius: 999px; padding: var(--cp-chrome-add-y) var(--cp-chrome-add-x);
  font-family: inherit; font-size: var(--cp-chrome-body-font); font-weight: 600; line-height: 1.2;
  cursor: pointer; box-shadow: var(--cp-shadow);
  display: inline-flex; align-items: center; gap: var(--cp-chrome-gap); white-space: nowrap;
}
.cm-menu button:hover, .cm-mermaid-add:hover, .cm-diff-add:hover, .cm-image-add:hover, .cm-link-add:hover, .cm-widget-add:hover {
  background: var(--cp-accent-hover); color: var(--cp-accent-fg);
}
.cm-menu button:active, .cm-mermaid-add:active, .cm-diff-add:active, .cm-image-add:active, .cm-link-add:active, .cm-widget-add:active {
  transform: translateY(1px);
}

.cm-composer {
  position: fixed; z-index: 210; width: 360px; max-width: 92vw;
  background: var(--cp-surface); border: 1px solid var(--cp-border); border-radius: 12px;
  box-shadow: var(--cp-shadow); padding: var(--cp-chrome-card-y);
  display: flex; flex-direction: column; gap: var(--cp-chrome-card-gap);
}
.cm-composer.dragging { user-select: none; box-shadow: 0 24px 64px rgba(0, 0, 0, 0.28); }
.cm-composer-handle {
  display: flex; align-items: center; justify-content: space-between;
  margin: -0.35rem -0.2rem 0.1rem -0.2rem;
  padding: calc(var(--cp-chrome-button-y) * 0.45) var(--cp-chrome-gap); border-radius: 6px;
  cursor: grab; color: var(--cp-text-muted); font-size: var(--cp-chrome-small-font);
  user-select: none;
}
.cm-composer-handle:hover { background: var(--cp-accent-soft); color: var(--cp-accent); }
.cm-composer.dragging .cm-composer-handle { cursor: grabbing; background: var(--cp-accent-soft); color: var(--cp-accent); }
.cm-composer-handle .grip { letter-spacing: 1px; font-weight: 700; font-size: 0.9rem; line-height: 1; }
.cm-composer-handle .label { opacity: 0.75; }
@keyframes cm-composer-flash {
  0%   { box-shadow: var(--cp-shadow); }
  30%  { box-shadow: 0 0 0 3px var(--cp-accent), 0 24px 64px rgba(0,0,0,0.28); }
  100% { box-shadow: var(--cp-shadow); }
}
.cm-composer.flash { animation: cm-composer-flash 0.6s ease-out 1; }
.cm-composer .quote {
  border-left: 3px solid var(--cp-warning); padding: var(--cp-chrome-quote-y) var(--cp-chrome-quote-x);
  color: var(--cp-text-muted); font-style: italic; font-size: var(--cp-chrome-body-font); line-height: 1.5;
  background: rgba(245, 158, 11, 0.07); border-radius: 0 4px 4px 0;
  max-height: 8.5em; overflow-y: auto;
}
/* When the quoted text came from a <pre>/<code> block, preserve its formatting:
   render in monospace, keep whitespace, don't collapse newlines. Applied as an
   extra class (cm-quote-code) by createComposerElement and renderSidebar. */
.cm-card .quote.cm-quote-code,
.cm-composer .quote.cm-quote-code {
  font-family: Consolas, "Courier New", Courier, monospace;
  font-size: var(--cp-chrome-code-font);
  font-style: normal;
  white-space: pre-wrap;
  word-break: break-word;
  tab-size: 2;
  -moz-tab-size: 2;
}
.cm-card .quote.cm-quote-code {
  display: block;
  -webkit-line-clamp: unset;
}
.cm-composer textarea {
  resize: vertical; min-height: 70px; padding: var(--cp-chrome-shell-x) var(--cp-chrome-action-x);
  background: var(--cp-bg-elevated); border: 1px solid var(--cp-border); border-radius: 6px;
  color: var(--cp-text); font-family: inherit; font-size: var(--cp-chrome-font);
}
.cm-composer textarea:focus { outline: none; border-color: var(--cp-accent); box-shadow: 0 0 0 2px var(--cp-accent-soft); }
.cm-composer textarea.cm-invalid { border-color: var(--cp-danger); box-shadow: 0 0 0 2px rgba(220, 38, 38, 0.14); }
.cm-composer .row { display: flex; justify-content: flex-end; gap: var(--cp-chrome-gap); }
.cm-composer button {
  background: var(--cp-surface); border: 1px solid var(--cp-border); color: var(--cp-text);
  padding: var(--cp-chrome-control-y) var(--cp-chrome-control-x); border-radius: 6px; cursor: pointer;
  font-family: inherit; font-size: var(--cp-chrome-font);
}
.cm-composer button.primary { background: var(--cp-accent); color: var(--cp-accent-fg); border-color: var(--cp-accent); }
.cm-composer button.primary:hover { background: var(--cp-accent-hover); }
.cm-composer button:not(.primary):hover { border-color: var(--cp-accent); color: var(--cp-accent); }

.cm-comment-popover {
  position: fixed; z-index: 215; width: 320px; max-width: 92vw;
  background: var(--cp-surface); border: 1px solid var(--cp-border); border-radius: 12px;
  box-shadow: var(--cp-shadow); padding: var(--cp-chrome-card-y);
  display: flex; flex-direction: column; gap: var(--cp-chrome-card-gap);
}
.cm-comment-popover-note {
  white-space: pre-wrap; word-break: break-word; color: var(--cp-text);
  font-size: var(--cp-chrome-body-font); line-height: 1.5;
  max-height: 40vh; overflow-y: auto;
}
.cm-comment-popover-meta { color: var(--cp-text-muted); font-size: var(--cp-chrome-small-font); }
.cm-comment-popover-edit { display: flex; flex-direction: column; }
.cm-comment-popover-input {
  width: 100%; box-sizing: border-box; resize: vertical; min-height: 5rem;
  padding: 0.35rem 0.5rem; font: inherit; font-size: var(--cp-chrome-body-font);
  line-height: 1.5; border: 1px solid var(--cp-border); border-radius: 6px;
  background: var(--cp-surface); color: var(--cp-text);
}
.cm-comment-popover-input.cm-invalid { border-color: var(--cp-danger, #dc2626); }
.cm-comment-popover-acts { display: flex; justify-content: flex-end; gap: var(--cp-chrome-gap); }
.cm-comment-popover button {
  background: var(--cp-surface); border: 1px solid var(--cp-border); color: var(--cp-text);
  padding: var(--cp-chrome-control-y) var(--cp-chrome-control-x); border-radius: 6px; cursor: pointer;
  font-family: inherit; font-size: var(--cp-chrome-font);
}
.cm-comment-popover button.primary { background: var(--cp-accent); color: var(--cp-accent-fg); border-color: var(--cp-accent); }
.cm-comment-popover button.primary:hover { background: var(--cp-accent-hover); }
.cm-comment-popover button:not(.primary):hover { border-color: var(--cp-accent); color: var(--cp-accent); }

.cm-toast {
  position: fixed; bottom: 1.5rem; left: 50%;
  transform: translateX(-50%) translateY(20px);
  background: var(--cp-accent); color: var(--cp-accent-fg);
  padding: var(--cp-chrome-card-y) var(--cp-chrome-toast-x); border-radius: 999px;
  box-shadow: var(--cp-shadow); font-size: var(--cp-chrome-font); z-index: 300;
  opacity: 0; pointer-events: none;
  transition: opacity 0.2s, transform 0.2s;
  max-width: 90vw; text-align: center;
}
.cm-toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }
/* Export confirmations use a centered variant so the message lands in the middle of the screen. */
.cm-toast.cm-toast-center { top: 50%; bottom: auto; transform: translate(-50%, calc(-50% + 20px)); }
.cm-toast.cm-toast-center.show { transform: translate(-50%, -50%); }
/* ---------- Section review tracking (badges, TOC dots, segmented filter) ----------
   Runtime-only chrome (cm-skip), so it never enters a Plain/standalone snapshot. The badge sits
   just right of a heading's text and shows the section's review state; the side-TOC gains a
   per-entry state dot and an All/Reviewed/Unreviewed/Commented/Changed segmented filter. */
:root {
  --cmh-review-ok: #2e7d32;
  --cmh-review-ok-soft: #e7f4ec;
  --cmh-review-ok-border: #a6d3af;
  --cmh-review-changed: var(--cp-warning, #b45309);
  --cmh-review-changed-soft: var(--cp-warning-soft, #fff7ed);
  --cmh-review-changed-border: #f0c48a;
  --cmh-review-commented: #1d4ed8;
  --cmh-review-commented-soft: #e6efff;
  --cmh-review-commented-border: #b3ccf5;
}

/* The badge/button. Reset the heading font so it reads as a small pill, not heading-sized. */
.cmh-review-badge {
  display: inline-flex; align-items: center; gap: 0.3em;
  margin-left: 0.6rem; vertical-align: middle;
  font-size: 0.68rem; font-weight: 600; line-height: 1.4; letter-spacing: 0.01em;
  padding: 0.05rem 0.5rem; border-radius: 999px;
  border: 1px solid var(--cp-border, #d5d5d5); background: var(--cp-surface, #fff); color: var(--cp-text-soft, #666);
  cursor: pointer; white-space: nowrap; transition: opacity 0.12s ease, background 0.12s ease;
}
.cmh-review-badge::before { content: ""; width: 0.5em; height: 0.5em; border-radius: 50%; background: currentColor; }
.cmh-review-badge::after { content: attr(data-cmh-label); }
.cmh-review-badge:focus-visible { outline: 2px solid var(--cp-accent); outline-offset: 2px; }

/* Unreviewed: a muted "Mark reviewed" affordance that only appears on heading hover/focus, so it
   does not clutter every heading until the reader reaches for it. It stays reachable by keyboard. */
.cmh-review-unreviewed { opacity: 0; }
.cmh-review-unreviewed::before { display: none; }
h1:hover > .cmh-review-unreviewed, h2:hover > .cmh-review-unreviewed, h3:hover > .cmh-review-unreviewed,
h4:hover > .cmh-review-unreviewed, h5:hover > .cmh-review-unreviewed, h6:hover > .cmh-review-unreviewed,
h1:focus-within > .cmh-review-unreviewed, h2:focus-within > .cmh-review-unreviewed,
h3:focus-within > .cmh-review-unreviewed, h4:focus-within > .cmh-review-unreviewed,
h5:focus-within > .cmh-review-unreviewed, h6:focus-within > .cmh-review-unreviewed,
.cmh-review-unreviewed:focus { opacity: 1; }

.cmh-review-reviewed { color: var(--cmh-review-ok); background: var(--cmh-review-ok-soft); border-color: var(--cmh-review-ok-border); }
.cmh-review-changed { color: var(--cmh-review-changed); background: var(--cmh-review-changed-soft); border-color: var(--cmh-review-changed-border); }
.cmh-review-commented { color: var(--cmh-review-commented); background: var(--cmh-review-commented-soft); border-color: var(--cmh-review-commented-border); }

/* Side-TOC per-entry single-character status mark, painted by updateTocReviewMarks() once the review
   UI is active. The letter is a ::after pseudo-element so it never enters the TOC link text. */
.cmh-toc-mark {
  display: inline-flex; align-items: center; justify-content: center;
  box-sizing: border-box; width: 1.15em; height: 1.15em; margin-right: 0.45em; vertical-align: middle;
  font-size: 0.62rem; font-weight: 700; line-height: 1; letter-spacing: 0;
  border-radius: 0.28em; border: 1px solid var(--cp-border, #ccc);
  background: transparent; color: var(--cp-text-soft, #666);
}
.cmh-toc-mark::after { content: attr(data-cmh-mark); }
.cmh-toc-mark-reviewed { color: var(--cmh-review-ok); border-color: var(--cmh-review-ok-border); background: var(--cmh-review-ok-soft); }
.cmh-toc-mark-changed { color: var(--cmh-review-changed); border-color: var(--cmh-review-changed-border); background: var(--cmh-review-changed-soft); }
.cmh-toc-mark-commented { color: var(--cmh-review-commented); border-color: var(--cmh-review-commented-border); background: var(--cmh-review-commented-soft); }
.cmh-toc-mark-unreviewed { background: transparent; }

/* The segmented review filter in the side-TOC head. Hidden until the review UI is active (its
   `hidden` attribute must win over the base display:flex, hence the attribute-qualified rule). */
.cm-side-toc-review { display: flex; flex-wrap: wrap; gap: 0.25rem; margin: 0 0 0.4rem; }
.cm-side-toc-review[hidden] { display: none; }
.cm-side-toc-review-btn {
  flex: 1 1 auto; min-width: fit-content;
  display: inline-flex; align-items: baseline; justify-content: center; gap: 0.25rem;
  white-space: nowrap;
  font-size: 0.68rem; font-weight: 600; padding: 0.15rem 0.4rem;
  border: 1px solid var(--cp-border, #d5d5d5); border-radius: 0.35rem;
  background: var(--cp-surface, #fff); color: var(--cp-text-soft, #666); cursor: pointer;
}
/* The live per-state count sits inline beside the label and never wraps, so a two-digit count
   still keeps each button on one line; the group flex-wraps into rows within the sidebar so it
   never overflows horizontally. The count keeps the button's own text color (no opacity dimming)
   so its small digits stay above the WCAG AA contrast floor; tabular-nums keeps equal-length
   counts from jittering as they change (the flex layout absorbs the one- to two-digit step). */
.cm-side-toc-review-btn-count { font-variant-numeric: tabular-nums; }
.cm-side-toc-review-btn:hover { border-color: var(--cp-accent); color: var(--cp-accent); }
.cm-side-toc-review-btn[aria-pressed="true"] { background: var(--cp-accent); border-color: var(--cp-accent); color: var(--cp-accent-fg, #fff); }
.cm-side-toc-review-btn:focus-visible { outline: 2px solid var(--cp-accent); outline-offset: 1px; }
.cm-side-toc.is-collapsed .cm-side-toc-review { display: none; }
/* --- Mermaid commenting layer (works with pre.mermaid / div.mermaid) --- */
.cm-mermaid-host { position: relative; }
.cm-mermaid-host svg g.node,
.cm-mermaid-host svg g.cluster,
.cm-mermaid-host svg g.edgeLabel {
  cursor: pointer;
  transition: filter 0.12s ease;
}
.cm-mermaid-host svg g.node:hover,
.cm-mermaid-host svg g.cluster:hover {
  filter: drop-shadow(0 0 4px var(--cp-accent));
}
.cm-mermaid-hl > rect,
.cm-mermaid-hl > polygon,
.cm-mermaid-hl > circle,
.cm-mermaid-hl > ellipse,
.cm-mermaid-hl > path {
  stroke: var(--cp-accent) !important;
  stroke-width: 3px !important;
}
.cm-mermaid-hl { filter: drop-shadow(0 0 4px var(--cp-accent)); }
/* Whole-diagram highlight: outline the host box (the node stroke rules don't apply). */
.cm-mermaid-host.cm-mermaid-hl { outline: 2px solid var(--cp-accent); outline-offset: 4px; border-radius: 6px; }
/* CMH-MMD-11: every rendered diagram is keyboard-focusable for commenting (attachMermaidKeyboardCommenting
   adds tabindex + data-cmh-comment-a11y) so a keyboard user can reveal the whole-diagram button and press
   Enter to comment. Give it a visible, themed focus ring (WCAG 2.4.7); the browser default outline is
   low-contrast on the soft surface. This covers a standalone host AND a gallery card (the figure/pre/div
   focus target), whether or not the card also carries the scroll-a11y ring. */
#commentRoot .cm-mermaid-host[data-cmh-comment-a11y="1"]:focus-visible,
#commentRoot .cmh-diagram-gallery > [data-cmh-comment-a11y="1"]:focus-visible {
  outline: 2px solid var(--cp-accent); outline-offset: 2px; border-radius: 6px;
}
/* Gantt/sequence labels are SVG <text> with no child shape; tint the text itself. */
text.cm-mermaid-hl, .cm-mermaid-hl > text { fill: var(--cp-accent) !important; font-weight: 700; }
/* CMH-MMD-10: a NARROW report diagram (natural width well under the content column) grows toward the
   column instead of being marooned by mermaid's intrinsic-width inline max-width. The cap
   (--cmh-diagram-cap, set by updateMermaidWidthClass) is a modest multiple of the intrinsic width so
   a tiny diagram never balloons; the SVG is centered. Covers both pre.mermaid and div.mermaid hosts
   (both carry .cm-mermaid-host). Report-only - a deck has its own contain-fit rules. */
#commentRoot .cm-mermaid-host.cmh-diagram-narrow svg {
  width: 100%;
  max-width: min(100%, var(--cmh-diagram-cap, 100%)) !important;
  height: auto;
  display: block;
  margin-inline: auto;
}
@keyframes cm-mermaid-pulse {
  0%, 100% { filter: drop-shadow(0 0 4px var(--cp-accent)); }
  50%      { filter: drop-shadow(0 0 14px var(--cp-accent)); }
}
.cm-mermaid-hl.cm-mermaid-active { animation: cm-mermaid-pulse 0.7s ease-in-out 3; }
.cm-mermaid-add { position: fixed; z-index: 200; }

/* Hover bubble that opens a comment. Needed because a highlighted region may itself
   be a link (or other clickable element), which would swallow the click - the bubble
   is a reliable, always-clickable affordance to open the comment. */
.cm-hl-bubble {
  position: fixed; z-index: 210;
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; padding: 0;
  background: var(--cp-warning); color: #fff;
  border: 1.5px solid #fff; border-radius: 999px;
  cursor: pointer; box-shadow: var(--cp-shadow); line-height: 0;
}
.cm-hl-bubble:hover { filter: brightness(1.08); }
.cm-hl-bubble svg { width: 16px; height: 16px; display: block; }

/* Portability status badge (shown in the toolbar overflow menu). */
.cm-mode-badge {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 8px; border-radius: 999px;
  font-size: 11px; font-weight: 600; letter-spacing: 0.02em;
  border: 1px solid var(--cp-border-strong); color: var(--cp-text-muted);
  background: var(--cp-surface-soft); white-space: nowrap;
}
.cm-mode-badge.is-nonportable { color: var(--cp-warning); border-color: var(--cp-warning); }
/* Parity with the sidebar .cm-type-badge: the overflow-menu portability badge is colored
   and gets a help cursor from the same data-doc-type set by updateDocTypeUi. */
.cm-mode-badge[data-doc-type="Portable"] { color: var(--cp-success); border-color: var(--cp-success); background: rgba(22, 163, 74, 0.12); }
.cm-mode-badge[data-doc-type="Offline"] { color: var(--cp-accent); border-color: var(--cp-accent); background: var(--cp-accent-soft); }
.cm-mode-badge[data-doc-type="Not portable"] { color: var(--cp-warning); border-color: var(--cp-warning); background: rgba(245, 158, 11, 0.12); cursor: help; }

/* NonPortable-only controls are hidden until the layer detects nonportable mode. */
.cm-nonportable-only { display: none !important; }
body.cm-nonportable .cm-nonportable-only { display: inline-block !important; }
body.cm-nonportable .cm-toolbar-menu .cm-nonportable-only { display: block !important; }

/* Inline-only controls (e.g. Export nonportable) are shown only in a portable/inline
   document and hidden once the file is in nonportable mode. */
body.cm-nonportable .cm-inline-only { display: none !important; }
.cm-toolbar-menu .cm-inline-only { display: block; }

/* Prominent primary action (Copy all) in the toolbar. */
.cm-toolbar button.cm-primary { background: var(--cp-accent); color: var(--cp-accent-fg); }
.cm-toolbar button.cm-primary:hover { background: var(--cp-accent-hover); color: var(--cp-accent-fg); }

/* Icon-only "more actions" button + its dropdown menu. */
.cm-toolbar-more { position: relative; display: inline-flex; }
.cm-toolbar .cm-icon-btn { padding: var(--cp-chrome-button-y) calc(var(--cp-chrome-action-x) * 0.75); }
.cm-toolbar-menu {
  position: absolute; top: calc(100% + 0.5rem); right: 0; z-index: 120;
  min-width: 12rem; display: flex; flex-direction: column; gap: calc(var(--cp-chrome-button-gap) * 0.5);
  padding: var(--cp-chrome-gap); background: var(--cp-surface); color: var(--cp-text);
  border: 1px solid var(--cp-border); border-radius: 12px; box-shadow: var(--cp-shadow);
}
.cm-toolbar-menu .cm-mode-badge { align-self: flex-start; margin: var(--cp-chrome-pill-y) calc(var(--cp-chrome-button-gap) * 0.6) var(--cp-chrome-button-y); }
.cm-toolbar-menu button {
  width: 100%; justify-content: flex-start; text-align: left;
  display: flex; align-items: center; gap: var(--cp-chrome-gap);
  padding: var(--cp-chrome-menu-item-y) var(--cp-chrome-action-x); border-radius: 8px; font-size: var(--cp-chrome-font);
}
.cm-toolbar-menu button:hover { background: var(--cp-accent-soft); color: var(--cp-accent); }

/* Missing-companion-assets banner (nonportable mode only). Revealed by the tiny
   inline bootstrap when the external runtime fails to initialize in time. */
#cmhAssetBanner {
  position: fixed; top: 0; left: 0; right: 0; z-index: 400;
  display: flex; align-items: center; justify-content: center; gap: 12px;
  padding: 10px 16px; font-size: 13px; line-height: 1.4;
  background: var(--cp-danger); color: #fff;
  box-shadow: var(--cp-shadow); text-align: center;
}
#cmhAssetBanner code { background: rgba(0,0,0,0.18); padding: 1px 5px; border-radius: 4px; }
#cmhAssetBanner .cmh-asset-message { flex: 0 1 auto; }
#cmhAssetBanner .cmh-asset-dismiss {
  flex: 0 0 auto; width: 24px; height: 24px; border-radius: 999px;
  border: 1px solid rgba(255,255,255,0.55); background: rgba(0,0,0,0.18);
  color: #fff; font-weight: 700; line-height: 1;
}
#cmhAssetBanner .cmh-asset-dismiss:hover, #cmhAssetBanner .cmh-asset-dismiss:focus-visible {
  background: rgba(0,0,0,0.32); outline: 2px solid rgba(255,255,255,0.7); outline-offset: 2px;
}
/* --- Diff / code-review layer (pre.cmh-diff / div.cmh-diff) --- */
.cmh-diff-host { margin: 1rem 0; }
.cmh-diff-view {
  border: 1px solid var(--cp-border); border-radius: 10px; overflow: hidden;
  background: var(--cp-surface); font-size: 0.82rem;
}
.cmh-diff-bar {
  display: flex; align-items: center; justify-content: space-between; gap: 0.6rem;
  padding: 0.45rem 0.7rem; background: var(--cp-surface-soft);
  border-bottom: 1px solid var(--cp-border);
}
.cmh-diff-label {
  font-family: Consolas, "Courier New", Courier, monospace;
  font-size: 0.8rem; color: var(--cp-text); font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cmh-diff-toggle, .cmh-diff-hltoggle {
  flex: none; background: var(--cp-surface); border: 1px solid var(--cp-border);
  color: var(--cp-text); border-radius: 999px; padding: 0.22rem 0.7rem;
  font-family: inherit; font-size: 0.76rem; cursor: pointer;
}
.cmh-diff-toggle:hover, .cmh-diff-hltoggle:hover { border-color: var(--cp-accent); color: var(--cp-accent); }
/* Syntax toggle: light green when ON, light red when OFF. */
.cmh-diff-hltoggle[aria-pressed="true"] { background: rgba(45, 164, 78, 0.16); border-color: rgba(45, 164, 78, 0.55); }
.cmh-diff-hltoggle[aria-pressed="false"] { background: rgba(209, 36, 47, 0.14); border-color: rgba(209, 36, 47, 0.5); }
.cmh-diff-body {
  overflow-x: auto;
  font-family: Consolas, "Courier New", Courier, monospace; line-height: 1.5;
}
.cmh-diff-inline .cmh-diff-body { display: block; }
.cmh-diff-split .cmh-diff-body { display: grid; grid-template-columns: 1fr 1fr; }
.cmh-diff-split .cmh-dl[data-side="old"] { border-right: 1px solid var(--cp-border); }
.cmh-diff-split .cmh-dl-full { grid-column: 1 / -1; }
.cmh-diff-pane { min-width: 0; }
.cmh-diff-raw .cmh-diff-body { display: block; }
.cmh-diff-toobig { padding: 0.4rem 0.7rem; font-family: inherit; font-size: 0.78rem; color: var(--cp-warning); background: var(--cp-surface-soft); border-bottom: 1px solid var(--cp-border); }
.cmh-diff-raw pre.cmh-diff-raw { margin: 0; padding: 0.5rem 0.7rem; white-space: pre; overflow-x: auto; color: var(--cp-text-muted); }

.cmh-dl {
  display: flex; align-items: flex-start; gap: 0.4rem;
  padding: 0 0.5rem; white-space: pre-wrap; word-break: break-word;
  border-left: 3px solid transparent;
}
.cmh-dl[tabindex]:focus-visible { outline: 2px solid var(--cp-accent); outline-offset: -2px; }
.cmh-dl-gutter {
  flex: none; width: 2.6em; text-align: right; user-select: none;
  color: var(--cp-text-soft); opacity: 0.75; font-size: 0.72rem; padding-top: 0.05rem;
}
.cmh-dl-sign { flex: none; width: 0.8em; user-select: none; color: var(--cp-text-soft); }
.cmh-dl-code { flex: 1 1 auto; min-width: 0; }
.cmh-dl-full { color: var(--cp-text-muted); background: var(--cp-surface-soft); }
.cmh-dl-hunk { color: var(--cp-link); background: rgba(0, 120, 212, 0.06); font-style: italic; }
.cmh-dl-file { color: var(--cp-text-soft); font-size: 0.76rem; }
.cmh-dl-add { background: rgba(22, 163, 74, 0.10); }
.cmh-dl-add .cmh-dl-sign { color: var(--cp-success); }
.cmh-dl-del { background: rgba(220, 38, 38, 0.10); }
.cmh-dl-del .cmh-dl-sign { color: var(--cp-danger); }
.cmh-dl-spacer { background: repeating-linear-gradient(45deg, transparent, transparent 6px, var(--cp-surface-soft) 6px, var(--cp-surface-soft) 12px); min-height: 1.5em; }
.cmh-dl-add, .cmh-dl-del, .cmh-dl-ctx { cursor: default; }
.cmh-dl-add:hover, .cmh-dl-del:hover, .cmh-dl-ctx:hover { filter: brightness(0.97); }
html[data-theme="dark"] .cmh-dl-add:hover,
html[data-theme="dark"] .cmh-dl-del:hover,
html[data-theme="dark"] .cmh-dl-ctx:hover { filter: brightness(1.15); }
.cmh-dl-hl { border-left-color: var(--cp-warning); box-shadow: inset 0 0 0 9999px rgba(245, 158, 11, 0.10); }
@keyframes cmh-dl-pulse {
  0%, 100% { box-shadow: inset 0 0 0 9999px rgba(245, 158, 11, 0.10); }
  50%      { box-shadow: inset 0 0 0 9999px rgba(245, 158, 11, 0.30); }
}
.cmh-dl-hl.cmh-dl-active { animation: cmh-dl-pulse 0.7s ease-in-out 3; }
/* Sub-line region highlight: a comment on part of a diff line. */
mark.cmh-dl-mark {
  background: rgba(245, 158, 11, 0.34);
  color: inherit; border-radius: 2px; padding: 0 1px; cursor: pointer;
  box-shadow: 0 -1px 0 rgba(245, 158, 11, 0.55) inset;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}
mark.cmh-dl-mark:hover { background: rgba(245, 158, 11, 0.5); }
mark.cmh-dl-mark.cmh-dl-mark-active { background: rgba(245, 158, 11, 0.7); outline: 2px solid var(--cp-warning); }
html[data-theme="dark"] mark.cmh-dl-mark { background: rgba(251, 191, 36, 0.30); }
html[data-theme="dark"] mark.cmh-dl-mark:hover { background: rgba(251, 191, 36, 0.44); }
.cm-diff-add { position: fixed; z-index: 200; }


/* ---------------------------------------------------------------------------
   Default content styling (sections, tables, TOC, images, badges) - shipped so
   a generated or retrofitted document looks neat without the host adding its own
   rules. All are scoped to #commentRoot and use the --cp-* theme vars, and carry
   no !important so a host stylesheet can still override them.
   --------------------------------------------------------------------------- */
#commentRoot > section {
  background: var(--cp-surface); border: 1px solid var(--cp-border); border-radius: 16px;
  padding: 1.5rem; margin: 1.5rem 0;
  box-shadow: 0 0 2px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.14);
}
#commentRoot > section > h2:first-child, #commentRoot > section > h3:first-child { margin-top: 0; }
/* Document title: a themed top-level h1 so a generated or retrofitted document has a
   visible heading. A bare top-level h1 gets an underline rule; an h1 inside the lede
   surface stays borderless because the box already frames it. */
#commentRoot > h1, #commentRoot > header > h1 {
  font-size: 1.9rem; line-height: 1.2; font-weight: 700; letter-spacing: -0.01em;
  margin: 0 0 0.85rem; color: var(--cp-text);
}
#commentRoot > h1 { padding-bottom: 0.4rem; border-bottom: 2px solid var(--cp-border); }
#commentRoot .badge {
  display: inline-block; padding: 1px 8px; border-radius: 10px;
  font-size: 0.78rem; font-weight: 600; line-height: 1.5;
  max-width: 100%; overflow-wrap: anywhere;
  border: 1px solid var(--cp-border); background: var(--cp-surface-soft); color: var(--cp-text-muted);
}
/* State badges convey status via a tinted background + colored border while keeping
   the label in --cp-text, so contrast stays >= 4.5:1 in both light and dark. */
#commentRoot .badge.ok { border-color: var(--cp-success); background: rgba(22, 163, 74, 0.14); color: var(--cp-text); }
#commentRoot .badge.warn { border-color: var(--cp-warning); background: rgba(245, 158, 11, 0.16); color: var(--cp-text); }
#commentRoot .badge.danger { border-color: var(--cp-danger); background: rgba(220, 38, 38, 0.14); color: var(--cp-text); }
/* The light-theme amber border is faint against a white card; darken it. */
html:not([data-theme="dark"]) #commentRoot .badge.warn { border-color: #b45309; }

#commentRoot table { border-collapse: collapse; width: 100%; margin: 0.75rem 0 0.25rem; font-size: 0.9rem; }
/* `break-word`, NOT `anywhere`. The two break identically once a line is being laid out, but
   they differ in INTRINSIC SIZING, which is what table layout depends on: `anywhere`
   participates in min-content sizing, so every cell reports a min-content width of about one
   character and the table algorithm collapses a column to that width and shreds its text even
   while other columns still have spare room (a 14-column table rendered `NAMESPACE MOVE` as
   `NAMES`/`PACE`/`MOVE`). `break-word` is ignored for min-content, so a cell keeps its
   longest-word width and only breaks when there is genuinely nowhere left to go. */
#commentRoot th, #commentRoot td { border: 1px solid var(--cp-border); padding: 6px 9px; text-align: left; vertical-align: top; overflow-wrap: break-word; }
#commentRoot th { background: var(--cp-bg-elevated); font-weight: 600; }
#commentRoot tbody tr:nth-child(even) td { background: rgba(0, 0, 0, 0.04); }
html[data-theme="dark"] #commentRoot tbody tr:nth-child(even) td { background: rgba(255, 255, 255, 0.03); }
#commentRoot table caption { caption-side: top; text-align: left; color: var(--cp-text-soft); font-size: 0.82rem; padding: 0.2rem 0; }
/* Every table renders inside a `.cmh-table-scroll` box (see assets/js/61-table-scroll.js): a table
   whose columns genuinely cannot fit scrolls horizontally inside its own box instead of pushing the
   whole document sideways. This replaces the old `@media (max-width: 700px)` rule that set
   `display: block; overflow-x: auto` on the table itself - that contained the overflow, but only on
   narrow screens, and `display: block` wraps the rows in an anonymous table box that shrink-to-fits,
   which collapsed a narrow table's columns to their content width. The wrapper carries the table's
   margins because `overflow-x` makes it a block formatting context, which would otherwise trap the
   table's own margins inside it and change the spacing around every table. An explicit `width: 100%`
   matters in a FLEX parent (a `.cmh-diagram-gallery` card row, a deck slide): a scroll container's
   automatic minimum size is 0, so a width-less wrapper would shrink to min-content and collapse the
   table (measured: 900px -> 252px) - the very failure that ruled out `display: block` on the table. */
#commentRoot .cmh-table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; margin: 0.75rem 0 0.25rem; width: 100%; box-sizing: border-box; }
#commentRoot .cmh-table-scroll > table { margin: 0; }
/* A wrapper that actually scrolls takes a tab stop (61-table-scroll.js), so it needs a visible
   focus ring - the same affordance a scrollable gallery card gets. */
#commentRoot .cmh-table-scroll[data-cmh-scroll-a11y]:focus-visible {
  outline: 2px solid var(--cp-accent); outline-offset: 2px;
}

#commentRoot .cmh-lede { background: var(--cp-surface); border: 1px solid var(--cp-border); border-radius: 8px; padding: 0.75rem 1.25rem 1rem; margin: 0 0 1.25rem; color: var(--cp-text); font-size: 1.04em; line-height: 1.6; }
#commentRoot .cmh-lede > :first-child { margin-top: 0; }
#commentRoot .cmh-lede > :last-child { margin-bottom: 0; }

/* Callouts: theme-aware boxed asides. Text stays var(--cp-text) so it is readable
   on the soft tinted backgrounds in both light and dark themes. Authors must use
   these classes (or the theme variables) instead of hardcoding colors. */
#commentRoot .cmh-callout { border-radius: 8px; padding: 0.75rem 1rem; margin: 1rem 0; border: 1px solid var(--cp-border); background: var(--cp-surface-soft); color: var(--cp-text); line-height: 1.55; }
#commentRoot .cmh-callout > :first-child { margin-top: 0; padding-top: 0; }
#commentRoot .cmh-callout > :last-child { margin-bottom: 0; }
#commentRoot .cmh-callout-danger { border-color: var(--cp-danger); background: var(--cp-danger-soft); }
#commentRoot .cmh-callout-warning { border-color: var(--cp-warning); background: var(--cp-warning-soft); }
#commentRoot .cmh-callout-success { border-color: var(--cp-success); background: var(--cp-success-soft); }
#commentRoot .cmh-callout-info { border-color: var(--cp-accent); background: var(--cp-accent-soft); }
/* Non-color affordance: a leading glyph per variant so the meaning survives grayscale printing
   and color-blindness (color is not the only signal). The glyph sits in a ::before pseudo-element
   so it never enters text selection or comment offsets, is drawn in --cp-text so it stays legible
   in both themes and in grayscale (shape, not color, carries the meaning), and forces text (not
   emoji) presentation with the U+FE0E variation selector. Padding is scoped to the variant classes
   so a bare .cmh-callout shows no empty gutter. */
#commentRoot .cmh-callout { position: relative; }
#commentRoot .cmh-callout-info,
#commentRoot .cmh-callout-success,
#commentRoot .cmh-callout-warning,
#commentRoot .cmh-callout-danger { padding-inline-start: 2.4rem; }
#commentRoot .cmh-callout::before {
  position: absolute; inset-inline-start: 0.85rem; top: 0.75rem; font-weight: 700; font-style: normal;
  line-height: 1.55; color: var(--cp-text);
}
/* Each variant declares a plain `content` first (the glyph, shown everywhere) then a
   `content: ".." / ""` override that hides the glyph from the accessibility tree on browsers that
   support alt-text (screen readers use the runtime aria-label instead). A browser that does not
   parse the alt-text form drops only that second declaration and keeps the visible glyph. */
#commentRoot .cmh-callout-info::before { content: "i"; content: "i" / ""; }
#commentRoot .cmh-callout-success::before { content: "\2713\FE0E"; content: "\2713\FE0E" / ""; }
#commentRoot .cmh-callout-warning::before { content: "\26A0\FE0E"; content: "\26A0\FE0E" / ""; }
#commentRoot .cmh-callout-danger::before { content: "\2716\FE0E"; content: "\2716\FE0E" / ""; }

#commentRoot .cm-toc { background: var(--cp-surface); border: 1px solid var(--cp-border); border-radius: 8px; padding: 1rem 1.25rem; margin: 1.25rem 0; }
#commentRoot .cm-toc-title { font-weight: 700; color: var(--cp-text); margin-bottom: 0.5rem; font-size: 1rem; }
#commentRoot .cm-toc ol { margin: 0; padding-left: 1.4rem; }
#commentRoot .cm-toc li { margin: 0.25rem 0; font-size: 0.92rem; }
#commentRoot .cm-toc a { color: var(--cp-link); text-decoration: none; }
#commentRoot .cm-toc a:hover { text-decoration: underline; }

/* Document overview strip (doc_stats.py): section / word / reading-time counts under the title. */
#commentRoot .cmh-doc-stats { display: flex; flex-wrap: wrap; gap: 0.35rem 1.1rem; align-items: baseline; margin: 0.35rem 0 1.4rem; color: var(--cp-text-muted); font-size: 0.9rem; }
#commentRoot .cmh-doc-stats .cmh-doc-stat { white-space: nowrap; }
#commentRoot .cmh-doc-stats .cmh-doc-stat + .cmh-doc-stat::before { content: "\00B7"; margin-right: 1.1rem; color: var(--cp-border); }
#commentRoot .cmh-doc-stats .cmh-doc-stat strong { color: var(--cp-text); font-weight: 600; font-variant-numeric: tabular-nums; }

#commentRoot img { max-width: 100%; height: auto; }
/* Bare content figures (images) default to the browser's 40px side margins, which
   crowd the image on narrow screens; use symmetric block spacing so the figure fills
   the content width like the framed chart/KQL figures do. */
#commentRoot figure { margin: 1.25rem 0; }

/* Per-line code numbers are generated in an absolute cm-skip gutter, so they stay
   visible but never enter text selection, copy payloads, or offset anchoring. */
#commentRoot .cmh-code-wrap pre.cmh-code-lined,
#commentRoot .cmh-code-wrap pre code.cmh-code-lined {
  position: relative;
  counter-reset: cmh-code-line;
  padding-left: 3.4em;
}
#commentRoot .cmh-code-wrap pre code.cmh-code-lined { display: block; }
#commentRoot .cmh-code-wrap .cmh-code-lined > .cmh-code-gutter {
  position: absolute; left: 0; top: 0;
  width: 2.6em; text-align: right; pointer-events: none;
  line-height: inherit;
}
#commentRoot .cmh-code-wrap .cmh-code-lined > .cmh-code-gutter > .cmh-code-line {
  position: absolute;
  left: 0;
  width: 100%;
  counter-increment: cmh-code-line;
}
#commentRoot .cmh-code-wrap .cmh-code-lined > .cmh-code-gutter > .cmh-code-line::before {
  content: counter(cmh-code-line);
  display: block;
  color: var(--cp-text-soft);
  opacity: 0.82;
  font-variant-numeric: tabular-nums;
}

/* CMH-CONTENT-19: a robust GALLERY for MULTIPLE diagrams/figures whose aspect ratios vary a lot.
   Every naive layout fails on mixed aspect ratios: a plain CSS grid makes each row as tall as its
   tallest cell, so one tall diagram strands its short siblings in dead space (marooning); bounding a
   cell's height by shrinking the SVG width turns a tall-narrow diagram into a thin sliver; CSS
   multi-column packs them but is fragile with mermaid's dynamic sizing (tiny/empty in a real browser);
   and forcing every diagram to fill one uniform card (`svg{width:100%;height:100%}` + contain-fit, or
   `width:auto` capped at a narrow `max-width`) letterboxes a tall-narrow OR an extreme-wide diagram
   into a thin ribbon floating in an empty card - the sliver, just centred and sometimes rotated.
   Relying on the layer's JS narrow/wide scale-up fails differently: it is measurement-timing dependent
   and rendered diagrams TINY in a real browser (while passing headless).
   This helper instead lays the cards out as a centred FLEX-WRAP of UNIFORM-HEIGHT, content-HUGGING
   cards: every diagram is rendered at ONE fixed HEIGHT (`svg{height:15rem}`) with its WIDTH derived
   from the mermaid viewBox aspect ratio (`width:auto`, no clamp), and each card SHRINKS to hug that
   width up to a generous cap. So a wide diagram gets a wide card and a tall-narrow diagram gets a
   narrow full-height card, each filling its card in BOTH dimensions at readable size (no letterbox, no
   sliver, no marooning). The rare diagram wider than the cap keeps its full readable height and
   SCROLLS horizontally inside its card (`overflow-x:auto`), rather than being crushed into an
   unreadable strip. Sizing is pure deterministic CSS anchored on a definite height, so it is
   pixel-identical in Chromium, Firefox, and WebKit (verified) and has no JS-measurement race; the JS
   narrow/wide scale-up is additionally disabled for a gallery host (see updateMermaidWidthClass). The
   flex-wrap + card rules apply only above the mobile breakpoint: a single mobile column cannot maroon,
   so the layer's own diagram flow and wide-diagram scroll (CMH-RESP-01/09) are left intact there and
   the JS disable is gated to match. Print stacks it to a single column (see 92-print.css). */
#commentRoot .cmh-diagram-gallery { margin: 1rem 0; }
@media screen and (min-width: 481px) {
  #commentRoot .cmh-diagram-gallery {
    display: flex; flex-wrap: wrap; gap: 1rem;
    justify-content: center; align-items: flex-start;
  }
  /* Target the diagram CONTAINERS explicitly (not `> *`, which would turn a stray table/list into a
     card and break it). Each card is a flex item that HUGS its diagram: `flex: 0 1 auto` (no grow,
     may shrink) with the width coming from the svg's aspect-derived width, capped at a generous
     `max-width` so a card stays readable but never dominates. The `#commentRoot` id gives these rules
     specificity over the bare-diagram reset in 70-kql.css so no `!important` is needed here.
     `overflow-x:auto` lets a diagram WIDER than the cap scroll horizontally at full height instead of
     being crushed; `overflow-y:hidden` keeps the card exactly one row tall. (`min-width:0` plus either
     overflow value zeroes the flex item's automatic min-size, so a wide card can shrink and never
     overflows the row.) `align-items: FLEX-START` (not `center`) is critical: a centered over-wide flex
     item is pushed to a NEGATIVE start offset that the scroll range excludes, so the diagram's left
     edge is clipped and unreachable; flex-start keeps the start edge at the card's start so the whole
     diagram is scrollable. Centring is moot for a diagram that FITS (the card hugs it, so there is no
     spare space to centre within), so start-alignment is visually identical for a fitting diagram and
     correct for an overflowing one - and it needs no `safe` keyword, so it works in every browser. The
     `max-width:100%` before the `min()` is a fallback for a browser without CSS `min()`. */
  #commentRoot .cmh-diagram-gallery > pre.mermaid,
  #commentRoot .cmh-diagram-gallery > div.mermaid,
  #commentRoot .cmh-diagram-gallery > figure {
    flex: 0 1 auto; min-width: 0; margin: 0; box-sizing: border-box;
    max-width: 100%; max-width: min(100%, 48rem); overflow-x: auto; overflow-y: hidden;
    display: flex; flex-direction: column; align-items: flex-start; justify-content: center;
    padding: 0.85rem; border: 1px solid var(--cp-border); border-radius: 12px;
    background: var(--cp-surface-soft);
  }
  /* A `<figure>` card wraps a diagram plus a `<figcaption>`. `width:fit-content` keeps the figure
     hugging its content: for a SHORT caption it shrinks to the diagram width (no dead space); for a
     caption LONGER than the diagram it grows only up to the caption's bounded width (see the
     figcaption `max-width` below), so a long caption WRAPS to a readable width instead of either
     stretching the card to the caption's full length (marooning the diagram in horizontal dead space)
     OR collapsing to the tiny diagram width and towering into a many-line vertical strip. The diagram
     host uses `margin-inline:auto` so a diagram NARROWER than a caption-widened card is CENTRED (not
     stranded at the card's start edge); for a diagram WIDER than the card the auto margins resolve to
     zero, so the diagram's start edge stays at the card start and remains reachable by the horizontal
     scroll. The figcaption uses `margin-inline:auto` so a caption NARROWER than the card (a short
     caption under a wide diagram) is CENTRED rather than pinned to the card's start edge (which
     `align-self:stretch` would do once `max-width:22rem` clamps the box), its
     `text-align:center` centres the text within that box, `overflow-wrap:anywhere` so a long
     UNBREAKABLE token can break rather than forcing the card wider, and `max-width:22rem` so a long
     caption wraps at a readable prose width (this bound is what stops the figure from stretching to a
     multi-line-tall tower when the diagram is very narrow). When a diagram is wider than the card cap
     the figure itself is the horizontal scroll container, so the caption is `position:sticky;
     inset-inline-start:0` to stay pinned in the visible card while the diagram scrolls beneath it - a
     static caption would scroll off the start edge and strand the reader without the label. The logical
     `inset-inline-start` (not physical `left`) pins to the correct edge in both LTR and RTL. Sticky
     keeps the caption in normal flow, so it does NOT change the figure's content width (hugging is
     preserved). */
  #commentRoot .cmh-diagram-gallery > figure {
    width: fit-content;
  }
  #commentRoot .cmh-diagram-gallery > figure > pre.mermaid,
  #commentRoot .cmh-diagram-gallery > figure > div.mermaid {
    margin: 0; margin-inline: auto; min-width: 0; overflow: visible;
    display: flex; flex-direction: column; align-items: flex-start; justify-content: center;
  }
  #commentRoot .cmh-diagram-gallery > figure > figcaption {
    text-align: center; margin-top: 0.4rem; margin-inline: auto;
    overflow-wrap: anywhere; max-width: 22rem;
    position: sticky; inset-inline-start: 0;
  }
  /* Size every diagram to one fixed HEIGHT and let its WIDTH follow the viewBox aspect ratio, with NO
     max-width clamp, so the diagram renders at its natural (readable) width and the card hugs it; a
     diagram wider than the card cap simply overflows into the card's horizontal scroll. A definite
     height + `width:auto` makes the browser derive the width from the mermaid viewBox (identical across
     engines). `!important` overrides mermaid's inline max-width (its intrinsic px size), the 70-kql
     reset (`pre.mermaid svg { max-width: none }`), and the layer's narrow-scale-up var - which would
     otherwise leave a small diagram at its tiny intrinsic size (the tiny regression). */
  #commentRoot .cmh-diagram-gallery > pre.mermaid > svg,
  #commentRoot .cmh-diagram-gallery > div.mermaid > svg,
  #commentRoot .cmh-diagram-gallery > figure > pre.mermaid > svg,
  #commentRoot .cmh-diagram-gallery > figure > div.mermaid > svg {
    height: 15rem !important; width: auto !important;
    max-width: none !important; max-height: 15rem !important;
  }
  /* An overflowing (extreme-wide) card is made keyboard-focusable (markGalleryCardScrollable adds
     tabindex + data-cmh-scroll-a11y); give it a visible, themed focus ring so a keyboard user can see
     which scroll card they are on (the browser default outline is low-contrast on the soft surface). */
  #commentRoot .cmh-diagram-gallery > [data-cmh-scroll-a11y="1"]:focus-visible {
    outline: 2px solid var(--cp-accent); outline-offset: 2px;
  }
}


/* ---------------------------------------------------------------------------
   Image comment layer - per-image structural anchoring (mirrors the mermaid
   node layer). A commentable <img> gets a subtle hover ring; the floating
   #imageAddBtn snaps to its top-right; a commented image keeps a warning ring.
   --------------------------------------------------------------------------- */
#commentRoot img.cm-img-commentable, #commentRoot canvas.cm-img-commentable { cursor: pointer; }
#commentRoot img.cm-img-commentable:hover, #commentRoot canvas.cm-img-commentable:hover { outline: 2px dashed var(--cp-accent); outline-offset: 2px; }
#commentRoot img.cm-img-commentable:focus-visible, #commentRoot canvas.cm-img-commentable:focus-visible { outline: 3px solid var(--cp-accent); outline-offset: 2px; }
#commentRoot img.cm-img-hl, #commentRoot canvas.cm-img-hl { outline: 3px solid var(--cp-warning); outline-offset: 2px; border-radius: 3px; }
#commentRoot img.cm-img-hl.cm-img-active, #commentRoot canvas.cm-img-hl.cm-img-active { outline-width: 4px; box-shadow: 0 0 0 4px var(--cp-accent-soft); }
.cmh-chart-tooltip { z-index: 410; white-space: nowrap; }
.cm-image-add { position: fixed; z-index: 200; }
/* Commentable widget parts (generic opt-in via data-cm-part inside a data-cm-widget).
   Parts live inside a cm-skip widget but are individually commentable, so they get the
   same hover/focus/highlight affordances as images. */
#commentRoot [data-cm-part].cm-part-commentable { cursor: pointer; }
#commentRoot [data-cm-part].cm-part-commentable:hover { outline: 2px dashed var(--cp-accent); outline-offset: 2px; }
#commentRoot [data-cm-part].cm-part-commentable:focus-visible { outline: 3px solid var(--cp-accent); outline-offset: 2px; }
#commentRoot [data-cm-part].cm-part-hl { outline: 3px solid var(--cp-warning); outline-offset: 2px; border-radius: 3px; }
#commentRoot [data-cm-part].cm-part-hl.cm-part-active { outline-width: 4px; box-shadow: 0 0 0 4px var(--cp-accent-soft); }
#commentRoot [data-cm-widget][data-cm-draggable] [data-cm-slot] > [data-cm-part],
#commentRoot [data-cm-slot][data-cm-draggable] > [data-cm-part] { cursor: grab; }
#commentRoot [data-cm-part].cm-widget-drag-source { opacity: 0.55; cursor: grabbing; }
#commentRoot [data-cm-slot].cm-widget-drop-target {
  outline: 2px solid var(--cp-accent); outline-offset: 3px; background: var(--cp-accent-soft);
}
body.cm-widget-dragging, body.cm-widget-dragging #commentRoot { cursor: grabbing; user-select: none; }
.cm-widget-add { position: fixed; z-index: 200; }
/* Synthetic sidebar cards: document-wide comments and the auto-generated widget
   state-change record. */
.cm-card.cm-card-doc .pin { color: var(--cp-accent); }
.cm-card.cm-card-state { border-color: var(--cp-warning); background: var(--cp-warning-soft); }
.cm-card.cm-card-state .cm-card-state-title { font-weight: 600; color: var(--cp-text); font-size: 0.82rem; }
.cm-card.cm-card-state ul { margin: 0.35rem 0 0; padding-left: 1.1rem; font-size: 0.8rem; color: var(--cp-text); }
.cm-card.cm-card-state li { margin: 0.1rem 0; }
/* A draggable widget hosts a corner "Reset moves" button (runtime, cm-skip) whenever its
   layout differs from load; make the widget a positioning context so the button can pin. */
#commentRoot [data-cm-widget][data-cm-draggable] { position: relative; }
.cm-widget-reset {
  position: absolute; top: 0.4rem; right: 0.4rem; z-index: 5;
  background: var(--cp-surface); border: 1px solid var(--cp-border); color: var(--cp-text);
  border-radius: 999px; padding: 0.2rem 0.7rem; font-family: inherit; font-size: 0.72rem; font-weight: 600;
  cursor: pointer; box-shadow: var(--cp-shadow);
}
.cm-widget-reset:hover { border-color: var(--cp-accent); color: var(--cp-accent); }
/* Jumping from a state card briefly rings its board. */
#commentRoot [data-cm-widget].cm-widget-flash { outline: 3px solid var(--cp-warning); outline-offset: 4px; border-radius: 6px; }
/* Per-code-block Copy button: always visible, pinned to the block's top-right. */
.cmh-code-wrap { position: relative; }
/* The language pill + Copy button float over the block's top-right corner; reserve
   headroom on the code so a long first line scrolls/wraps under them instead of being
   overlapped by the controls. Scoped under #commentRoot so it outranks the id-scoped
   default pre padding. */
#commentRoot .cmh-code-wrap > pre { padding-top: 2.5rem; }
.cm-code-tools { position: absolute; top: 8px; right: 8px; z-index: 4; display: inline-flex; align-items: center; gap: 0.35rem; }
.cm-code-lang {
  font-size: 0.66rem; font-weight: 600; letter-spacing: 0.02em;
  color: var(--cp-text-soft); background: var(--cp-panel-strong); border: 1px solid var(--cp-border);
  border-radius: 999px; padding: 0.12rem 0.5rem; box-shadow: var(--cp-shadow); backdrop-filter: blur(6px);
}
.cm-code-copy {
  background: var(--cp-panel-strong); color: var(--cp-text); border: 1px solid var(--cp-border);
  border-radius: 6px; padding: 0.2rem 0.55rem; font-family: inherit; font-size: 0.72rem;
  cursor: pointer; box-shadow: var(--cp-shadow); backdrop-filter: blur(6px); opacity: 0.85;
}
.cm-code-copy:hover { border-color: var(--cp-accent); color: var(--cp-accent); opacity: 1; }
/* Sortable-table column chevrons. */
#commentRoot table.cmh-sortable th { white-space: nowrap; }
.cmh-sort-ctrl {
  margin-left: 0.35rem; padding: 0; border: none; background: transparent; cursor: pointer;
  display: inline-flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 0.16rem; line-height: 0.7; vertical-align: middle; font-size: 0.62rem; color: var(--cp-text-soft);
}
.cmh-sort-ctrl .cmh-sort-up, .cmh-sort-ctrl .cmh-sort-dn { opacity: 0.38; }
.cmh-sort-ctrl .cmh-sort-up::before { content: "\25B2"; }
.cmh-sort-ctrl .cmh-sort-dn::before { content: "\25BC"; }
.cmh-sort-ctrl:hover .cmh-sort-up, .cmh-sort-ctrl:hover .cmh-sort-dn { opacity: 0.7; }
.cmh-sort-ctrl[data-dir="asc"] .cmh-sort-up { opacity: 1; color: var(--cp-accent); }
.cmh-sort-ctrl[data-dir="desc"] .cmh-sort-dn { opacity: 1; color: var(--cp-accent); }

/* ---------------------------------------------------------------------------
   Link comment layer (CMH-LINK) - author-facing <a href> links get a subtle
   hover cue and a floating #linkAddBtn; a commented link keeps a warning
   underline + ring so the reader can see which references carry feedback. The
   affordance button is separate, so activating it never navigates and a normal
   click still follows the link. --------------------------------------------- */
#commentRoot a.cm-link-commentable:hover { text-decoration-thickness: 2px; outline: 1px dashed var(--cp-accent); outline-offset: 2px; border-radius: 2px; }
#commentRoot a.cm-link-hl { outline: 2px solid var(--cp-warning); outline-offset: 2px; border-radius: 2px; text-decoration-color: var(--cp-warning); }
#commentRoot a.cm-link-hl.cm-link-active { outline-width: 3px; box-shadow: 0 0 0 3px var(--cp-accent-soft); }
.cm-link-add { position: fixed; z-index: 200; }
/* ---------------------------------------------------------------------------
   Kusto query blocks - a framed figure (caption bar + code) with author-time KQL
   syntax highlighting. The .cmh-kql-* token spans are baked into the code by
   tools/kql_highlight.py; these rules only supply the frame and token colors, so
   no per-report CSS is needed. Scoped to #commentRoot, --cp-* vars, no !important.
   --------------------------------------------------------------------------- */
#commentRoot figure.cmh-kql {
  margin: 1.25rem 0; border: 1px solid var(--cp-border); border-radius: 10px;
  overflow: hidden; background: var(--cp-surface);
}
#commentRoot figure.cmh-kql .cmh-kql-cap {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: 0.4rem 0.75rem; font-size: 0.82rem;
  background: var(--cp-surface-soft); border-bottom: 1px solid var(--cp-border);
}
#commentRoot figure.cmh-kql .cmh-kql-title {
  flex: 0 1 auto; min-width: 0; overflow-wrap: anywhere; font-weight: 600; color: var(--cp-text-muted); cursor: pointer;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  background: transparent; border: 0; padding: 0; font-size: inherit; text-align: left;
}
#commentRoot figure.cmh-kql .cmh-kql-title:hover { color: var(--cp-accent); text-decoration: underline; }
#commentRoot figure.cmh-kql .cmh-kql-run {
  flex: none; white-space: nowrap; font-weight: 600; text-decoration: none; color: var(--cp-link);
}
#commentRoot figure.cmh-kql .cmh-kql-run:hover { text-decoration: underline; }
html[data-theme="dark"] #commentRoot figure.cmh-kql .cmh-kql-run { color: #f8fafc; }
html[data-theme="dark"] #commentRoot figure.cmh-kql .cmh-kql-run:hover { color: #dbeafe; }
/* On a narrow screen the cluster title and the "Run in ..." link cannot sit side by
   side without cramping, so stack them on their own lines. */
@media (max-width: 700px) {
  #commentRoot figure.cmh-kql .cmh-kql-cap { flex-direction: column; align-items: flex-start; gap: 0.35rem; }
}
#commentRoot figure.cmh-kql pre {
  margin: 0; border: 0; border-radius: 0; padding: 0.7rem 0.9rem; overflow-x: auto;
  background: var(--cp-bg-elevated);
}
/* The Copy/language pills are wrapped around every code block at runtime, KQL figures
   included, so the KQL <pre> needs the same top headroom; this selector outranks the
   frameless-KQL rule just above so the reserved space is not lost. */
#commentRoot figure.cmh-kql .cmh-code-wrap > pre { padding-top: 2.5rem; }
/* Standalone code blocks get a light frame like the KQL figure. The KQL figure's own
   <pre> (higher specificity above) stays frameless; the mermaid host is reset below. */
#commentRoot pre {
  background: var(--cp-bg-elevated); border: 1px solid var(--cp-border);
  border-radius: 10px; padding: 0.85rem 1rem; overflow-x: auto;
}
/* Pin a deterministic numeric line-height on the gutter-bearing code/KQL blocks - both the <pre>
   and the measured <code> - so the per-line gutter that setupCodeLineNumbers() overlays always
   reads a stable px line-height from getComputedStyle(target).lineHeight and never falls back to a
   hardcoded 20px. Without this, a report/deck/theme whose ambient line-height (or a
   `code { line-height: normal }` reset) leaves the computed value the keyword `normal` makes the JS
   parseFloat to NaN, so the line numbers sit above the text and drift down a tall block. Value 1.55
   is the base body line-height (assets/template.shell.html), so there is no visual change to the
   shipped defaults. The mermaid and diff <pre> are excluded (they are not gutter-bearing, so their
   own typography is left untouched), and the <code> is covered at a specificity above a bare
   `code { line-height: ... }` rule so the pin holds even when a theme resets line-height directly on
   the <code> the gutter measures. The <code> is matched as a descendant (not a direct child) so it
   still covers the target setupCodeLineNumbers() picks via pre.querySelector("code"), even if the
   <code> is nested below the <pre>. */
#commentRoot pre:not(.mermaid):not(.cmh-diff):not(.cmh-diff-raw),
#commentRoot pre:not(.mermaid):not(.cmh-diff):not(.cmh-diff-raw) code {
  line-height: 1.55;
}
/* Optional author caption/filename line above a standalone code block (data-code-caption
   on the <pre>): a cm-skip bar joined seamlessly to the framed code below it, mirroring the
   KQL caption look. The language pill + Copy button live INSIDE the bar as flex items on the
   right, so the filename text (which flexes and ellipsizes) can never overlap them for any
   language-label width; the caption is non-selectable chrome so a drag that starts on it
   cannot leak the filename into a code comment's quote. Scoped to #commentRoot, --cp-* vars. */
#commentRoot .cmh-code-wrap.cmh-has-caption { margin: 1.25rem 0; }
#commentRoot .cmh-code-wrap > .cmh-code-caption {
  display: flex; align-items: center; gap: 1rem; min-height: 1.4rem;
  padding: 0.4rem 0.9rem;
  font-size: 0.82rem; font-weight: 600;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  color: var(--cp-text-muted); background: var(--cp-surface-soft);
  border: 1px solid var(--cp-border); border-bottom: 0; border-radius: 10px 10px 0 0;
  -webkit-user-select: none; user-select: none;
}
#commentRoot .cmh-code-caption > .cmh-code-caption-text {
  flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Inside the caption the tools flow inline (not floating over the code). */
#commentRoot .cmh-code-wrap.cmh-has-caption > .cmh-code-caption > .cm-code-tools {
  position: static; top: auto; right: auto; flex: none;
}
#commentRoot .cmh-code-wrap.cmh-has-caption > pre {
  margin: 0; padding-top: 0.85rem;
  border-top: 0; border-top-left-radius: 0; border-top-right-radius: 0;
}
#commentRoot pre.mermaid { background: none; border: 0; border-radius: 0; padding: 0; max-width: 100%; overflow-x: auto; overflow-y: hidden; }
#commentRoot pre.mermaid svg { max-width: none; }
#commentRoot pre.mermaid.cmh-diagram-scroll-fade {
  -webkit-mask-image: linear-gradient(to right, transparent 0, #000 18px, #000 calc(100% - 18px), transparent 100%);
  mask-image: linear-gradient(to right, transparent 0, #000 18px, #000 calc(100% - 18px), transparent 100%);
}
/* Chart figures are boxed for readability, like code and KQL blocks. */
#commentRoot figure.chart {
  margin: 1.25rem 0; border: 1px solid var(--cp-border); border-radius: 10px;
  padding: 0.85rem 1rem; background: var(--cp-surface); max-width: 100%; overflow-x: auto; overflow-y: hidden;
}
#commentRoot figure.chart > .chart-wrap {
  position: relative; width: 100%; max-width: 100%; height: clamp(220px, 42vw, 440px);
  max-height: min(60vh, 480px); min-height: 160px; overflow: hidden;
}
#commentRoot figure.chart canvas,
#commentRoot figure.chart img.cmh-chart,
#commentRoot canvas.cmh-chart {
  display: block; width: 100% !important; max-width: 100% !important;
  height: 100% !important; max-height: 100% !important; box-sizing: border-box;
  object-fit: contain;
}
#commentRoot figure.chart > figcaption { margin-top: 0.5rem; }
@media (max-width: 480px) {
  /* Keep only genuinely wide mermaid diagrams legible (they scroll inside their box).
     Small diagrams and responsive Chart.js canvases fit the viewport on their own. */
  #commentRoot pre.mermaid.cmh-diagram-wide svg { min-width: 560px; }
}
/* KQL syntax token colors (primer-style; light defaults + dark overrides). Plain
   identifiers/columns inherit --cp-text; only these categories are tinted. */
#commentRoot .cmh-kql-kw  { color: #8250df; font-weight: 600; }
#commentRoot .cmh-kql-fn  { color: #0550ae; }
#commentRoot .cmh-kql-str { color: #0a7d33; }
#commentRoot .cmh-kql-num { color: #953800; }
#commentRoot .cmh-kql-com { color: var(--cp-text-soft); font-style: italic; }
#commentRoot .cmh-kql-op  { color: var(--cp-text-muted); }
html[data-theme="dark"] #commentRoot .cmh-kql-kw  { color: #d2a8ff; }
html[data-theme="dark"] #commentRoot .cmh-kql-fn  { color: #79c0ff; }
html[data-theme="dark"] #commentRoot .cmh-kql-str { color: #7ee787; }
html[data-theme="dark"] #commentRoot .cmh-kql-num { color: #ffa657; }

/* General code syntax token colors (baked at author time by tools/highlight_code.py;
   same primer palette as the KQL tokens). Plain identifiers inherit --cp-text. The `key`
   token is a JSON property name, tinted apart from a string VALUE the way every mainstream
   JSON highlighter renders it. */
#commentRoot .cmh-code-kw  { color: #8250df; font-weight: 600; }
#commentRoot .cmh-code-fn  { color: #0550ae; }
#commentRoot .cmh-code-key { color: #0550ae; }
#commentRoot .cmh-code-str { color: #0a7d33; }
#commentRoot .cmh-code-num { color: #953800; }
#commentRoot .cmh-code-com { color: var(--cp-text-soft); font-style: italic; }
#commentRoot .cmh-code-op  { color: var(--cp-text-muted); }
html[data-theme="dark"] #commentRoot .cmh-code-kw  { color: #d2a8ff; }
html[data-theme="dark"] #commentRoot .cmh-code-fn  { color: #79c0ff; }
html[data-theme="dark"] #commentRoot .cmh-code-key { color: #79c0ff; }
html[data-theme="dark"] #commentRoot .cmh-code-str { color: #7ee787; }
html[data-theme="dark"] #commentRoot .cmh-code-num { color: #ffa657; }

/* KQL line counters share the generic code-line wrappers but use KQL-tuned tones. */
#commentRoot figure.cmh-kql .cmh-code-wrap code.cmh-code-lined > .cmh-code-gutter > .cmh-code-line.cmh-kql-line::before {
  color: var(--cp-text-muted); opacity: 0.9;
}
html[data-theme="dark"] #commentRoot figure.cmh-kql .cmh-code-wrap code.cmh-code-lined > .cmh-code-gutter > .cmh-code-line.cmh-kql-line::before {
  color: #9da7b3;
}


.cm-skip[hidden], .cm-skip [hidden] { display: none !important; }
/* A shared, themed focus ring for every interactive control the layer ships, so
   keyboard focus is clearly visible in both light and dark (the UA default
   outline has poor contrast on the dark surfaces). */
.cm-toolbar button:focus-visible,
.cm-toolbar-menu button:focus-visible,
.cm-sidebar button:focus-visible,
.cm-composer button:focus-visible,
.cm-composer textarea:focus-visible,
.cm-reply-input:focus-visible,
.cm-menu button:focus-visible,
.cm-mermaid-add:focus-visible,
.cm-diff-add:focus-visible,
.cm-image-add:focus-visible,
.cm-link-add:focus-visible,
.cm-widget-add:focus-visible,
.cm-storage-manager button:focus-visible,
.cm-toast-action:focus-visible,
.cm-hl-bubble:focus-visible {
  outline: 2px solid var(--cp-accent);
  outline-offset: 2px;
}

/* Layered checklist: four-state item controls, hierarchy indentation, and the per-list
   change card. The state icon (an injected cm-skip button) replaces the native list marker;
   the item label stays ordinary commentable content. */
#commentRoot .cmh-checklist ul, #commentRoot .cmh-checklist ol { list-style: none; }
#commentRoot .cmh-checklist.cmh-checklist-ready ul { padding-left: 1.4rem; }
#commentRoot .cmh-checklist.cmh-checklist-ready > ul { padding-left: 0.2rem; }
#commentRoot li.cmh-check-item { position: relative; margin: 0.15rem 0; }
#commentRoot .cmh-check-item[data-cmh-check-role="branch"] { font-weight: 600; }
#commentRoot .cmh-check-item[data-cmh-check-role="branch"] .cmh-check-item { font-weight: 400; }

/* The four-state control. It is cm-skip (never a comment target) and sits inline before the
   label, or inside a table row's state cell. */
.cmh-check {
  display: inline-flex; align-items: center; justify-content: center;
  vertical-align: -0.35em; margin-right: 0.4rem; padding: 0;
  width: 1.35rem; height: 1.35rem;
  background: transparent; border: none; border-radius: 6px;
  cursor: pointer; color: inherit; line-height: 0;
}
.cmh-check:hover { background: var(--cp-accent-soft); }
.cmh-check:focus-visible { outline: 2px solid var(--cp-accent); outline-offset: 2px; }
.cmh-check svg { display: block; }
#commentRoot table.cmh-checklist td .cmh-check { margin-right: 0; }
#commentRoot table.cmh-checklist.cmh-checklist-ready td:first-child { width: 1.8rem; text-align: center; }

/* On touch/narrow screens the compact state control keeps its small glyph but gets a
   >=44px invisible tap target (an overlaid pseudo-element), so it is comfortable to hit
   without enlarging the visible icon or disturbing dense rows/nested lists. */
@media (max-width: 640px) {
  .cmh-check { position: relative; }
  .cmh-check::after {
    content: ""; position: absolute; top: 50%; left: 50%;
    width: 44px; height: 44px; transform: translate(-50%, -50%);
  }
  /* Give dense checklist rows enough vertical rhythm that neighbouring 44px tap
     targets do not overlap into each other. */
  #commentRoot li.cmh-check-item { margin-block: 0.4rem; }
  /* Table-mode checklists have no list-item margin, so pad each row instead: this
     keeps the row pitch at least ~44px so the vertically centred tap overlays map to
     their own row and cannot steal a neighbouring row's hit area. */
  #commentRoot table.cmh-checklist.cmh-checklist-ready td { padding-block: 0.75rem; }
}

/* Jump-flash when a change card's jump button targets a checklist. */
@keyframes cmh-check-flash-kf { 0%, 100% { box-shadow: none; } 30% { box-shadow: 0 0 0 3px var(--cp-accent-soft); } }
#commentRoot .cmh-check-flash { animation: cmh-check-flash-kf 0.7s ease-in-out 2; border-radius: 8px; }

/* Per-list change card in the sidebar (shaped like a comment card, not counted as one). */
.cm-card-checklist .cmh-cl-changes { list-style: none; margin: 0.25rem 0 0; padding: 0; }
.cm-card-checklist .cmh-cl-changes li { display: flex; align-items: center; gap: 0.3rem; margin: 0.15rem 0; font-size: 0.8rem; }
.cm-card-checklist .cmh-cl-mini { display: inline-flex; line-height: 0; }
.cm-card-checklist .cmh-cl-arrow { color: var(--cp-text-soft); }
.cm-card-checklist .cm-card-state-title { font-weight: 600; margin-top: 0.15rem; }
/* Editable notes fields: a clearly-editable textarea with a label chip and a single/multi-line
   toggle, plus the per-note change card. The card reuses the comment card shape and its .acts
   buttons, so its jump/reset match the other comment cards' theme. */
#commentRoot .cmh-note.cmh-note-ready {
  display: block;
  margin: 0.6rem 0;
  padding: 0.55rem 0.7rem;
  border: 1px solid var(--cp-border, #d8dee9);
  border-radius: 10px;
  background: var(--cp-surface, #fbfcfe);
}
#commentRoot .cmh-note-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.4rem;
}
#commentRoot .cmh-note-label {
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--cp-accent, #2f6f4f);
  background: var(--cp-accent-soft, #e7f4ec);
  border: 1px solid var(--cp-accent-soft, #bfe0cd);
  border-radius: 999px;
  padding: 0.15rem 0.55rem;
}
#commentRoot .cmh-note-label::before { content: "\270E\00a0"; }
#commentRoot .cmh-note-toggle {
  font-size: 0.7rem;
  font-weight: 600;
  color: var(--cp-text-soft, #4a5568);
  background: var(--cp-surface-2, #eef1f6);
  border: 1px solid var(--cp-border, #d3d9e3);
  border-radius: 6px;
  padding: 0.2rem 0.5rem;
  cursor: pointer;
}
#commentRoot .cmh-note-toggle:hover { background: var(--cp-accent-soft); }
#commentRoot .cmh-note-toggle:focus-visible { outline: 2px solid var(--cp-accent); outline-offset: 2px; }
#commentRoot .cmh-note-input {
  display: block;
  width: 100%;
  box-sizing: border-box;
  resize: vertical;
  font: inherit;
  line-height: 1.5;
  color: var(--cp-text, inherit);
  background: var(--cp-bg, #fff);
  border: 1px solid var(--cp-border, #c7ced9);
  border-radius: 8px;
  padding: 0.4rem 0.55rem;
  white-space: pre-wrap;
}
#commentRoot .cmh-note.cmh-note-single .cmh-note-input {
  resize: none;
  white-space: nowrap;
  overflow-x: auto;
}
#commentRoot .cmh-note-input:hover { border-color: var(--cp-accent, #93a4bd); }
#commentRoot .cmh-note-input:focus {
  outline: none;
  border-color: var(--cp-accent, #3b82f6);
  box-shadow: 0 0 0 3px var(--cp-accent-soft, rgba(59, 130, 246, 0.18));
}

/* Jump-flash when a change card's jump button targets a note. */
@keyframes cmh-note-flash-kf { 0%, 100% { box-shadow: none; } 30% { box-shadow: 0 0 0 3px var(--cp-accent-soft); } }
#commentRoot .cmh-note-flash { animation: cmh-note-flash-kf 0.7s ease-in-out 2; }

/* Foldable notes: a +/- disclosure button reveals or hides the field on the line below. Collapse is
   session-only presentation. The collapsed rules are #commentRoot-scoped so they outrank the base
   `#commentRoot .cmh-note-input { display: block }` rule above. */
#commentRoot .cmh-note-fold {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.4rem; height: 1.4rem; padding: 0; margin-right: 0.15rem;
  font: 700 1rem/1 var(--cp-font, inherit);
  color: var(--cp-accent, #1d4ed8);
  background: var(--cp-accent-soft, #e6efff);
  border: 1px solid var(--cp-border, #bcd2ff); border-radius: 6px;
  cursor: pointer;
}
#commentRoot .cmh-note-fold::before { content: "\2212"; }          /* minus: expanded */
#commentRoot .cmh-note-collapsed .cmh-note-fold::before { content: "+"; }
#commentRoot .cmh-note-fold:hover { background: var(--cp-accent, #d7e4ff); }
#commentRoot .cmh-note-fold:focus-visible { outline: 2px solid var(--cp-accent); outline-offset: 2px; }
#commentRoot .cmh-note.cmh-note-collapsed .cmh-note-input,
#commentRoot .cmh-note.cmh-note-collapsed .cmh-note-toggle { display: none; }
#commentRoot .cmh-note.cmh-note-collapsed .cmh-note-head { margin-bottom: 0; }
/* A badge on a collapsed note that still holds content, so hidden text is discoverable. */
#commentRoot .cmh-note-label::after {
  content: "\25CF"; display: none;
  margin-left: 0.4rem; font-size: 0.7rem; color: var(--cp-accent, #1d4ed8);
}
#commentRoot .cmh-note.cmh-note-has-content .cmh-note-label::after { display: inline; }

/* Per-note change card in the sidebar (shaped like a comment card, not counted as one). */
.cm-card-note .cmh-note-diff {
  display: block;
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
}
.cm-card-note .cmh-note-arrow { color: var(--cp-text-soft); }

/* On phones the compact note controls keep their small glyphs but expose a >=44px
   touch target (the fold via an overlaid pseudo-element, the toggle via min-height). */
@media (max-width: 640px) {
  #commentRoot .cmh-note-fold { position: relative; }
  #commentRoot .cmh-note-fold::after {
    content: ""; position: absolute; top: 50%; left: 50%;
    width: 44px; height: 44px; transform: translate(-50%, -50%);
  }
  #commentRoot .cmh-note-toggle { min-height: 44px; }
}
/* Unvalidated-document fallback banner (CMH-STAMP-03): a small, dismissible amber strip shown when a
   document carries a created stamp but no current validated stamp. It is cm-skip chrome and never
   bakes into an export. A high z-index keeps it visible on a fixed-stage deck too. */
.cmh-unvalidated-banner {
  position: fixed;
  left: 12px;
  bottom: 12px;
  z-index: 100003;
  max-width: min(520px, calc(100vw - 24px));
  display: flex;
  gap: 10px;
  align-items: flex-start;
  padding: 9px 11px;
  border: 1px solid #f59e0b;
  border-radius: 8px;
  background: #fffbeb;
  color: #78350f;
  font: 13px/1.45 -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.18);
}
.cmh-unvalidated-banner .cmh-unvalidated-msg { flex: 1 1 auto; }
.cmh-unvalidated-banner .cmh-unvalidated-dismiss {
  flex: 0 0 auto;
  border: none;
  background: transparent;
  color: #78350f;
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  padding: 0 2px;
}
.cmh-unvalidated-banner .cmh-unvalidated-dismiss:hover { color: #92400e; }
html[data-theme="dark"] .cmh-unvalidated-banner {
  border-color: #b45309;
  background: #3a2a0a;
  color: #fde68a;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.5);
}
html[data-theme="dark"] .cmh-unvalidated-banner .cmh-unvalidated-dismiss { color: #fde68a; }
/* Rich-text comment notes: the small markdown-ish formatting rendered inside a note (bold, italic,
   underline, strikethrough, inline code, bullet lists, links) and the composer's formatting toolbar.
   The .cmh-rich class is carried by the sidebar card note, the inline popover note, and the print
   appendix note; the note containers keep white-space: pre-wrap (set elsewhere), so this partial only
   styles the inline elements and lists, never the whitespace model. */

.cmh-rich strong { font-weight: 700; }
.cmh-rich em { font-style: italic; }
.cmh-rich u { text-decoration: underline; }
.cmh-rich s { text-decoration: line-through; }
.cmh-rich code {
  font-family: Consolas, "Courier New", Courier, monospace;
  font-size: 0.92em;
  background: var(--cp-surface-soft, rgba(127, 127, 127, 0.14));
  border: 1px solid var(--cp-border);
  padding: 0.03em 0.35em;
  border-radius: 4px;
}
.cmh-rich a { color: var(--cp-link); text-decoration: underline; word-break: break-word; }
.cmh-rich a:hover { text-decoration: none; }
.cmh-rich a:focus-visible { outline: 2px solid var(--cp-accent); outline-offset: 2px; border-radius: 2px; }
.cmh-rich ul.cmh-rich-list { margin: 0.3em 0; padding-left: 1.4em; }
.cmh-rich ul.cmh-rich-list li { margin: 0.1em 0; }
.cmh-print-note.cmh-rich { margin: 0.5em 0; white-space: pre-wrap; word-break: break-word; }

/* Composer formatting toolbar: a compact row of wrap buttons above the note textarea. */
.cm-format-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin: 0.1rem 0 0.4rem;
}
.cm-format-bar button {
  min-width: 30px;
  padding: 3px 7px;
  font-size: 0.85rem;
  line-height: 1.2;
  background: var(--cp-surface);
  border: 1px solid var(--cp-border);
  color: var(--cp-text);
  border-radius: 6px;
  cursor: pointer;
}
.cm-format-bar button:hover { border-color: var(--cp-accent); color: var(--cp-accent); background: var(--cp-accent-soft); }
.cm-format-bar button:focus-visible { outline: 2px solid var(--cp-accent); outline-offset: 1px; }
.cm-format-bar button strong,
.cm-format-bar button em,
.cm-format-bar button s { font-size: inherit; }
/* Author attribution + comment threads (replies).
   Covers CMH-AUTHOR (the author pill + sidebar identity control) and CMH-THREAD (the
   root-entry / reply layout and the Reply button). */

/* ---- Author pill ---- */
.cm-author-pill {
  display: inline-block;
  font-size: 0.72rem;
  font-weight: 600;
  line-height: 1.35;
  padding: 0.05em 0.5em;
  margin-right: 0.4em;
  border-radius: 999px;
  vertical-align: text-bottom;
  white-space: nowrap;
  max-width: 12rem;
  overflow: hidden;
  text-overflow: ellipsis;
  color: hsl(var(--cm-author-hue, 210) 55% 28%);
  background: hsl(var(--cm-author-hue, 210) 70% 92%);
  border: 1px solid hsl(var(--cm-author-hue, 210) 45% 78%);
}
html[data-theme="dark"] .cm-author-pill {
  color: hsl(var(--cm-author-hue, 210) 85% 82%);
  background: hsl(var(--cm-author-hue, 210) 40% 24%);
  border-color: hsl(var(--cm-author-hue, 210) 35% 42%);
}

/* ---- Sidebar identity control ---- */
.cm-identity {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35rem;
  font-size: var(--cp-chrome-small-font, 0.78rem);
  color: var(--cp-muted, #64748b);
  margin-top: 0.15rem;
}
.cm-identity .cm-identity-label { flex: 0 0 auto; }
.cm-identity .cm-identity-name { font-weight: 600; }
.cm-identity .cm-identity-name.cm-identity-unset { font-style: italic; opacity: 0.85; }
.cm-identity .cm-identity-btn {
  flex: 0 0 auto;
  background: none;
  border: none;
  padding: 0 0.15rem;
  color: var(--cp-accent);
  cursor: pointer;
  text-decoration: underline;
  font-size: inherit;
}
.cm-identity .cm-identity-btn:hover { color: var(--cp-accent); opacity: 0.85; }
.cm-identity-edit { display: inline-flex; align-items: center; gap: 0.3rem; flex: 1 1 auto; min-width: 0; }
.cm-identity-edit[hidden] { display: none; }
.cm-identity-input {
  flex: 1 1 6rem;
  min-width: 0;
  padding: 0.15rem 0.4rem;
  font-size: inherit;
  border: 1px solid var(--cp-border, #cbd5e1);
  border-radius: 6px;
  background: var(--cp-surface, #fff);
  color: inherit;
}
/* The edit-mode Save/Cancel are themed, not default UA buttons: Save is the crimson primary (matching
   Copy all), Cancel a themed secondary with a border that hovers to the accent. */
.cm-identity-save, .cm-identity-cancel {
  flex: 0 0 auto;
  padding: 0.15rem 0.6rem;
  border-radius: 6px;
  font: inherit;
  font-weight: 600;
  line-height: 1.4;
  cursor: pointer;
}
.cm-identity-save {
  background: var(--cp-accent);
  color: var(--cp-accent-fg);
  border: 1px solid var(--cp-accent);
}
.cm-identity-save:hover { background: var(--cp-accent-hover); border-color: var(--cp-accent-hover); }
.cm-identity-cancel {
  background: var(--cp-surface);
  color: var(--cp-text);
  border: 1px solid var(--cp-border);
  font-weight: 500;
}
.cm-identity-cancel:hover { border-color: var(--cp-accent); color: var(--cp-accent); }

/* ---- Thread entries + replies ---- */
.cm-card .cm-entry-root .note { margin: 0; }
.cm-card .cm-replies {
  margin-top: 0.5rem;
  padding-left: 0.6rem;
  border-left: 2px solid var(--cp-border, #e2e8f0);
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
}
.cm-card .cm-reply .note { margin: 0; }
.cm-card .cm-reply .meta { opacity: 0.9; }
.cm-card .cm-reply-row { margin-top: 0.45rem; }
.cm-card .cm-reply-btn {
  background: none;
  border: 1px solid var(--cp-border, #cbd5e1);
  border-radius: 6px;
  padding: 0.1rem 0.6rem;
  font-size: var(--cp-chrome-small-font, 0.78rem);
  color: var(--cp-accent);
  cursor: pointer;
}
.cm-card .cm-reply-btn:hover { background: var(--cp-accent-soft); }

/* Inline reply composer (issue #644): compose a new reply or edit an existing one in place, in the
   thread card, instead of a floating popup. */
.cm-reply-compose { margin-top: 0.45rem; display: flex; flex-direction: column; gap: 0.35rem; }
.cm-card .cm-reply-editing .note[hidden] { display: none; }
.cm-reply-input {
  width: 100%;
  box-sizing: border-box;
  resize: vertical;
  min-height: 2.4rem;
  padding: 0.35rem 0.5rem;
  font: inherit;
  font-size: var(--cp-chrome-small-font, 0.82rem);
  line-height: 1.4;
  border: 1px solid var(--cp-border, #cbd5e1);
  border-radius: 6px;
  background: var(--cp-surface, #fff);
  color: inherit;
}
.cm-reply-input.cm-invalid { border-color: var(--cp-danger, #dc2626); }
.cm-reply-compose-actions { display: flex; justify-content: flex-end; gap: 0.4rem; }
.cm-reply-compose-actions button {
  border: 1px solid var(--cp-border, #cbd5e1);
  border-radius: 6px;
  padding: 0.12rem 0.7rem;
  font-size: var(--cp-chrome-small-font, 0.78rem);
  cursor: pointer;
  background: var(--cp-surface, #fff);
  color: inherit;
}
.cm-reply-compose-actions .cm-reply-save {
  background: var(--cp-accent);
  border-color: var(--cp-accent);
  color: var(--cp-accent-fg, #fff);
}
.cm-reply-compose-actions .cm-reply-cancel:hover { background: var(--cp-accent-soft); }

/* Print: show the author pill and replies as plain indented text. */
@media print {
  .cmh-print-reply { margin: 0.2rem 0 0 0.8rem; }
}
/* Storage manager dialog (cross-document localStorage). Reuses .cm-modal-overlay for the backdrop
   so a click outside the panel dismisses it; the panel is near-full-screen with small margins. */
.cm-storage-manager {
  max-width: none;
  width: min(96vw, 1400px);
  height: 92vh;
  display: flex;
  flex-direction: column;
  padding: 0;
}
.cm-storage-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 0.9rem var(--cp-chrome-modal-x); border-bottom: 1px solid var(--cp-border);
  flex: 0 0 auto;
}
.cm-storage-head h2 { margin: 0; font-size: 1.05rem; display: flex; align-items: center; gap: 0.4rem; }
.cm-storage-close {
  background: transparent; border: none; color: var(--cp-text-soft);
  font-size: calc(var(--cp-chrome-font) * 1.65); line-height: 1; cursor: pointer;
  padding: 0 var(--cp-chrome-button-y); border-radius: 6px;
}
.cm-storage-close:hover { color: var(--cp-accent); background: var(--cp-accent-soft); }
.cm-storage-intro {
  margin: 0; padding: 0.6rem var(--cp-chrome-modal-x) 0;
  font-size: var(--cp-chrome-help-font); line-height: 1.5; color: var(--cp-text-soft); flex: 0 0 auto;
}
.cm-storage-usage {
  margin: 0.2rem var(--cp-chrome-modal-x) 0.2rem; padding: 0.6rem 0.75rem;
  background: var(--cp-surface); border: 1px solid var(--cp-border); border-radius: 8px; flex: 0 0 auto;
  /* Slice colors, shared by the SVG wedges and the legend swatches. Each keeps at least a 3:1 contrast
     against the panel surface (light and dark) so the wedges stay distinguishable for low-vision users;
     the per-slice SVG <title> and the legend text are the non-color cues. `this` reuses --cp-accent,
     which already flips per theme. */
  --cm-pie-this: var(--cp-accent);
  --cm-pie-otherdocs: #4f46e5;
  --cm-pie-other: #b45309;
  --cm-pie-free: #64748b;
}
html[data-theme="dark"] .cm-storage-usage {
  --cm-pie-otherdocs: #a5b4fc;
  --cm-pie-other: #fbbf24;
  --cm-pie-free: #94a3b8;
}
.cm-storage-chart { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; }
.cm-storage-pie { flex: 0 0 auto; display: block; }
.cm-storage-pie .cm-pie-slice { stroke: var(--cp-surface); stroke-width: 1; }
.cm-storage-pie .cm-pie-this { fill: var(--cm-pie-this); }
.cm-storage-pie .cm-pie-otherdocs { fill: var(--cm-pie-otherdocs); }
.cm-storage-pie .cm-pie-other { fill: var(--cm-pie-other); }
.cm-storage-pie .cm-pie-free { fill: var(--cm-pie-free); }
.cm-storage-legend { list-style: none; margin: 0; padding: 0; flex: 1 1 12rem; min-width: 12rem; }
.cm-storage-legend-item {
  display: flex; align-items: center; gap: 0.5rem; font-size: 0.8rem; line-height: 1.9; color: var(--cp-text);
}
.cm-storage-legend-swatch {
  flex: 0 0 auto; width: 0.72rem; height: 0.72rem; border-radius: 3px; border: 1px solid var(--cp-border);
}
.cm-storage-legend-swatch.cm-pie-this { background: var(--cm-pie-this); }
.cm-storage-legend-swatch.cm-pie-otherdocs { background: var(--cm-pie-otherdocs); }
.cm-storage-legend-swatch.cm-pie-other { background: var(--cm-pie-other); }
.cm-storage-legend-swatch.cm-pie-free { background: var(--cm-pie-free); }
.cm-storage-legend-label { flex: 1 1 auto; }
.cm-storage-legend-size { flex: 0 0 auto; color: var(--cp-text-soft); font-variant-numeric: tabular-nums; }
.cm-storage-banner {
  margin: 0.6rem var(--cp-chrome-modal-x) 0; padding: 0.55rem 0.75rem; border-radius: 8px;
  font-size: var(--cp-chrome-help-font); line-height: 1.45; flex: 0 0 auto;
}
.cm-storage-banner-warn { background: rgba(220, 38, 38, 0.12); border: 1px solid var(--cp-danger); color: var(--cp-danger); }
.cm-storage-banner-ok { background: var(--cp-accent-soft); border: 1px solid var(--cp-accent); color: var(--cp-accent); }
.cm-storage-list { padding: 0.4rem var(--cp-chrome-modal-x) var(--cp-chrome-modal-x); overflow-y: auto; overflow-x: auto; flex: 1 1 auto; min-height: 0; }
.cm-storage-table { width: 100%; border-collapse: collapse; font-size: 0.86rem; }
.cm-storage-table thead th {
  text-align: left; font-size: 0.74rem; text-transform: uppercase; letter-spacing: 0.03em;
  color: var(--cp-text-soft); font-weight: 600; padding: 0.3rem 0.5rem; border-bottom: 1px solid var(--cp-border);
}
.cm-storage-table thead th:nth-child(2), .cm-storage-table thead th:nth-child(3), .cm-storage-table thead th:nth-child(4) { text-align: right; white-space: nowrap; }
.cm-storage-row > td { padding: 0.55rem 0.5rem; border-bottom: 1px solid var(--cp-border); vertical-align: top; }
.cm-storage-row .cm-storage-count, .cm-storage-row .cm-storage-size, .cm-storage-row .cm-storage-share { text-align: right; white-space: nowrap; color: var(--cp-text-soft); }
.cm-storage-current > td { background: var(--cp-accent-soft); }
.cm-storage-cell-name { min-width: 0; }
.cm-storage-name-line { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.cm-storage-name { font-weight: 600; font-size: 0.9rem; word-break: break-word; }
.cm-storage-badge {
  font-size: 0.72rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.03em;
  background: var(--cp-accent); color: var(--cp-accent-fg); border-radius: 999px; padding: 0.08rem 0.5rem;
}
.cm-storage-source { font-size: 0.76rem; color: var(--cp-text-soft); overflow-wrap: anywhere; margin-top: 0.1rem; }
.cm-storage-actions { display: flex; align-items: center; gap: 0.4rem; justify-content: flex-end; flex-wrap: wrap; }
.cm-storage-show-comments { margin-top: 0.35rem; font-size: 0.78rem; padding: 0.2rem 0.5rem; }
.cm-storage-btn {
  background: var(--cp-surface); border: 1px solid var(--cp-border); color: var(--cp-text);
  border-radius: 8px; padding: 0.35rem 0.7rem; font-size: 0.83rem; font-family: inherit; cursor: pointer;
}
.cm-storage-btn:hover { border-color: var(--cp-accent); color: var(--cp-accent); }
.cm-storage-danger { color: var(--cp-danger); border-color: var(--cp-danger); border-color: color-mix(in srgb, var(--cp-danger) 45%, var(--cp-border)); }
.cm-storage-danger:hover { background: rgba(220, 38, 38, 0.12); border-color: var(--cp-danger); color: var(--cp-danger); }
.cm-storage-confirm { display: flex; align-items: center; gap: 0.4rem; flex-wrap: wrap; justify-content: flex-end; }
.cm-storage-confirm-msg { font-size: 0.8rem; color: var(--cp-text); }
/* Per-document comment browse list (a full-width row under its document). */
.cm-storage-comments-row > td { padding: 0 0.5rem 0.55rem; background: var(--cp-surface); }
.cm-storage-comments { display: flex; flex-direction: column; gap: 0.3rem; padding-top: 0.2rem; }
.cm-storage-comment {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 0.6rem;
  padding: 0.4rem 0.55rem; border: 1px solid var(--cp-border); border-radius: 6px;
}
.cm-storage-comment-info { min-width: 0; flex: 1 1 auto; }
.cm-storage-comment-quote { font-size: 0.8rem; color: var(--cp-text-soft); font-style: italic; overflow-wrap: anywhere; }
.cm-storage-comment-note { font-size: 0.84rem; color: var(--cp-text); overflow-wrap: anywhere; margin-top: 0.1rem; }
.cm-storage-comment-meta { font-size: 0.74rem; color: var(--cp-text-soft); margin-top: 0.15rem; display: flex; gap: 0.5rem; flex-wrap: wrap; }
.cm-storage-comment .cm-storage-actions { flex: 0 0 auto; }
.cm-storage-comment-empty { font-size: 0.8rem; color: var(--cp-text-soft); padding: 0.3rem 0.2rem; }
.cm-storage-empty { padding: 0.8rem var(--cp-chrome-modal-x) var(--cp-chrome-modal-x); flex: 0 0 auto; }
.cm-storage-empty p { font-size: var(--cp-chrome-help-font); line-height: 1.5; color: var(--cp-text); margin: 0 0 0.6rem; }
.cm-storage-empty-actions { display: flex; gap: 0.5rem; flex-wrap: wrap; }
.cm-storage-global .cm-storage-name { font-weight: 600; }
.cm-storage-foot {
  flex: 0 0 auto; display: flex; justify-content: flex-end;
  padding: 0.6rem var(--cp-chrome-modal-x); border-top: 1px solid var(--cp-border);
}
.cm-storage-foot-close { min-width: 5rem; }

/* Inline action button inside a toast (e.g. "Manage storage" on a storage-full toast). The toast
   itself is pointer-events:none so it never blocks the page; the action re-enables clicks on itself
   ONLY while the toast is shown (.show). When the toast fades out the action returns to
   pointer-events:none, and showToast/hideToast removes it from the DOM, so a faded-out toast never
   leaves an invisible, clickable, or Tab-focusable control behind. */
.cm-toast-action {
  margin-left: 0.6rem; background: var(--cp-accent-fg); color: var(--cp-accent);
  border: none; border-radius: 999px; padding: 0.15rem 0.6rem; font-size: 0.82em;
  font-family: inherit; font-weight: 600; cursor: pointer; pointer-events: none;
}
.cm-toast.show .cm-toast-action { pointer-events: auto; }
.cm-toast-action:hover { filter: brightness(1.08); }

@media (max-width: 640px) {
  .cm-storage-manager { width: 96vw; height: 94vh; }
  .cm-storage-table { font-size: 0.82rem; }
  .cm-storage-comment { flex-direction: column; align-items: stretch; }
  .cm-storage-comment .cm-storage-actions { justify-content: flex-end; }
}
/* Deck profile (data-cmh-mode="deck"): comment-mode force-reveal and slide chrome. */
body.cmh-deck-present .cm-toolbar,
body.cmh-deck-present #sidebar {
  display: none !important;
}
/* The comments action toolbar (Copy all / Show / ...) is redundant in a deck: the single corner
   comment toggle plus the panel's own header controls cover it. Keep it out of decks entirely, in
   present AND comment mode, so only the one corner icon and the nav bar show. */
body:has(#commentRoot[data-cmh-mode="deck"]) .cm-toolbar {
  display: none !important;
}
/* Hide the corner comment-options control whenever the side panel is open: the panel's own
   header controls (Close, sort, Copy all) take over, and the control would sit over the sidebar.
   Applies at every width; closing the panel brings it back. */
body.sidebar-open:has(#commentRoot.cmh-deck-comment-mode) .cmh-deck-mode-ctl {
  display: none !important;
}
.cmh-deck-landscape-hint {
  position: fixed;
  left: 50%;
  bottom: 1rem;
  z-index: 100002;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 0.65rem;
  max-width: calc(100vw - 2rem);
  padding: 0.55rem 0.65rem 0.55rem 0.8rem;
  color: var(--cp-text, #fff);
  background: var(--cp-surface, #222);
  border: 1px solid var(--cp-border, #444);
  border-radius: 999px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.32);
  font-size: 0.85rem;
  line-height: 1.25;
}
.cmh-deck-landscape-hint[hidden] { display: none !important; }
.cmh-deck-landscape-hint button {
  border: 0;
  border-radius: 999px;
  padding: 0.3rem 0.55rem;
  background: var(--cp-accent, #2ecc71);
  color: var(--cp-accent-fg, #111);
  font: inherit;
  font-weight: 700;
  cursor: pointer;
}
.cmh-deck-landscape-hint button:hover { background: var(--cp-accent-hover, #27ae60); }
@media print {
  .cmh-deck-landscape-hint { display: none !important; }
}
/* When commenting is disabled ("off" state), suppress the text-selection popup so a selection is
   not a dead end. In the default state (comments on, panel closed) the popup DOES appear, so a
   reviewer can select text and Add Comment without first opening the panel. The rich-content
   floating "Add Comment" buttons (mermaid nodes, images, diff lines, widget parts, headings) are
   hidden too, so every comment entry point is inert - not just the selection popup. */
body.cmh-deck-comments-off #menuComment,
body.cmh-deck-comments-off #mermaidAddBtn,
body.cmh-deck-comments-off #imageAddBtn,
body.cmh-deck-comments-off #linkAddBtn,
body.cmh-deck-comments-off #diffAddBtn,
body.cmh-deck-comments-off #widgetAddBtn,
body.cmh-deck-comments-off #headingAddBtn {
  display: none !important;
}
#commentRoot[data-cmh-mode="deck"] .slide {
  --cmh-deck-code-bg: #0f172a;
  --cmh-deck-code-bg-soft: #111827;
  --cmh-deck-code-border: rgba(148, 163, 184, 0.44);
  --cmh-deck-code-text: #f8fafc;
  --cmh-deck-code-muted: #cbd5e1;
  --cmh-deck-code-soft: #94a3b8;
}
#commentRoot[data-cmh-mode="deck"] .slide table thead th {
  background: var(--cmh-deck-table-head-bg, rgba(15, 23, 42, 0.92));
  color: var(--cmh-deck-table-head-fg, #f8fafc);
  border-color: var(--cmh-deck-table-head-border, rgba(148, 163, 184, 0.48));
}
#commentRoot[data-cmh-mode="deck"] .slide table :is(th, td) {
  transition: background-color 0.16s ease;
}
#commentRoot[data-cmh-mode="deck"] .slide table :is(th, td):hover,
#commentRoot[data-cmh-mode="deck"] .slide table :is(th, td):focus-within {
  box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--cp-accent, #2ecc71) 58%, transparent);
}
#commentRoot[data-cmh-mode="deck"] .slide table td:hover,
#commentRoot[data-cmh-mode="deck"] .slide table td:focus-within {
  background: color-mix(in srgb, var(--cp-accent, #2ecc71) 14%, var(--cp-surface, #fff));
}
#commentRoot[data-cmh-mode="deck"] .slide table thead th:hover,
#commentRoot[data-cmh-mode="deck"] .slide table thead th:focus-within {
  background: color-mix(in srgb, var(--cp-accent, #2ecc71) 84%, #111827);
}
#commentRoot[data-cmh-mode="deck"] .slide pre:not(.mermaid),
#commentRoot[data-cmh-mode="deck"] .slide pre:not(.mermaid) code,
#commentRoot[data-cmh-mode="deck"] .slide figure.cmh-kql,
#commentRoot[data-cmh-mode="deck"] .slide figure.cmh-kql pre,
#commentRoot[data-cmh-mode="deck"] .slide figure.cmh-kql code {
  color: var(--cmh-deck-code-text);
}
#commentRoot[data-cmh-mode="deck"] .slide pre:not(.mermaid),
#commentRoot[data-cmh-mode="deck"] .slide figure.cmh-kql,
#commentRoot[data-cmh-mode="deck"] .slide figure.cmh-kql pre {
  background: var(--cmh-deck-code-bg);
  border-color: var(--cmh-deck-code-border);
}
#commentRoot[data-cmh-mode="deck"] .slide figure.cmh-kql .cmh-kql-cap,
#commentRoot[data-cmh-mode="deck"] .slide .cmh-code-wrap > .cmh-code-caption,
#commentRoot[data-cmh-mode="deck"] .slide .cmh-diff-bar,
#commentRoot[data-cmh-mode="deck"] .slide .cmh-diff-toobig {
  background: var(--cmh-deck-code-bg-soft);
  border-color: var(--cmh-deck-code-border);
  color: var(--cmh-deck-code-muted);
}
#commentRoot[data-cmh-mode="deck"] .slide figure.cmh-kql .cmh-kql-title,
#commentRoot[data-cmh-mode="deck"] .slide .cmh-diff-label {
  color: var(--cmh-deck-code-text);
}
#commentRoot[data-cmh-mode="deck"] .slide figure.cmh-kql .cmh-kql-run {
  color: var(--cmh-deck-code-text);
}
#commentRoot[data-cmh-mode="deck"] .slide figure.cmh-kql .cmh-kql-run:hover {
  color: var(--cmh-deck-code-link-hover-fg, #dbeafe);
}
#commentRoot[data-cmh-mode="deck"] .slide .cmh-code-kw,
#commentRoot[data-cmh-mode="deck"] .slide .cmh-kql-kw { color: var(--cmh-deck-tok-kw, #d8b4fe); }
#commentRoot[data-cmh-mode="deck"] .slide .cmh-code-fn,
#commentRoot[data-cmh-mode="deck"] .slide .cmh-kql-fn { color: var(--cmh-deck-tok-fn, #93c5fd); }
#commentRoot[data-cmh-mode="deck"] .slide .cmh-code-key { color: var(--cmh-deck-tok-key, var(--cmh-deck-tok-fn, #93c5fd)); }
#commentRoot[data-cmh-mode="deck"] .slide .cmh-code-str,
#commentRoot[data-cmh-mode="deck"] .slide .cmh-kql-str { color: var(--cmh-deck-tok-str, #86efac); }
#commentRoot[data-cmh-mode="deck"] .slide .cmh-code-num,
#commentRoot[data-cmh-mode="deck"] .slide .cmh-kql-num { color: var(--cmh-deck-tok-num, #fbbf24); }
#commentRoot[data-cmh-mode="deck"] .slide .cmh-code-com,
#commentRoot[data-cmh-mode="deck"] .slide .cmh-kql-com { color: var(--cmh-deck-tok-com, #94a3b8); }
#commentRoot[data-cmh-mode="deck"] .slide .cmh-code-op,
#commentRoot[data-cmh-mode="deck"] .slide .cmh-kql-op { color: var(--cmh-deck-tok-op, #cbd5e1); }
#commentRoot[data-cmh-mode="deck"] .slide .cmh-code-wrap .cmh-code-lined > .cmh-code-gutter > .cmh-code-line::before,
#commentRoot[data-cmh-mode="deck"] .slide figure.cmh-kql .cmh-code-wrap code.cmh-code-lined > .cmh-code-gutter > .cmh-code-line.cmh-kql-line::before {
  color: var(--cmh-deck-code-soft);
}
#commentRoot[data-cmh-mode="deck"] .slide .cm-code-lang,
#commentRoot[data-cmh-mode="deck"] .slide .cm-code-copy {
  background: var(--cmh-deck-code-badge-bg, rgba(15, 23, 42, 0.88));
  border-color: var(--cmh-deck-code-border);
  color: var(--cmh-deck-code-text);
}
#commentRoot[data-cmh-mode="deck"] .slide .cm-code-copy:hover {
  border-color: #93c5fd;
  color: #bfdbfe;
}
#commentRoot[data-cmh-mode="deck"] .slide .cmh-diff-view,
#commentRoot[data-cmh-mode="deck"] .slide .cmh-diff-body,
#commentRoot[data-cmh-mode="deck"] .slide .cmh-diff-view pre,
#commentRoot[data-cmh-mode="deck"] .slide .cmh-diff-view code,
#commentRoot[data-cmh-mode="deck"] .slide .cmh-diff-view span:not([class*="cmh-code-"]):not([class*="cmh-kql-"]),
#commentRoot[data-cmh-mode="deck"] .slide .cmh-diff-view button {
  color: var(--cmh-deck-code-text);
}
#commentRoot[data-cmh-mode="deck"] .slide .cmh-diff-view,
#commentRoot[data-cmh-mode="deck"] .slide .cmh-diff-toggle,
#commentRoot[data-cmh-mode="deck"] .slide .cmh-diff-hltoggle {
  background: var(--cmh-deck-code-bg);
  border-color: var(--cmh-deck-code-border);
}
#commentRoot[data-cmh-mode="deck"] .slide .cmh-dl-gutter,
#commentRoot[data-cmh-mode="deck"] .slide .cmh-dl-sign,
#commentRoot[data-cmh-mode="deck"] .slide .cmh-dl-file {
  color: var(--cmh-deck-code-soft);
}
#commentRoot[data-cmh-mode="deck"] .slide .cmh-dl-full,
#commentRoot[data-cmh-mode="deck"] .slide .cmh-dl-spacer {
  background: var(--cmh-deck-code-bg-soft);
  color: var(--cmh-deck-code-muted);
}
#commentRoot[data-cmh-mode="deck"] .slide .cmh-dl-hunk {
  background: rgba(96, 165, 250, 0.16);
  color: var(--cmh-deck-diff-hunk-fg, #bfdbfe);
}
#commentRoot[data-cmh-mode="deck"] .slide .cmh-dl-add {
  background: rgba(34, 197, 94, 0.20);
}
#commentRoot[data-cmh-mode="deck"] .slide .cmh-dl-add .cmh-dl-sign {
  color: var(--cmh-deck-diff-add-fg, #86efac);
}
#commentRoot[data-cmh-mode="deck"] .slide .cmh-dl-del {
  background: rgba(248, 113, 113, 0.22);
}
#commentRoot[data-cmh-mode="deck"] .slide .cmh-dl-del .cmh-dl-sign {
  color: var(--cmh-deck-diff-del-fg, #fca5a5);
}
#commentRoot[data-cmh-mode="deck"] .slide .cmh-dl-add:hover,
#commentRoot[data-cmh-mode="deck"] .slide .cmh-dl-del:hover,
#commentRoot[data-cmh-mode="deck"] .slide .cmh-dl-ctx:hover {
  filter: brightness(1.12);
}
#commentRoot[data-cmh-mode="deck"] .slide .cm-mermaid-host svg .node rect,
#commentRoot[data-cmh-mode="deck"] .slide .cm-mermaid-host svg .node polygon,
#commentRoot[data-cmh-mode="deck"] .slide .cm-mermaid-host svg .node circle,
#commentRoot[data-cmh-mode="deck"] .slide .cm-mermaid-host svg .node ellipse {
  fill: var(--cmh-deck-mermaid-node-fill, #1e293b) !important;
  stroke: var(--cmh-deck-mermaid-node-stroke, #93c5fd) !important;
}
#commentRoot[data-cmh-mode="deck"] .slide .cm-mermaid-host svg .cluster rect,
#commentRoot[data-cmh-mode="deck"] .slide .cm-mermaid-host svg .cluster polygon {
  fill: var(--cmh-deck-mermaid-cluster-fill, rgba(30, 41, 59, 0.78)) !important;
  stroke: var(--cmh-deck-mermaid-cluster-stroke, rgba(147, 197, 253, 0.7)) !important;
}
#commentRoot[data-cmh-mode="deck"] .slide .cm-mermaid-host svg :where(.nodeLabel, .label, text, foreignObject, foreignObject *) {
  color: var(--cmh-deck-mermaid-label, #f8fafc) !important;
  fill: var(--cmh-deck-mermaid-label, #f8fafc) !important;
}
#commentRoot[data-cmh-mode="deck"] .slide .cm-mermaid-host svg :where(.edgePath path, .flowchart-link, path.flowchart-link) {
  stroke: var(--cmh-deck-mermaid-edge, #334155) !important;
  stroke-width: 2.4px !important;
  /* Edges are strokes, not shapes: force fill:none so a curved connector (a back-edge) is drawn
     as a thin line and never fills the area under its curve with the inherited dark slide color
     (which rendered as solid black blobs). Arrowheads keep their own fill in the marker rule below. */
  fill: none !important;
}
#commentRoot[data-cmh-mode="deck"] .slide .cm-mermaid-host svg marker path {
  stroke: var(--cmh-deck-mermaid-edge, #334155) !important;
  fill: var(--cmh-deck-mermaid-edge, #334155) !important;
}
#commentRoot[data-cmh-mode="deck"] .slide .cm-mermaid-host svg .edgeLabel,
#commentRoot[data-cmh-mode="deck"] .slide .cm-mermaid-host svg .edgeLabel p {
  background: var(--cmh-deck-mermaid-edge-label-bg, #111827) !important;
  color: var(--cmh-deck-mermaid-edge-label-fg, #f8fafc) !important;
}
/* In comment mode on a wide screen, narrow the stage so the OPEN sidebar does not overlap it
   (the deck runtime refits the stage to the reduced viewport width via a ResizeObserver), and
   shift the centered nav bar left by half the sidebar width so it stays centered on the stage.
   Gated on the sidebar being open: when the panel is hidden the stage spans the full width again
   (no reserved black bar), and the toggle - hidden while the panel is open - needs no reposition. */
@media (min-width: 900px) {
  body.sidebar-open #commentRoot.cmh-deck-comment-mode .deck-viewport {
    right: 400px;
  }
  body.sidebar-open:has(#commentRoot.cmh-deck-comment-mode) .cmh-deck-nav {
    left: calc(50% - 200px);
  }
}
#commentRoot.cmh-deck-comment-mode .slide .reveal,
#commentRoot.cmh-deck-comment-mode .slide [class*="reveal"] {
  opacity: 1 !important;
  visibility: visible !important;
  transform: none !important;
}
.cmh-deck-mode-ctl {
  position: fixed;
  top: 14px;
  right: 14px;
  z-index: 100001;
}
.cmh-deck-mode-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  height: 42px;
  padding: 0 8px;
  border-radius: 8px;
  border: 1px solid var(--cp-border, #444);
  /* Keep a stable surface background in EVERY state so the brand icon stays legible - the old
     accent-filled "on" state hid the accent-coloured bubble against an accent background. */
  background: var(--cp-surface, #222);
  color: var(--cp-text, #fff);
  font: inherit;
  cursor: pointer;
  /* Lift the chrome off arbitrary slide backgrounds so it stays legible over any slide colour. */
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
}
.cmh-deck-mode-toggle:hover,
.cmh-deck-mode-toggle[aria-expanded="true"] {
  border-color: var(--cp-accent, #2ecc71);
  background: var(--cp-surface-soft, #333);
}
.cmh-deck-mode-toggle .cm-brand-icon {
  width: 20px;
  height: 20px;
  margin: 0;
}
/* A small down caret signals the button opens a menu (not a bare toggle). */
.cmh-deck-mode-toggle .cmh-deck-mode-caret {
  width: 0;
  height: 0;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 5px solid currentColor;
  opacity: 0.75;
}
/* A subtle accent dot marks the panel-open state without recolouring the whole button. */
.cmh-deck-mode-toggle.cmh-deck-pane-open {
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4), 0 0 0 2px var(--cp-accent, #2ecc71);
}
.cmh-deck-mode-menu {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  min-width: 220px;
  display: flex;
  flex-direction: column;
  padding: 6px;
  border-radius: 10px;
  border: 1px solid var(--cp-border, #444);
  background: var(--cp-surface, #222);
  box-shadow: 0 10px 26px rgba(0, 0, 0, 0.42);
}
.cmh-deck-mode-menu[hidden] {
  display: none !important;
}
.cmh-deck-mode-item {
  display: block;
  width: 100%;
  padding: 9px 12px;
  border: none;
  border-radius: 7px;
  background: transparent;
  color: var(--cp-text, #fff);
  font: inherit;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}
.cmh-deck-mode-item:hover,
.cmh-deck-mode-item:focus-visible {
  background: var(--cp-surface-soft, #333);
  outline: none;
}
.cmh-deck-mode-item[disabled],
.cmh-deck-mode-item[aria-disabled="true"] {
  opacity: 0.45;
  cursor: not-allowed;
}
.cmh-deck-mode-radio[aria-checked="true"]::before {
  content: "\2713\00a0";
  color: var(--cp-accent, #2ecc71);
  font-weight: 700;
}
.cmh-deck-mode-sep {
  display: block;
  height: 1px;
  margin: 5px 8px;
  background: var(--cp-border, #444);
}
.cmh-deck-mode-site::after {
  content: "\2197";
  margin-left: 6px;
  opacity: 0.7;
}
#commentRoot[data-cmh-mode="deck"] .deck-viewport:focus {
  outline: none;
}
.cmh-deck-nav {
  position: fixed;
  bottom: 16px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 100001;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 10px;
  border-radius: 999px;
  background: var(--cp-surface, #222);
  border: 1px solid var(--cp-border, #444);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
}
.cmh-deck-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 6px 14px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--cp-accent, #2ecc71) 16%, var(--cp-surface-soft, #333));
  border: 1px solid color-mix(in srgb, var(--cp-accent, #2ecc71) 34%, var(--cp-border, #444));
  color: var(--cp-text, #fff);
  font: inherit;
  min-width: 56px;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.cmh-deck-nav .cmh-deck-overview-button {
  background: color-mix(in srgb, var(--cp-accent, #2ecc71) 22%, var(--cp-surface-soft, #333));
  border-color: color-mix(in srgb, var(--cp-accent, #2ecc71) 40%, var(--cp-border, #444));
}
.cmh-deck-nav button {
  padding: 6px 12px;
  border-radius: 999px;
  border: 1px solid var(--cp-border, #444);
  background: var(--cp-surface-soft, #333);
  color: var(--cp-text, #fff);
  font: inherit;
  cursor: pointer;
}
.cmh-deck-nav button:disabled {
  opacity: 0.9;
  color: var(--cp-text-soft, #55606b);
  cursor: default;
}
.cmh-deck-nav button.cmh-deck-overview-on {
  border-color: var(--cp-accent, #2ecc71);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--cp-accent, #2ecc71) 35%, transparent);
}
.cmh-deck-edge-nav {
  position: fixed;
  z-index: 100001;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  padding: 0;
  border-radius: 999px;
  border: 1px solid var(--cp-border, #444);
  background: color-mix(in srgb, var(--cp-surface, #222) 84%, transparent);
  color: var(--cp-text, #fff);
  font: inherit;
  font-size: 26px;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.32);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: translateY(-50%) scale(0.96);
  transition: opacity 0.18s ease, transform 0.18s ease, visibility 0.18s linear;
}
.cmh-deck-edge-nav.is-active {
  opacity: var(--cmh-deck-edge-opacity, 0.72);
  visibility: visible;
  pointer-events: auto;
  transform: translateY(-50%) scale(1);
}
.cmh-deck-edge-nav:hover,
.cmh-deck-edge-nav:focus-visible {
  opacity: 1;
  border-color: var(--cp-accent, #2ecc71);
  outline: none;
}
.cmh-deck-edge-nav:disabled,
body.cmh-deck-overview-open .cmh-deck-edge-nav,
body:has(#commentRoot.cmh-deck-comment-mode) .cmh-deck-edge-nav {
  opacity: 0 !important;
  visibility: hidden !important;
  pointer-events: none !important;
}
.cmh-deck-overview {
  position: fixed;
  inset: 0 auto 0 0;
  z-index: 100002;
  display: flex;
  flex-direction: column;
  width: min(760px, 48vw);
  min-width: min(100vw, 320px);
  padding: 20px;
  gap: 16px;
  color: var(--cp-text, #fff);
  background: color-mix(in srgb, var(--cp-accent, #b11f4b) 12%, var(--cp-surface, #fff));
  border-right: 1px solid var(--cp-border, #444);
  box-shadow: 12px 0 28px rgba(0, 0, 0, 0.38);
  overflow: hidden;
}
.cmh-deck-overview[hidden] {
  display: none !important;
}
.cmh-deck-overview-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.cmh-deck-overview-title {
  margin: 0;
  font: inherit;
  font-size: 18px;
  font-weight: 700;
}
.cmh-deck-overview-titlewrap {
  display: flex;
  align-items: baseline;
  gap: 10px;
  min-width: 0;
}
.cmh-deck-overview-count {
  font: inherit;
  font-size: 13px;
  color: var(--cp-text-soft, #64748b);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.cmh-deck-overview-card {
  border: 1px solid var(--cp-border, #444);
  background: var(--cp-surface-soft, #333);
  color: var(--cp-text, #fff);
  font: inherit;
  cursor: pointer;
}
.cmh-deck-overview-close {
  padding: 6px 12px;
  border-radius: 999px;
  border: 1px solid var(--cp-accent, #b11f4b);
  background: var(--cp-accent, #b11f4b);
  color: var(--cp-accent-fg, #fff);
  font: inherit;
  cursor: pointer;
}
.cmh-deck-overview-close:hover {
  background: var(--cp-accent-hover, #8f1a3d);
  border-color: var(--cp-accent-hover, #8f1a3d);
}
.cmh-deck-overview-searchwrap {
  flex: none;
}
.cmh-deck-overview-search {
  width: 100%;
  box-sizing: border-box;
  padding: 9px 12px;
  border-radius: 8px;
  border: 1px solid var(--cp-border, #444);
  background: var(--cp-surface, #fff);
  color: var(--cp-text, #fff);
  font: inherit;
  font-size: 15px;
}
.cmh-deck-overview-search::placeholder {
  color: var(--cp-text-soft, #64748b);
}
.cmh-deck-overview-search:focus-visible {
  outline: none;
  border-color: var(--cp-accent, #b11f4b);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--cp-accent, #b11f4b) 35%, transparent);
}
.cmh-deck-overview-card[hidden] {
  display: none !important;
}
.cmh-deck-overview-grid {
  display: flex;
  flex-direction: column;
  gap: 8px;
  flex: 1 1 auto;
  min-height: 0;
  overflow: auto;
  padding: 2px 2px 10px;
}
.cmh-deck-overview-card {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  border-radius: 10px;
  text-align: left;
  font-size: 16px;
}
.cmh-deck-overview-card:hover,
.cmh-deck-overview-card:focus-visible {
  border-color: var(--cp-accent, #2ecc71);
  outline: none;
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--cp-accent, #2ecc71) 35%, transparent);
}
.cmh-deck-overview-card[aria-current="true"] {
  border-color: var(--cp-accent, #2ecc71);
  background: color-mix(in srgb, var(--cp-accent, #2ecc71) 12%, var(--cp-surface-soft, #333));
}
.cmh-deck-overview-card-num {
  flex: none;
  min-width: 2.2em;
  padding: 2px 8px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--cp-accent, #b11f4b) 18%, var(--cp-surface-soft, #333));
  color: var(--cp-text, #fff);
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  text-align: center;
}
.cmh-deck-overview-card-label {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
@media (max-width: 640px) {
  .cmh-deck-nav button {
    padding: 11px 16px;
    min-height: 44px;
  }
  .cmh-deck-mode-toggle {
    height: 44px;
    min-height: 44px;
  }
  .cmh-deck-mode-item {
    padding: 12px 14px;
    min-height: 44px;
  }
  .cmh-deck-overview {
    width: 100vw;
  }
}
/* On a narrow screen the sidebar opens as a near-full-width overlay, so the fixed nav bar (high
   z-index) would float on top of it. Hide it only while the sidebar is actually open in comment
   mode; hiding the sidebar brings it back so navigating stays reachable. (The comment-mode toggle
   is already hidden at every width while the panel is open, above.) */
@media (max-width: 899px) {
  body.sidebar-open:has(#commentRoot.cmh-deck-comment-mode) .cmh-deck-nav {
    display: none;
  }
}

/* Layer-2 slide recipes: reusable, theme-coloured archetype classes the agent composes so a themed
   deck needs no per-deck CSS. Each recipe consumes the deck theme tokens (--slide-accent,
   --slide-fg-muted, --slide-border, --slide-accent-fg) with generic-dark defaults, so the classes
   are coherent on an unthemed deck and recolour automatically under any preset. Content budgets are
   documented in references/deck-contract.md. */
#commentRoot[data-cmh-mode="deck"] .slide .cmh-slide-lede {
  color: var(--slide-fg-muted, #a1a1aa);
  font-size: 34px;
  line-height: 1.4;
  max-width: 26ch;
}
/* Stable header baseline (general deck rule): reserve a consistent title band so a slide's
   subtitle and body start at the same vertical position no matter how many lines the title (h2)
   wraps to, and the header does not visibly jump when navigating between slides. Content slides
   top-align by default (see viewport-base.css / the scaffolded per-deck padding), so the title
   itself already starts at a stable Y; the centred section-divider recipe (.cmh-slide-section)
   opts out. The band is sized in em so it scales with any deck's title font size, and it is a
   min-height (not a fixed height) so a rare longer title still grows rather than clip. */
#commentRoot[data-cmh-mode="deck"] .slide:not(.cmh-slide-section) > h2 {
  min-height: 2.8em;
}
/* A subtitle/lede placed immediately under the title takes its top spacing from the title's own
   margin-bottom, not from its own margin-top, so its rendered top is exactly the (stable) title-band
   bottom on every slide - it cannot drift with a per-slide lede margin. (Flex-column items do not
   collapse margins, so a stray lede margin-top would otherwise offset the subtitle baseline even
   though the title band is stable.) */
#commentRoot[data-cmh-mode="deck"] .slide:not(.cmh-slide-section) > h2 + .cmh-slide-lede {
  margin-top: 0;
}
#commentRoot[data-cmh-mode="deck"] .slide.cmh-slide-section {
  display: flex;
  flex-direction: column;
  justify-content: center;
}
#commentRoot[data-cmh-mode="deck"] .slide.cmh-slide-section .cmh-slide-kicker {
  color: var(--slide-accent, #93c5fd);
  font-size: 30px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  margin: 0 0 0.3em;
}
#commentRoot[data-cmh-mode="deck"] .slide.cmh-slide-section::before {
  content: "";
  display: block;
  width: 120px;
  height: 8px;
  margin-bottom: 28px;
  border-radius: 999px;
  background: var(--slide-accent, #93c5fd);
}
/* A full-content slide laid out as a flex column, so a trailing margin-top:auto child (for
   example the .cmh-refs reference row) pins to the bottom of the fixed 1080px slide box. Unlike
   .cmh-slide-section (a centred kicker/heading divider) this stacks normal slide content from the
   top and reserves the remaining height for the auto-margin child. */
#commentRoot[data-cmh-mode="deck"] .slide.cmh-slide-flow {
  display: flex;
  flex-direction: column;
}
#commentRoot[data-cmh-mode="deck"] .slide .cmh-cols-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 48px;
  align-items: start;
}
#commentRoot[data-cmh-mode="deck"] .slide .cmh-metric-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 28px;
}
#commentRoot[data-cmh-mode="deck"] .slide .cmh-metric {
  padding: 28px 32px;
  border: 1px solid var(--slide-border, rgba(255, 255, 255, 0.22));
  border-radius: 16px;
  background: var(--slide-bg, transparent);
  transition: transform 0.16s ease, border-color 0.16s ease;
}
#commentRoot[data-cmh-mode="deck"] .slide .cmh-metric:hover {
  transform: translateY(-4px);
  box-shadow: 0 12px 28px rgba(15, 23, 42, 0.16);
  border-color: var(--slide-accent, #93c5fd);
}
#commentRoot[data-cmh-mode="deck"] .slide .cmh-metric > .cmh-metric-value {
  display: block;
  color: var(--slide-accent, #93c5fd);
  font-size: 44px;
  font-weight: 800;
  line-height: 1.1;
  overflow-wrap: break-word;
}
#commentRoot[data-cmh-mode="deck"] .slide .cmh-metric > .cmh-metric-label {
  display: block;
  color: var(--slide-fg-muted, #a1a1aa);
  font-size: 24px;
  margin-top: 8px;
}
#commentRoot[data-cmh-mode="deck"] .slide .cmh-pill {
  display: inline-block;
  padding: 6px 18px;
  border-radius: 999px;
  background: var(--slide-accent, #93c5fd);
  color: var(--slide-accent-fg, #0b0b0f);
  font-weight: 700;
  letter-spacing: 0.02em;
  /* Hover-lift: animate only the cheap transform (not box-shadow, and not a brightness filter that
     could push a custom theme's pill fill below its AA text contrast) so the deck hover stays smooth
     and every themed pill keeps its vetted contrast. */
  transition: transform 0.15s ease;
}
#commentRoot[data-cmh-mode="deck"] .slide .cmh-pill:hover {
  transform: translateY(-2px);
}
/* Reusable status-pill variants: green Available, amber WIP, slate Planned (white text, AA-safe). */
#commentRoot[data-cmh-mode="deck"] .slide .cmh-pill.is-available { background: #1a7f37; color: #ffffff; }
#commentRoot[data-cmh-mode="deck"] .slide .cmh-pill.is-wip { background: #8a5200; color: #ffffff; }
#commentRoot[data-cmh-mode="deck"] .slide .cmh-pill.is-planned { background: #57606a; color: #ffffff; }
/* Generous spacing between deck paragraphs and bullets (prefer bullets over prose). */
#commentRoot[data-cmh-mode="deck"] .slide p { margin: 0 0 0.75em; }
#commentRoot[data-cmh-mode="deck"] .slide ul,
#commentRoot[data-cmh-mode="deck"] .slide ol { margin: 0.2em 0 0.75em; padding-left: 1.1em; line-height: 1.5; }
#commentRoot[data-cmh-mode="deck"] .slide li { margin-bottom: 0.5em; }
/* Consistent reference row: pills pinned to the bottom of the slide, laid out horizontally. */
#commentRoot[data-cmh-mode="deck"] .slide .cmh-refs {
  margin-top: auto;
  padding-top: 20px;
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
  font-size: 19px;
}
#commentRoot[data-cmh-mode="deck"] .slide .cmh-refs > .cmh-refs-label { color: var(--slide-fg-muted, #a1a1aa); font-weight: 600; }
#commentRoot[data-cmh-mode="deck"] .slide .cmh-refs a {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 15px;
  border-radius: 999px;
  background: var(--cmh-deck-code-bg, rgba(148, 163, 184, 0.16));
  border: 1px solid var(--slide-border, rgba(148, 163, 184, 0.4));
  color: var(--slide-link, #2f81f7);
  text-decoration: none;
  transition: transform 0.14s ease, border-color 0.14s ease;
}
#commentRoot[data-cmh-mode="deck"] .slide .cmh-refs a:hover {
  transform: translateY(-2px);
  border-color: var(--slide-accent, #93c5fd);
  box-shadow: 0 6px 16px rgba(15, 23, 42, 0.14);
}

/* Sortable-table chevrons on a deck header: the base chevron colours (muted text / accent) are
   invisible on a solid coloured (e.g. raspberry) deck header, so tint them with the header
   foreground so the sort affordance stays legible in both directions. */
#commentRoot[data-cmh-mode="deck"] .slide table thead th .cmh-sort-ctrl {
  color: var(--cmh-deck-table-head-fg, #f8fafc);
}
#commentRoot[data-cmh-mode="deck"] .slide table thead th .cmh-sort-ctrl .cmh-sort-up,
#commentRoot[data-cmh-mode="deck"] .slide table thead th .cmh-sort-ctrl .cmh-sort-dn {
  color: var(--cmh-deck-table-head-fg, #f8fafc);
  opacity: 0.5;
}
#commentRoot[data-cmh-mode="deck"] .slide table thead th .cmh-sort-ctrl:hover .cmh-sort-up,
#commentRoot[data-cmh-mode="deck"] .slide table thead th .cmh-sort-ctrl:hover .cmh-sort-dn {
  opacity: 0.82;
}
#commentRoot[data-cmh-mode="deck"] .slide table thead th .cmh-sort-ctrl[data-dir="asc"] .cmh-sort-up,
#commentRoot[data-cmh-mode="deck"] .slide table thead th .cmh-sort-ctrl[data-dir="desc"] .cmh-sort-dn {
  color: var(--cmh-deck-table-head-fg, #f8fafc);
  opacity: 1;
}

/* Mermaid diagrams on a deck slide should fill the available slide width instead of rendering at
   their small intrinsic size and leaving most of the slide empty. Scaling to 100% width lets the
   SVG's own viewBox grow the nodes/labels to a readable deck size. */
#commentRoot[data-cmh-mode="deck"] .slide .cm-mermaid-host {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
}
#commentRoot[data-cmh-mode="deck"] .slide .cm-mermaid-host > svg {
  width: 100%;
  height: auto;
  /* Mermaid stamps an inline max-width (its intrinsic px size) on the rendered SVG, which would
     otherwise cap it far below the slide width; override it so the diagram fills the slide. */
  max-width: none !important;
}
/* CMH-DECK-35: a diagram-dominant slide - the author opt-in .cmh-slide-diagram, or the runtime
   auto-detected .cmh-deck-diagram-slide (a slide whose only non-text content is one diagram) -
   lays out as a flex column so the diagram fills the remaining slide HEIGHT as well as the width.
   fitDeckDiagram() then sizes the SVG to contain-fit within the grown host (both dimensions); the
   width:auto/height:auto + max-*:100% here is the pre-JS / no-JS fallback so the diagram is bounded
   and never overflows the slide before sizing runs. */
#commentRoot[data-cmh-mode="deck"] .slide.cmh-slide-diagram,
#commentRoot[data-cmh-mode="deck"] .slide.cmh-deck-diagram-slide {
  display: flex;
  flex-direction: column;
}
/* Un-confine a lone diagram from a half column: flatten ONLY the .cmh-cols-2 that actually holds the
   diagram (:has) into the slide's flex column so its columns stack in DOM order, and let the column
   holding the diagram grow, so the diagram uses the full slide width instead of a half-width column.
   A sibling text-only .cmh-cols-2 on the same slide keeps its two-column layout. */
#commentRoot[data-cmh-mode="deck"] .slide.cmh-slide-diagram .cmh-cols-2:has(.cm-mermaid-host),
#commentRoot[data-cmh-mode="deck"] .slide.cmh-deck-diagram-slide .cmh-cols-2:has(.cm-mermaid-host) {
  display: contents;
}
/* Propagate the flex context through EVERY ancestor wrapper of the diagram (a column of the flattened
   grid, or one or more plain wrappers around the diagram - matched at any depth, not just a direct
   child) so the host is always a flex-grown item and its measured height is space-driven. That keeps
   the diagram correctly bounded BELOW a trailing block (for example a .cmh-refs row) instead of
   painting over it, and lets fitDeckDiagram read a true available box. flex:1 1 0% (equal share from a
   zero basis) also keeps sizing stable when fitDeckDiagram momentarily collapses one SVG to measure
   it, so two diagrams on a forced .cmh-slide-diagram slide never steal each other's space. The
   flattened .cmh-cols-2 itself is excluded so it keeps display:contents. */
#commentRoot[data-cmh-mode="deck"] .slide.cmh-slide-diagram *:has(.cm-mermaid-host):not(.cmh-cols-2),
#commentRoot[data-cmh-mode="deck"] .slide.cmh-deck-diagram-slide *:has(.cm-mermaid-host):not(.cmh-cols-2) {
  display: flex;
  flex-direction: column;
  flex: 1 1 0%;
  min-height: 0;
}
#commentRoot[data-cmh-mode="deck"] .slide.cmh-slide-diagram .cm-mermaid-host,
#commentRoot[data-cmh-mode="deck"] .slide.cmh-deck-diagram-slide .cm-mermaid-host {
  flex: 1 1 0%;
  min-height: 0;
}
#commentRoot[data-cmh-mode="deck"] .slide.cmh-slide-diagram .cm-mermaid-host > svg,
#commentRoot[data-cmh-mode="deck"] .slide.cmh-deck-diagram-slide .cm-mermaid-host > svg {
  width: auto;
  height: auto;
  max-width: 100% !important;
  max-height: 100%;
}
.cmh-print-comments,
.cmh-print-noscript {
  display: none;
}

@media print {
  @page {
    margin: 0.6in;
  }

  /* Deck slides print full-bleed on their own landscape 16:9 page at the native 1920x1080
     stage size, so a fixed-size slide is never clipped by a portrait paper page. Printing
     does not need to be A4/Letter - one slide fills exactly one page. */
  @page cmh-deck-slide {
    size: 1920px 1080px;
    margin: 0;
  }

  :root,
  html[data-theme="dark"] {
    /* Print on light paper regardless of the on-screen theme: reset the palette AND the
       color-scheme. Without the color-scheme reset a dark-theme document keeps color-scheme:dark,
       so the browser paints the page canvas/backdrop (the @page margin area behind the content)
       dark even though the body background is reset to white - producing heavy dark margins in the
       PDF. */
    color-scheme: light;
    --cp-bg: #fff;
    --cp-bg-elevated: #fff;
    --cp-surface: #fff;
    --cp-surface-soft: #f8fafc;
    --cp-panel-strong: #fff;
    --cp-border: #cbd5e1;
    --cp-text: #111827;
    --cp-text-soft: #374151;
    --cp-text-muted: #4b5563;
    --cp-link: #1d4ed8;
    --cp-accent: #1d4ed8;
    --cp-accent-hover: #1e40af;
    --cp-accent-soft: #eff6ff;
    --cp-accent-fg: #fff;
    --cp-warning: #92400e;
    --cp-warning-soft: #fffbeb;
    --cp-danger: #991b1b;
    --cp-danger-soft: #fef2f2;
    --cp-success: #166534;
    --cp-success-soft: #f0fdf4;
    --cp-shadow: none;
  }

  *,
  *::before,
  *::after {
    box-shadow: none !important;
    text-shadow: none !important;
    filter: none !important;
  }

  html,
  body {
    background: var(--cp-bg) !important;
    color: var(--cp-text) !important;
    margin: 0 !important;
    padding: 0 !important;
    overflow: visible !important;
    -webkit-print-color-adjust: economy;
    print-color-adjust: economy;
  }

  /* Strip the trailing bottom margin from the final flow element. A residual margin below the
     last content (for example a section's margin-bottom) otherwise counts toward the document
     height and can spill onto an extra, near-blank page whenever the content height lands just
     under a page boundary. */
  #commentRoot > *:last-child,
  main > *:last-child,
  .app > main:last-child {
    margin-bottom: 0 !important;
  }

  body,
  .app,
  body.sidebar-open .app,
  body.cm-side-toc-on .app,
  body.cm-has-footer .app {
    max-width: none !important;
    width: auto !important;
    margin: 0 !important;
    padding: 0 !important;
    background: var(--cp-bg) !important;
    color: var(--cp-text) !important;
    overflow: visible !important;
  }

  body > .cm-skip,
  .cm-toolbar,
  .cm-sidebar,
  .cm-sidebar-resize,
  .cm-side-toc,
  .cm-scroll-progress,
  .cm-footer,
  .cm-menu,
  .cm-composer,
  .cm-comment-popover,
  .cm-tooltip,
  .mermaidTooltip,
  .cm-toast,
  .cm-modal-overlay,
  .cm-mermaid-add,
  .cm-diff-add,
  .cm-image-add,
  .cm-widget-add,
  .cm-hl-bubble,
  #commentRoot .cmh-sec-caret,
  #commentRoot .cmh-review-badge,
  #commentRoot .cmh-sort-ctrl,
  #commentRoot .cm-widget-reset,
  .cm-code-copy,
  #commentRoot [data-cmh-copy],
  #commentRoot [data-cmh-check-btn],
  #commentRoot [data-cmh-note-toggle],
  #commentRoot [data-cmh-note-fold] {
    display: none !important;
  }

  #commentRoot,
  #commentRoot * {
    overflow: visible !important;
  }

  #commentRoot {
    background: var(--cp-bg) !important;
    color: var(--cp-text) !important;
  }

  /* The composing preview highlight is transient chrome: print the underlying text
     plainly rather than with the provisional amber fill and dashed outline. */
  mark.cm-preview {
    background: transparent !important;
    box-shadow: none !important;
    outline: none !important;
    padding: 0 !important;
  }

  #commentRoot section.cmh-section-collapsed > * {
    display: revert !important;
  }

  #commentRoot .cmh-note.cmh-note-collapsed .cmh-note-input,
  #commentRoot .cmh-note.cmh-note-collapsed .cmh-note-head {
    display: revert !important;
  }

  #commentRoot section.cmh-section-collapsed > .cm-code-copy,
  #commentRoot section.cmh-section-collapsed > [data-cmh-copy],
  #commentRoot section.cmh-section-collapsed > [data-cmh-check-btn],
  #commentRoot section.cmh-section-collapsed > [data-cmh-note-toggle],
  #commentRoot section.cmh-section-collapsed > [data-cmh-note-fold] {
    display: none !important;
  }

  #commentRoot > section,
  #commentRoot .cmh-lede,
  #commentRoot .cm-toc,
  #commentRoot .cmh-callout,
  #commentRoot:not([data-cmh-mode="deck"]) figure.cmh-kql,
  #commentRoot:not([data-cmh-mode="deck"]) .cmh-diff-view,
  .cmh-print-comments,
  .cmh-print-noscript {
    background: var(--cp-surface) !important;
    color: var(--cp-text) !important;
    border-color: var(--cp-border) !important;
    box-shadow: none !important;
  }

  /* Keep breakable units whole, but let a whole SECTION (which can be taller than a page)
     flow across pages - forcing break-inside:avoid on a too-tall section made Chromium
     reserve a page for its box and push the real content to the next page, leaving a
     near-blank page with only the heading. Small units below still stay whole. */
  #commentRoot figure,
  #commentRoot pre,
  #commentRoot blockquote,
  #commentRoot table,
  #commentRoot .cmh-callout,
  #commentRoot [data-cm-widget] > *,
  .cmh-print-comment {
    break-inside: avoid;
    page-break-inside: avoid;
  }

  /* A heading stays with the content that follows it, so a section title never prints
     orphaned at the bottom of a page or alone on an otherwise-blank page. */
  #commentRoot h1,
  #commentRoot h2,
  #commentRoot h3,
  #commentRoot h4 {
    break-after: avoid;
    page-break-after: avoid;
    break-inside: avoid;
  }

  /* Widgets (kanban boards and other draggable part containers) block-stack for print, so
     their columns print full width one after another instead of relying on a grid/flex track
     layout that Chromium can fragment badly across a page break. Scoped away from decks, whose
     fixed-size slides keep their own grid/flex layout (see the deck rules below). */
  #commentRoot:not([data-cmh-mode="deck"]) [data-cm-widget] {
    display: block !important;
  }
  #commentRoot:not([data-cmh-mode="deck"]) [data-cm-widget] > * {
    width: auto !important;
    max-width: 100% !important;
  }

  /* Multi-column galleries stack into a single column for print, so their items flow across pages
     naturally. A CSS grid does not fragment across a page break, so a tall gallery would otherwise
     jump whole to the next page and strand its section heading alone on a near-blank page. Each
     item still stays whole (break-inside:avoid). Scoped away from decks. */
  #commentRoot:not([data-cmh-mode="deck"]) .visual-grid,
  #commentRoot:not([data-cmh-mode="deck"]) .cmh-diagram-gallery {
    display: block !important;
  }
  #commentRoot:not([data-cmh-mode="deck"]) .visual-grid > *,
  #commentRoot:not([data-cmh-mode="deck"]) .cmh-diagram-gallery > * {
    width: auto !important;
    max-width: 100% !important;
    margin-bottom: 0.75rem !important;
    break-inside: avoid;
    page-break-inside: avoid;
  }
  /* A .cmh-diagram-gallery card hugs its diagram at a fixed height on screen (framed, bounded); for
     print, drop the height bound and the frame so the whole diagram prints at natural size. Scoped to
     the diagram CONTAINERS (matching the screen card selector), so a stray non-card child is left alone,
     and to the diagram gallery ONLY - the chart .visual-grid keeps its figure frames in print. */
  #commentRoot:not([data-cmh-mode="deck"]) .cmh-diagram-gallery > pre.mermaid,
  #commentRoot:not([data-cmh-mode="deck"]) .cmh-diagram-gallery > div.mermaid,
  #commentRoot:not([data-cmh-mode="deck"]) .cmh-diagram-gallery > figure {
    display: block !important;
    height: auto !important;
    overflow: visible !important;
    border: 0 !important;
    padding: 0 !important;
    background: none !important;
  }

  #commentRoot pre,
  #commentRoot code,
  #commentRoot .cmh-diff-view pre,
  #commentRoot .cmh-diff-view code,
  #commentRoot figure.cmh-kql pre,
  #commentRoot figure.cmh-kql code {
    white-space: pre-wrap !important;
    overflow-wrap: anywhere !important;
    word-break: break-word !important;
  }

  /* Print re-lights syntax-highlight tokens to the LIGHT palette for FLAT (non-deck) documents
     regardless of the on-screen theme. A flat document's code/KQL/diff backgrounds are reset to the
     light paper surface in print, but the four tinted token colors (keyword/function/string/number)
     are hardcoded hex, and a dark-theme reader keeps `html[data-theme="dark"]` set when printing -
     so without this the dark-mode pastels (light green strings, etc.) would print near-invisibly on
     white. The comment/operator tokens already use the reset `--cp-*` variables. This is scoped away
     from decks (like the other report-only print rules): a deck keeps its own designed slide
     backgrounds and token palette in print (its KQL blocks stay on a dark slide background, where
     the bright deck tokens - not this dark palette - are the legible ones). */
  html[data-theme="dark"] #commentRoot:not([data-cmh-mode="deck"]) .cmh-kql-kw,
  html[data-theme="dark"] #commentRoot:not([data-cmh-mode="deck"]) .cmh-code-kw {
    color: #8250df !important;
  }
  html[data-theme="dark"] #commentRoot:not([data-cmh-mode="deck"]) .cmh-kql-fn,
  html[data-theme="dark"] #commentRoot:not([data-cmh-mode="deck"]) .cmh-code-fn {
    color: #0550ae !important;
  }
  html[data-theme="dark"] #commentRoot:not([data-cmh-mode="deck"]) .cmh-code-key {
    color: #0550ae !important;
  }
  html[data-theme="dark"] #commentRoot:not([data-cmh-mode="deck"]) .cmh-kql-str,
  html[data-theme="dark"] #commentRoot:not([data-cmh-mode="deck"]) .cmh-code-str {
    color: #0a7d33 !important;
  }
  html[data-theme="dark"] #commentRoot:not([data-cmh-mode="deck"]) .cmh-kql-num,
  html[data-theme="dark"] #commentRoot:not([data-cmh-mode="deck"]) .cmh-code-num {
    color: #953800 !important;
  }

  /* Paper cannot scroll, so the on-screen scroll box must not CLIP a wide table into a PDF: the
     wrapper goes back to `overflow: visible` and the `anywhere` rule below (which restores
     min-content squeezing) is what makes the table fit the sheet instead. */
  #commentRoot .cmh-table-scroll {
    overflow: visible !important;
  }

  #commentRoot table {
    display: table !important;
    width: 100% !important;
    max-width: 100% !important;
    table-layout: auto !important;
  }

  /* Long unbreakable cell text (an id, url, or token) wraps rather than forcing the table wider than
     the page, so on a driver that CANNOT grow the page (a non-honoring driver paginating onto fixed
     paper) a wide cell wraps instead of being clipped off the sheet edge. */
  #commentRoot td,
  #commentRoot th {
    overflow-wrap: anywhere !important;
    word-break: break-word !important;
  }

  #commentRoot img,
  #commentRoot svg,
  #commentRoot canvas {
    max-width: 100% !important;
    height: auto !important;
  }

  /* Cap tall media (mermaid diagrams, inline SVG figures, images) to the printable page height so a
     tall item scales to fit one page instead of overflowing, splitting across a page break, or
     leaving a near-empty trailing page. width:auto keeps the aspect ratio while it shrinks. Scoped
     away from decks, whose fixed 1080px slides intentionally fill the slide page. */
  #commentRoot:not([data-cmh-mode="deck"]) pre.mermaid svg,
  #commentRoot:not([data-cmh-mode="deck"]) figure svg,
  #commentRoot:not([data-cmh-mode="deck"]) figure img,
  #commentRoot:not([data-cmh-mode="deck"]) img {
    max-height: 8.4in !important;
    max-width: 100% !important;
    width: auto !important;
    height: auto !important;
  }

  a {
    color: var(--cp-link) !important;
  }

  .cmh-print-comments,
  .cmh-print-noscript {
    display: block !important;
    margin: 2rem 0 0 !important;
    padding: 1rem 0 0 !important;
    border-top: 2px solid var(--cp-border) !important;
    break-before: page;
    page-break-before: always;
  }

  .cmh-print-comments h2,
  .cmh-print-noscript h2 {
    margin: 0 0 0.7rem !important;
    color: var(--cp-text) !important;
  }

  .cmh-print-comment {
    margin: 1rem 0 !important;
    padding: 0.85rem 1rem !important;
    border: 1px solid var(--cp-border) !important;
    border-radius: 10px !important;
    background: var(--cp-surface-soft) !important;
  }

  .cmh-print-comment h3 {
    margin: 0 0 0.45rem !important;
    color: var(--cp-text) !important;
  }

  .cmh-print-comment p {
    margin: 0.35rem 0 !important;
  }

  .cmh-print-comment blockquote {
    margin: 0.5rem 0 !important;
    padding: 0.4rem 0.65rem !important;
    border-left: 3px solid var(--cp-warning) !important;
    color: var(--cp-text-muted) !important;
    background: var(--cp-warning-soft) !important;
    white-space: pre-wrap !important;
  }

  .cmh-print-meta {
    color: var(--cp-text-muted) !important;
    font-size: 0.82rem !important;
  }

  #commentRoot[data-cmh-mode="deck"] .deck-viewport,
  #commentRoot[data-cmh-mode="deck"] .deck-stage {
    position: static !important;
    inset: auto !important;
    width: auto !important;
    height: auto !important;
    transform: none !important;
    overflow: visible !important;
  }

  /* Only the slides print; the stage's non-slide children (the injected <style> and the
     corner-logo overlay) would otherwise add a stray page. */
  #commentRoot[data-cmh-mode="deck"] .deck-stage > *:not(.slide) {
    display: none !important;
  }

  #commentRoot[data-cmh-mode="deck"] .slide {
    page: cmh-deck-slide;
    position: relative !important;
    inset: auto !important;
    /* Display is intentionally NOT set here: 83-print.js pins each slide's on-screen computed
       display inline so print keeps the authored flex/grid layout (the vendored deck engine's print
       rule would otherwise force every slide to display:block and flatten multi-column slides). */
    width: 1920px !important;
    min-height: 1080px !important;
    height: 1080px !important;
    margin: 0 !important;
    visibility: visible !important;
    opacity: 1 !important;
    pointer-events: auto !important;
    transform: none !important;
    overflow: hidden !important;
    break-inside: avoid;
    page-break-inside: avoid;
  }

  /* One slide per page via break-BEFORE on every slide after the first (a slide preceded by another
     slide - the general sibling combinator so an intervening hidden non-slide child cannot break
     it). This never leaves a trailing blank page the way break-after on the last slide can. */
  #commentRoot[data-cmh-mode="deck"] .slide ~ .slide {
    break-before: page;
    page-break-before: always;
  }
}
/* ---------- Reduced motion (CMH-A11Y-07) ---------- */
/* Honor the OS/browser "reduce motion" preference: clamp every non-essential animation and
   transition (including their delays) to near-instant so the composer flash, mermaid/diff pulses,
   and checklist/notes flashes do not animate for users who are motion-sensitive. Durations are
   clamped (not set to none) so animations that establish a final state via keyframes still land
   correctly. The deck slide stage additionally carries the vendored slide engine's own
   reduced-motion rule (animations instant, a minimal essential slide transition). */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-delay: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    transition-delay: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
