.bubo-highlighter-yellow {
    background-color: rgba(255, 255, 0, 0.33);
}
.bubo-highlighter-magenta {
    background-color: #FF50FF;
}
.bubo-highlighter-cyan {
    background-color: #00FFFF;
}
.bubo-highlighter-lightred {
    background-color: #FFA0A0;
}
.bubo-highlighter-green {
    background-color: rgba(0, 255, 0, 0.33);
}

/* PDF text layer: the visible glyphs live in the rendered page image BELOW
   the (invisible, selection-only) text layer, so a translucent highlight
   painted on top washes the ink out. Multiply blending makes highlights
   behave as if painted BEHIND the ink — white paper turns yellow, dark
   glyphs stay dark.

   The blend MUST sit on .textLayer itself, NOT on the highlighter spans:
   the text-layer item spans carry transforms and .textLayer is z-indexed,
   and each creates an isolated stacking context, so a span-level
   mix-blend-mode (and backdrop-filter) never reaches the canvas — verified
   by pixel-sampling (span-level rule was a no-op). At the layer level the
   whole layer (transparent text contributes nothing per-pixel) multiplies
   onto the sibling canvas below. Side effects: text selection and the
   opaque marker colors (magenta/cyan/lightred) also multiply in PDF text
   layers — ink shows through them now.
   The annotation-View iframe is unaffected (its spans wrap real text, the
   background already paints behind the glyphs). */
.textLayer {
    mix-blend-mode: multiply;
}

* {
  overflow-anchor: none;
}

.vh100 {
    height: 100vh;
}

/* PDF-viewer text-selection popup only (pdf_selection.cljs). Both were the old
   green palette — a green-900 focus border and a pure-lime :active — and are now
   the interaction accent, blue-600, per decision 2a
   (lode/gui/visual-language-decisions.md). !important is kept because this popup
   renders inside an iframe that also loads Bootstrap 3. */
.bubo-focusable-border-accent:focus-visible {
    border: 2px solid #2563eb !important;
    border-radius: 0.75rem !important;
    outline: none !important;
}

.bubo-active-accent:active {
    color: #2563eb !important;
}

.bubo-text-base {
    font-size: 1rem !important;
    line-height: 1.5rem !important;
}

/* ---------------------------------------------------------------------------
   .bubo-card-body — child-card content (v1 § 4e)

   REQUIRED, not cosmetic. Since § 4e a child card carries the author's real
   markup again (lists, tables, <pre>, headings) instead of the plain text
   `as-text` used to produce — and Tailwind v4's preflight actively removes what
   that markup needs:

       ol, ul, menu { list-style: none }          <- restored lists lose bullets
       *            { margin: 0 }                 <- p/h1-h6 lose all separation

   so without these rules a restored list renders as unmarked lines and restored
   paragraphs run together. Everything is scoped to .bubo-card-body: this is the
   embedded author's content, not ours, and none of it may leak into our chrome.

   UNLAYERED on purpose — postcss.config.js strips @layer utilities, so layered
   rules would lose to Tailwind's own (lode/gui/styling-tailwind.md).

   Sizes are in rem and the root font-size is PINNED TO 14px by two legacy
   stylesheets (lode/gui/type-scale-and-root-font-size.md), so 1rem = 14px here,
   not 16px. The scale below is chosen against that, deliberately modest: a child
   card is a row in a list, not a document.

   Not repeated here because preflight already provides it: `img, video
   { max-width: 100%; height: auto }`. The width axis is additionally carried by
   `min-w-0 overflow-x-auto` on the wrapper itself.

   The legacy/extension surfaces need none of this — Bootstrap 3 does not reset
   lists — which is why it lives beside the SPA's stylesheet rather than in the
   server-rendered fragment.
   --------------------------------------------------------------------------- */

.bubo-card-body ul,
.bubo-card-body ol {
    list-style: revert;
    padding-left: 1.5rem;
    margin: 0.35rem 0;
}
.bubo-card-body li { margin: 0.1rem 0; }

.bubo-card-body p { margin: 0.4rem 0; }
.bubo-card-body p:first-child { margin-top: 0; }
.bubo-card-body p:last-child { margin-bottom: 0; }

.bubo-card-body h1,
.bubo-card-body h2,
.bubo-card-body h3,
.bubo-card-body h4,
.bubo-card-body h5,
.bubo-card-body h6 {
    font-weight: 600;
    line-height: 1.3;
    margin: 0.5rem 0 0.25rem;
}
.bubo-card-body h1 { font-size: 1.25rem; }
.bubo-card-body h2 { font-size: 1.15rem; }
.bubo-card-body h3 { font-size: 1.05rem; }
.bubo-card-body h4,
.bubo-card-body h5,
.bubo-card-body h6 { font-size: 1rem; }

/* A real <pre> defaults to `white-space: pre`, which does NOT wrap — and this is
   exactly the case the removed `whitespace-pre-wrap` used to cover for the whole
   card. Scoped to <pre> it keeps the author's line structure without turning
   every newline between tags into a blank line. */
.bubo-card-body pre {
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    margin: 0.4rem 0;
}
.bubo-card-body code,
.bubo-card-body pre {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.92em;
}
.bubo-card-body :not(pre) > code {
    background-color: #f3f4f6;
    border-radius: 0.2rem;
    padding: 0.05rem 0.25rem;
}

/* Our own cell borders — the "then they will behave like code" contract: an
   author's table keeps its STRUCTURE, and we supply the appearance, because the
   geometry filter has already dropped whatever they said about size. */
.bubo-card-body table {
    border-collapse: collapse;
    margin: 0.4rem 0;
}
.bubo-card-body th,
.bubo-card-body td {
    border: 1px solid #e5e7eb;
    padding: 0.15rem 0.4rem;
    text-align: left;
    vertical-align: top;
}
.bubo-card-body th { font-weight: 600; background-color: #f9fafb; }

.bubo-card-body blockquote {
    border-left: 3px solid #d1d5db;
    padding-left: 0.75rem;
    margin: 0.4rem 0;
    color: #4b5563;
}
.bubo-card-body hr {
    border: 0;
    border-top: 1px solid #e5e7eb;
    margin: 0.5rem 0;
}
