/* Ghost Koenig card base styles for abn.is */

/* ---- Image cards ---- */
.kg-image-card { margin: 0 0 1.5em; }
.kg-image-card img { max-width: 100%; height: auto; display: block; margin: 0 auto; }
.kg-width-wide { max-width: 85vw; margin-left: auto; margin-right: auto; }
.kg-width-full { max-width: 100vw; margin-left: calc(50% - 50vw); margin-right: calc(50% - 50vw); }

/* ---- Gallery cards ---- */
.kg-gallery-card { margin: 0 0 1.5em; }
.kg-gallery-container { display: flex; flex-direction: column; gap: 8px; }
.kg-gallery-row { display: flex; gap: 8px; }
.kg-gallery-image { flex: 1; }
.kg-gallery-image img { max-width: 100%; height: 100%; object-fit: cover; display: block; }

/* ---- Bookmark cards (the LinkPreview design — see src/components/LinkPreview.astro) ----
   Ghost emits this markup for pasted-link bookmark cards; we style its native
   classes to match the LinkPreview component so article cards and direct-MDX
   cards read identically. The key fixes vs. the old embed: the THUMBNAIL is a
   fixed column that never drives card height, and the FAVICON (.kg-bookmark-icon,
   previously unstyled and rendered at its natural size) is locked to an 18px chip. */
.kg-bookmark-card { margin: 30px 0; }
.kg-bookmark-container {
  display: flex;
  align-items: stretch;
  background: var(--color-surface);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-xl);
  overflow: hidden;
  text-decoration: none;
  color: inherit;
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.kg-bookmark-container:hover {
  transform: translateY(-3px);
  border-color: var(--color-accent);
  box-shadow: var(--shadow-lg);
}
/* no thumbnail → drop the column, switch to the 3px accent left-rule variant */
.kg-bookmark-container:not(:has(.kg-bookmark-thumbnail)) {
  border-left: 3px solid var(--color-accent);
  border-radius: 3px var(--radius-xl) var(--radius-xl) 3px;
}

.kg-bookmark-content {
  flex: 1;
  min-width: 0;
  padding: 20px 22px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.kg-bookmark-title {
  font-size: 16px;
  font-weight: 700;
  line-height: 1.35;
  letter-spacing: -0.01em;
  color: var(--color-heading);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.kg-bookmark-description {
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--color-text-muted);
  margin: 7px 0 0;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* source row: 18px favicon chip + publisher · author + an ↗ external cue */
.kg-bookmark-metadata {
  display: flex;
  align-items: center;
  margin-top: 16px;
  min-width: 0;
  font-size: 12.5px;
  color: var(--color-text-muted);
  overflow: hidden;
}
.kg-bookmark-icon {
  flex: none;
  width: 18px;
  height: 18px;
  margin: 0 9px 0 0;
  border-radius: 5px;
  object-fit: cover;
  background: var(--color-surface-sunken);
}
.kg-bookmark-author,
.kg-bookmark-publisher {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.kg-bookmark-publisher { color: var(--color-text); font-weight: 500; }
/* separator only when both author and publisher are present */
.kg-bookmark-author + .kg-bookmark-publisher::before {
  content: "·";
  margin: 0 0.45em;
  color: var(--color-text-faint);
  font-weight: 400;
}
.kg-bookmark-metadata::after {
  content: "↗";
  flex: none;
  margin-left: auto;
  padding-left: 12px;
  color: var(--color-text-faint);
  font-size: 13px;
  transition: transform var(--dur) var(--ease), color var(--dur) var(--ease);
}
.kg-bookmark-container:hover .kg-bookmark-metadata::after {
  transform: translate(2px, -2px);
  color: var(--color-accent-text);
}

/* thumbnail: fixed column, cover-cropped — never dictates card height */
.kg-bookmark-thumbnail {
  flex: none;
  width: clamp(132px, 34%, 196px);
  background: var(--color-surface-sunken);
}
.kg-bookmark-thumbnail img {
  width: 100%;
  height: 100%;
  min-height: 122px;
  object-fit: cover;
  display: block;
}

/* caption beneath the card (Ghost wraps it in <figcaption>) */
.kg-bookmark-card figcaption {
  font-size: 14px;
  line-height: 1.7;
  font-style: italic;
  color: var(--color-text-muted);
  text-align: center;
  margin: 16px auto 0;
  max-width: 60ch;
}

/* dark: dim bright thumbnails so they don't glare; hover restores full detail */
[data-theme="dark"] .kg-bookmark-thumbnail img {
  transition: filter var(--dur-slow) var(--ease);
  filter: brightness(0.82) saturate(0.94);
}
[data-theme="dark"] .kg-bookmark-container:hover .kg-bookmark-thumbnail img {
  filter: brightness(0.96) saturate(1);
}
/* mobile: image cards stack — thumbnail on top (full width), text below */
@media (max-width: 600px) {
  .kg-bookmark-container:has(.kg-bookmark-thumbnail) { flex-direction: column-reverse; }
  .kg-bookmark-thumbnail { width: 100%; height: 148px; }
}

/* ---- Button cards ---- */
.kg-button-card { margin: 0 0 1.5em; display: flex; }
.kg-button-card.kg-align-center { justify-content: center; }
.kg-btn {
  display: inline-flex; align-items: center;
  padding: 10px 20px;
  background: var(--color-accent);
  color: var(--color-on-accent);
  border-radius: var(--radius-md);
  font-weight: var(--fw-semibold);
  font-size: var(--text-sm);
  text-decoration: none;
  transition: opacity var(--dur) var(--ease);
}
.kg-btn:hover { opacity: 0.88; }

/* ---- Callout cards ---- */
.kg-callout-card {
  border-radius: var(--radius-xl);
  padding: 22px 26px;
  margin: 30px 0;
  font-size: 15px;
  line-height: 1.7;
}
.kg-callout-card .kg-callout-emoji {
  display: none; /* hide the emoji — the label handles the semantic meaning */
}
.kg-callout-card .kg-callout-text {
  color: var(--color-text);
}
.kg-callout-card .kg-callout-text p { margin: 0; }
.kg-callout-card .kg-callout-text p + p { margin-top: 0.75em; }

/* Eyebrow labels injected via ::before — color from theme-aware --callout-* tokens */
.kg-callout-card-yellow::before,
.kg-callout-card-green::before,
.kg-callout-card-grey::before {
  content: 'TIP';
  display: block;
  font-size: 10.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--callout-tip-label);
  margin-bottom: 10px;
}
.kg-callout-card-red::before,
.kg-callout-card-pink::before {
  content: 'WARNING';
  display: block;
  font-size: 10.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--callout-warn-label);
  margin-bottom: 10px;
}
/* pull quote: no default eyebrow label — the oversized body already signals the takeaway */

/* tip variants (yellow/green/grey → honey style; theme-aware --callout-tip-* tokens) */
.kg-callout-card-yellow,
.kg-callout-card-green,
.kg-callout-card-grey {
  background: var(--callout-tip-bg);
  border: 1px solid var(--callout-tip-line);
  color: var(--color-text);
}

/* warning variants (red/pink → red style; theme-aware --callout-warn-* tokens) */
.kg-callout-card-red,
.kg-callout-card-pink {
  background: var(--callout-warn-bg);
  border: 1px solid var(--callout-warn-line);
  color: var(--color-text);
}

/* pull/accent variants (blue/purple → violet diagonal gradient, fixed brand colors) */
.kg-callout-card-blue,
.kg-callout-card-purple {
  background: linear-gradient(120deg, #7902AA, #A435CE 48%, #A435CE);
  border: none;
  color: #fff;
  padding: 28px 30px;
}
.kg-callout-card-blue .kg-callout-text,
.kg-callout-card-purple .kg-callout-text {
  font-size: 18px;
  font-weight: 600;
  line-height: 1.4;
}

/* Force crisp white body text on the violet gradient in BOTH themes.
   The base rule `.kg-callout-card .kg-callout-text { color: var(--color-text) }`
   (2 classes) outranks the card-level `color:#fff` on the variant, so it must be
   re-asserted at matching specificity on .kg-callout-text itself. */
.kg-callout-card-blue .kg-callout-text,
.kg-callout-card-purple .kg-callout-text {
  color: #fff;
}

/* Inline <code> chips inside the violet pull-quote → flag yellow (--c-yellow-flag),
   matching the eyebrow label usage. Replace the prose light-chip background with a
   subtle translucent dark wash that reads cleanly on the violet gradient.
   The extra .kg-callout-text class raises specificity to (0,3,1) so this beats the
   prose inline-code rule `.prose[data-astro-cid-…] code` (0,2,1), which is emitted in
   a later <style> block and would otherwise win the cascade on source order. */
.kg-callout-card-blue .kg-callout-text.kg-callout-text code,
.kg-callout-card-purple .kg-callout-text.kg-callout-text code {
  color: #FFD800;
  background: rgba(0, 0, 0, 0.18);
  border: none;
  font-family: var(--font-code);
}

/* Links inside the violet pull-quote → brand cyan/info (--c-info-d #22D3EE).
   Without this, links inherit the global prose link style (dark violet #7902AA +
   underline), which is nearly invisible on the #7902AA→#A435CE violet gradient.
   Cyan is the brand's info hue (and the code "function" color); it has strong
   contrast on the violet gradient and is clearly DISTINCT from the flag-yellow
   #FFD800 used by the inline <code> chips and eyebrow label, so links don't read
   as code. The double .kg-callout-text class raises specificity to (0,3,1) to beat
   the prose link rule `.prose[data-astro-cid-…] a` (≈0,2,1) emitted in a later
   <style> block (same reasoning as the code chips above). A cyan underline + bolder
   weight reinforces the link affordance; hover/focus brightens to a near-white cyan
   tint with a full-opacity cyan underline. Identical in light & dark — the card is
   the same fixed violet gradient in both themes, so no theme override is needed. */
.kg-callout-card-blue .kg-callout-text.kg-callout-text a,
.kg-callout-card-purple .kg-callout-text.kg-callout-text a {
  color: #22D3EE;
  font-weight: 700;
  text-decoration: underline;
  text-decoration-color: rgba(34, 211, 238, 0.6);
  text-underline-offset: 0.18em;
  text-decoration-thickness: 1.5px;
  transition: color var(--dur-fast) var(--ease), text-decoration-color var(--dur-fast) var(--ease);
}
.kg-callout-card-blue .kg-callout-text.kg-callout-text a:hover,
.kg-callout-card-purple .kg-callout-text.kg-callout-text a:hover,
.kg-callout-card-blue .kg-callout-text.kg-callout-text a:focus-visible,
.kg-callout-card-purple .kg-callout-text.kg-callout-text a:focus-visible {
  color: #CFFAFE;
  text-decoration-color: #22D3EE;
}

/* Bold inside the violet pull-quote → yellow highlighter mark (matches the `.hl`
   span on the about page). Without this, `.prose strong` forces
   color:var(--color-heading) directly on the <strong> element — which in LIGHT
   mode is near-black #1C1917 and illegible on the violet gradient (it beats the
   inherited white from .kg-callout-text because it targets the element directly).
   The body is already weight 600, so plain white wouldn't differentiate the
   emphasis; the highlighter mark keeps it readable AND distinct in both themes.
   Double .kg-callout-text class → specificity (0,3,1), beating `.prose strong`
   (0,1,1). Hardcoded dark ink because the yellow background is theme-independent. */
.kg-callout-card-blue .kg-callout-text.kg-callout-text strong,
.kg-callout-card-purple .kg-callout-text.kg-callout-text strong,
.kg-callout-card-blue .kg-callout-text.kg-callout-text b,
.kg-callout-card-purple .kg-callout-text.kg-callout-text b {
  background: #FFE873;
  color: #1C1917;
  padding: 0.05em 0.22em;
  border-radius: 3px;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}

/* tip/warning palettes are theme-aware via --callout-* tokens — no dark override.
   purple/blue pull quote is fixed brand violet (identical in both themes). */

/* ---- Toggle cards ---- */
.kg-toggle-card { margin: 0 0 1.5em; border: 1px solid var(--color-line); border-radius: var(--radius-md); overflow: hidden; }
.kg-toggle-heading {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 16px; cursor: pointer;
  background: var(--color-surface);
  user-select: none;
}
.kg-toggle-heading-text { font-weight: var(--fw-semibold); color: var(--color-heading); margin: 0; font-size: var(--text-body); }
.kg-toggle-card-icon { color: var(--color-text-muted); transition: transform var(--dur) var(--ease); flex: none; }
.kg-toggle-content { padding: 0 16px 16px; display: none; }
.kg-toggle-card.open .kg-toggle-content { display: block; }
.kg-toggle-card.open .kg-toggle-card-icon { transform: rotate(180deg); }

/* ---- Embed cards (YouTube, Spotify, Twitter) ---- */
.kg-embed-card { margin: 0 0 1.5em; }
figure.kg-embed-card { aspect-ratio: 16 / 9; overflow: hidden; margin: 0 0 1.5em; }
figure.kg-embed-card iframe { width: 100%; height: 100%; border: none; }
.kg-embed-card:not(figure) iframe { width: 100%; border: none; }

/* ---- Code card (kg-code-card) — filename chrome + copy button ---- */
figure.kg-code-card {
  margin: 1.5em 0;
  background: #0D0D0F;
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 8px;
  overflow: hidden;
  display: flex;
  flex-direction: column-reverse; /* figcaption (filename) goes to top visually */
}
figure.kg-code-card pre {
  margin: 0;
  border-radius: 0;
  border: none;
  background: transparent !important;
  padding: 20px 24px;
  overflow-x: auto;
}
figure.kg-code-card pre code {
  background: none !important;
  color: inherit;
}
figure.kg-code-card figcaption {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 24px;
  background: #16161A;
  border-bottom: 1px solid rgba(255,255,255,0.08);
  font-family: var(--font-code);
  font-size: 12px;
  color: #71717A; /* muted */
  text-align: left;
  font-style: normal;
  margin-top: 0;
}
figure.kg-code-card figcaption::after {
  content: 'copy';
  cursor: pointer;
  font-size: 11px;
  color: #71717A;
  letter-spacing: 0.04em;
}
figure.kg-code-card figcaption[data-copy-state="copied"]::after {
  content: 'copied!';
  color: #4ADE80; /* success green */
}

/* ╔═══════════════════════════════════════════════════════════════════════╗
   ║ BEGIN CODE-BLOCK REDESIGN (codeblock.* ) — owned by the code-block       ║
   ║ rendering effort. Self-contained; do not interleave other styles here.  ║
   ║ Adopts design_handoff_code_blocks_redesign: syntax LABEL chrome, real   ║
   ║ copy button (idle→hover→copied ✓), optional description FOOTER.          ║
   ║ Shiki blocks (figure.kg-code-card > pre.shiki) are rewritten server-side ║
   ║ into figure.codeblock by rehypeCodeBlocks() in src/lib/content.ts.       ║
   ║ Fonts: JetBrains Mono (source) + IBM Plex Mono (chrome) — already loaded ║
   ║ site-wide in BaseLayout.astro. Default theme = is-auto (follows site).   ║
   ╚═══════════════════════════════════════════════════════════════════════╝ */
.codeblock {
  /* dark (default). Palette comes from tokens.css primitives — change brand
     colours there, not here. (--cb-foot/-gutter and the label rgba tints are
     code-block-specific, no canonical primitive, so they stay literal.) */
  --cb-bg:     var(--c-void);
  --cb-bar:    var(--c-surface-d);
  --cb-foot:   #111114;
  --cb-line:   var(--c-line-d);
  --cb-text:   var(--c-text-d);
  --cb-muted:  var(--c-muted-d);
  --cb-gutter: #52525B;
  --cb-accent: var(--c-violet-400);
  --cb-label:  var(--c-violet-300);
  --cb-label-bg: rgba(164,53,206,.16);
  --cb-label-bd: rgba(164,53,206,.30);
  --cb-ok:     var(--c-success-d);

  display: block;
  border: 1px solid var(--cb-line);
  border-radius: 12px;
  overflow: hidden;
  background: var(--cb-bg);
  margin: 26px 0;
}

/* ---- light ---- */
.codeblock.is-light {
  --cb-bg:     var(--c-paper);
  --cb-bar:    var(--c-mist);
  --cb-foot:   var(--c-surface);
  --cb-line:   var(--c-line);
  --cb-text:   var(--c-ink);
  --cb-muted:  var(--c-muted);
  --cb-gutter: var(--c-stone-400);
  --cb-accent: var(--c-violet-700);
  --cb-label:  var(--c-violet-700);
  --cb-label-bg: rgba(121,2,170,.08);
  --cb-label-bd: rgba(121,2,170,.20);
  --cb-ok:     var(--c-success);
}

/* ---- auto: follow the page theme (light base; dark when the site is dark) ---- */
.codeblock.is-auto {
  --cb-bg:var(--c-paper); --cb-bar:var(--c-mist); --cb-foot:var(--c-surface); --cb-line:var(--c-line);
  --cb-text:var(--c-ink); --cb-muted:var(--c-muted); --cb-gutter:var(--c-stone-400); --cb-accent:var(--c-violet-700);
  --cb-label:var(--c-violet-700); --cb-label-bg:rgba(121,2,170,.08); --cb-label-bd:rgba(121,2,170,.20);
  --cb-ok:var(--c-success);
}
:root[data-theme="dark"] .codeblock.is-auto {
  --cb-bg:var(--c-void); --cb-bar:var(--c-surface-d); --cb-foot:#111114; --cb-line:var(--c-line-d);
  --cb-text:var(--c-text-d); --cb-muted:var(--c-muted-d); --cb-gutter:#52525B; --cb-accent:var(--c-violet-400);
  --cb-label:var(--c-violet-300); --cb-label-bg:rgba(164,53,206,.16); --cb-label-bd:rgba(164,53,206,.30);
  --cb-ok:var(--c-success-d);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .codeblock.is-auto {
    --cb-bg:var(--c-void); --cb-bar:var(--c-surface-d); --cb-foot:#111114; --cb-line:var(--c-line-d);
    --cb-text:var(--c-text-d); --cb-muted:var(--c-muted-d); --cb-gutter:#52525B; --cb-accent:var(--c-violet-400);
    --cb-label:var(--c-violet-300); --cb-label-bg:rgba(164,53,206,.16); --cb-label-bd:rgba(164,53,206,.30);
    --cb-ok:var(--c-success-d);
  }
}

/* ---- rainbow brand hairline (ALWAYS-ON brand signature, not hover/opt-in) ---- */
.codeblock__rainbow {
  height: 2px;
  background: var(--gradient-pride-bar);
}

/* ---- chrome ---- */
.codeblock__bar {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  padding: 10px 14px;
  background: var(--cb-bar);
  border-bottom: 1px solid var(--cb-line);
}
.codeblock__meta { display: flex; align-items: center; gap: 10px; min-width: 0; }
.codeblock__label {
  display: inline-flex; align-items: center; flex: none;
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 10px; letter-spacing: .08em; text-transform: uppercase; font-weight: 700;
  color: var(--cb-label);
  background: var(--cb-label-bg);
  border: 1px solid var(--cb-label-bd);
  border-radius: 5px; padding: 2px 7px;
}
.codeblock__title {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 12px; color: var(--cb-muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ---- copy button (idle accent per-shell; shared structure lives near EOF) ---- */
.codeblock .copy-btn { color: var(--cb-accent); }
.codeblock .copy-btn.is-copied { color: var(--color-success); }
.codeblock .copy-btn:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--cb-label-bd); border-radius: 6px; }

/* ---- code body (the Shiki <pre>, re-tagged .codeblock__pre) ---- */
.codeblock .codeblock__pre,
.codeblock pre.codeblock__pre {
  margin: 0; padding: 18px;
  background: var(--cb-bg) !important;
  border: none;
  border-radius: 0;
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 13.5px; line-height: 1.8;
  color: var(--cb-text);
  overflow-x: auto;
  white-space: pre;
}
.codeblock__pre::-webkit-scrollbar { height: 8px; }
.codeblock__pre::-webkit-scrollbar-thumb { background: #3A3A40; border-radius: var(--radius-pill); }
.codeblock__pre code { background: none; padding: 0; border-radius: 0; font-size: inherit; color: inherit; }
.codeblock__pre .line { display: inline-block; min-width: 100%; }

/* ---- description footer ---- */
.codeblock__desc {
  margin: 0;
  padding: 12px 18px;
  background: var(--cb-foot);
  border-top: 1px solid var(--cb-line);
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 12px; line-height: 1.55; color: var(--cb-muted);
  text-align: left;
  font-style: normal;
}
.codeblock__desc p { margin: 0; }
.codeblock__desc code {
  background: var(--cb-label-bg); color: var(--cb-label);
  padding: 1px 5px; border-radius: 4px;
  font-family: "JetBrains Mono", ui-monospace, monospace;
}

/* ╚════════════════════════ END CODE-BLOCK REDESIGN ═══════════════════════╝ */

/* =============================================================
   abn. — Prose tables (LEGACY .table-scroll shell)
   Article tables are now wrapped server-side in the on-brand .abn-tbl
   shell by rehypeAbnTables() in content.ts (styled by
   src/components/table/table.css). These rules are kept only for any
   stray `.table-scroll`-wrapped table and are scoped tightly to that
   wrapper so they can never bleed into a `.abn-tbl`.
   ============================================================= */
.table-scroll {
  overflow-x: auto;
  max-width: 100%;
  margin: 1.5em 0;
  -webkit-overflow-scrolling: touch;
}

.table-scroll table {
  border-collapse: collapse;
  width: 100%;
  margin: 0; /* outer margin lives on .table-scroll */
  font-size: 14px;
  line-height: var(--lh-normal);
  color: var(--color-text);
}

.table-scroll th,
.table-scroll td {
  border: 1px solid var(--color-line);
  padding: 8px 12px;
  text-align: left;
  vertical-align: top;
}

.table-scroll thead th {
  background: var(--color-surface-sunken);
  color: var(--color-heading);
  font-weight: var(--fw-semibold);
  white-space: nowrap;
}

/* Hide a fully-empty header row that survives (defensive). */
.table-scroll thead:empty { display: none; }

/* ---- Captions ---- */
figcaption {
  text-align: center;
  color: var(--color-text-faint);
  font-size: var(--text-xs);
  margin-top: 8px;
  line-height: var(--lh-normal);
}

/* =============================================================
   abn. — Terminal blocks
   Styles for shell/bash/sh code blocks rendered as terminal sessions.
   Shared by .term (prompt session) and .cmdcard (single command).
   Fonts: JetBrains Mono = session body, IBM Plex Mono = chrome/UI.
   ============================================================= */

.term, .cmdcard {
  /* ---- dark (default / recommended). Palette from tokens.css primitives;
     status rgba tints stay literal (no canonical primitive). ---- */
  --t-bg:var(--c-void);
  --t-bar:var(--c-surface-d);
  --t-line:var(--c-line-d);
  --t-line-2:var(--c-line-d2);
  --t-text:var(--c-text-d);
  --t-muted:var(--c-muted-d);
  --t-faint:var(--c-faint-d);
  --t-accent:var(--c-violet-400);
  --t-ok:var(--c-success-d);
  --t-err:var(--c-danger-d);
  --t-warn:var(--c-yellow-flag);
  --t-ok-bg:rgba(74,222,128,.10);   --t-ok-bd:rgba(74,222,128,.35);
  --t-err-bg:rgba(248,113,113,.10); --t-err-bd:rgba(248,113,113,.35);

  --t-font:"JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  --t-font-ui:"IBM Plex Mono", ui-monospace, monospace;
  --t-radius:12px;
}

/* ---- explicit light ---- */
.term.is-light, .cmdcard.is-light {
  --t-bg:var(--c-paper);
  --t-bar:var(--c-mist);
  --t-line:var(--c-line);
  --t-line-2:var(--c-stone-300);
  --t-text:var(--c-ink);
  --t-muted:var(--c-muted);
  --t-faint:var(--c-stone-400);
  --t-accent:var(--c-violet-700);
  --t-ok:var(--c-success);
  --t-err:var(--c-danger-text);
  --t-warn:var(--c-yellow-text);
  --t-ok-bg:rgba(22,163,74,.08);   --t-ok-bd:rgba(22,163,74,.30);
  --t-err-bg:rgba(185,28,28,.07);  --t-err-bd:rgba(185,28,28,.28);
}

/* ---- auto: light base, dark when the site/OS is dark ---- */
.term.is-auto, .cmdcard.is-auto {
  --t-bg:var(--c-paper); --t-bar:var(--c-mist); --t-line:var(--c-line); --t-line-2:var(--c-stone-300);
  --t-text:var(--c-ink); --t-muted:var(--c-muted); --t-faint:var(--c-stone-400); --t-accent:var(--c-violet-700);
  --t-ok:var(--c-success); --t-err:var(--c-danger-text); --t-warn:var(--c-yellow-text);
  --t-ok-bg:rgba(22,163,74,.08); --t-ok-bd:rgba(22,163,74,.30);
  --t-err-bg:rgba(185,28,28,.07); --t-err-bd:rgba(185,28,28,.28);
}
[data-theme="dark"] .term.is-auto, [data-theme="dark"] .cmdcard.is-auto {
  --t-bg:var(--c-void); --t-bar:var(--c-surface-d); --t-line:var(--c-line-d); --t-line-2:var(--c-line-d2);
  --t-text:var(--c-text-d); --t-muted:var(--c-muted-d); --t-faint:var(--c-faint-d); --t-accent:var(--c-violet-400);
  --t-ok:var(--c-success-d); --t-err:var(--c-danger-d); --t-warn:var(--c-yellow-flag);
  --t-ok-bg:rgba(74,222,128,.10); --t-ok-bd:rgba(74,222,128,.35);
  --t-err-bg:rgba(248,113,113,.10); --t-err-bd:rgba(248,113,113,.35);
}
@media (prefers-color-scheme:dark) {
  :root:not([data-theme="light"]) .term.is-auto,
  :root:not([data-theme="light"]) .cmdcard.is-auto {
    --t-bg:var(--c-void); --t-bar:var(--c-surface-d); --t-line:var(--c-line-d); --t-line-2:var(--c-line-d2);
    --t-text:var(--c-text-d); --t-muted:var(--c-muted-d); --t-faint:var(--c-faint-d); --t-accent:var(--c-violet-400);
    --t-ok:var(--c-success-d); --t-err:var(--c-danger-d); --t-warn:var(--c-yellow-flag);
    --t-ok-bg:rgba(74,222,128,.10); --t-ok-bd:rgba(74,222,128,.35);
    --t-err-bg:rgba(248,113,113,.10); --t-err-bd:rgba(248,113,113,.35);
  }
}

/* =================== Terminal (prompt session) =================== */
.term {
  border:1px solid var(--t-line);
  border-radius:var(--t-radius);
  overflow:hidden;
  background:var(--t-bg);
  margin:1.5em 0;
}
.term__rainbow {
  height:2px;
  background:var(--gradient-pride-bar);
}
.term__bar {
  display:flex; align-items:center; justify-content:space-between;
  padding:11px 16px;
  background:var(--t-bar);
  border-bottom:1px solid var(--t-line);
}
.term__label { font-family:var(--t-font); font-size:11.5px; color:var(--t-muted); }
.term .copy-btn, .cmdcard .copy-btn { color: var(--t-accent); }
.term .copy-btn.is-copied, .cmdcard .copy-btn.is-copied { color: var(--color-success); }

.term__body {
  padding:18px 18px 20px;
  font-family:var(--t-font);
  font-size:13.5px; line-height:1.85;
  color:var(--t-text);
}
.term__line { display:flex; gap:10px; margin-top:6px; }
.term__line:first-child { margin-top:0; }
.term__prompt { color:var(--t-accent); font-weight:700; flex:none; width:14px; }
.term__cmd { min-width:0; overflow-wrap:anywhere; }

.term__out {
  color:var(--t-muted); white-space:pre-wrap;
  padding-left:24px; overflow-wrap:anywhere; margin-top:2px;
}
.term__comment { color:var(--t-accent); opacity:.85; margin-top:10px; }
.term__comment:first-child { margin-top:0; }
.term__comment + .term__line { margin-top:0; }

.term__exitrow { display:flex; align-items:center; gap:10px; margin-top:14px; padding-left:24px; }
.term__exit {
  display:inline-flex; align-items:center;
  font-family:var(--t-font); font-size:11px;
  border-radius:var(--radius-pill); padding:2px 9px;
}
.term__exit.is-ok  { color:var(--t-ok);  border:1px solid var(--t-ok-bd);  background:var(--t-ok-bg); }
.term__exit.is-err { color:var(--t-err); border:1px solid var(--t-err-bd); background:var(--t-err-bg); }
.term__time { color:var(--t-faint); font-size:12px; }

.term__caret {
  display:inline-block; width:8px; height:16px;
  background:var(--t-accent); transform:translateY(3px);
  animation:term-blink 1.05s steps(1) infinite;
}
@keyframes term-blink { 0%,49%{opacity:1} 50%,100%{opacity:0} }

/* inline highlight helpers */
.hl-ok   { color:var(--t-ok); }
.hl-err  { color:var(--t-err); }
.hl-warn { color:var(--t-warn); }
.hl-cmd, .hl-accent { color:var(--t-accent); }
.hl-dim  { color:var(--t-faint); }

/* =================== CommandCard (single command + output) =================== */
.cmdcard {
  border:1px solid var(--t-line);
  border-radius:var(--t-radius);
  overflow:hidden;
  background:var(--t-bg);
  margin:1.5em 0;
}
.cmdcard__bar {
  display:flex; align-items:center; justify-content:space-between; gap:14px;
  padding:14px 16px; background:var(--t-bar);
}
.cmdcard__cmd {
  display:flex; gap:10px; align-items:baseline; min-width:0;
  font-family:var(--t-font); font-size:13.5px; color:var(--t-text);
}
.cmdcard__cmd > span:last-child { white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.cmdcard__prompt { color:var(--t-accent); font-weight:700; flex:none; }
.cmdcard__out {
  padding:16px 18px;
  font-family:var(--t-font); font-size:13px; line-height:1.8;
  color:var(--t-muted); white-space:pre-wrap;
  border-top:1px solid var(--t-line); overflow-wrap:anywhere;
}

@media (prefers-reduced-motion:reduce) {
  .term__caret { animation:none; }
}

/* Unified copy button (shared by code, terminal, mermaid, table shells). The
   idle accent colour is set per-shell below; the copied state is theme-aware. */
.copy-btn {
  display:inline-flex; align-items:center; gap:6px; flex:none;
  background:none; border:0; padding:0; cursor:pointer;
  font-family:var(--font-ui); font-size:11px; letter-spacing:.06em;
  text-transform:uppercase; color:inherit;
}
.copy-btn__ico {
  width:12px; height:12px; border:1.5px solid currentColor; border-radius:3px;
  flex:none; display:inline-flex; align-items:center; justify-content:center;
  line-height:1; font-size:11px;
}
.copy-btn:hover .copy-btn__lbl { text-decoration:underline; }
.copy-btn.is-copied .copy-btn__ico { border:none; }

