/* Typography for markdown-prose pages (articles, about, mentorship, etc.) */

.prose {
  font-size: 14px;
  line-height: 1.75;
  color: var(--fg);
}

.prose > * + * { margin-top: 1.2em; }

.prose h1, .prose h2, .prose h3, .prose h4 {
  color: var(--bright);
  font-weight: 700;
  letter-spacing: -0.01em;
  margin-bottom: 0.5em;
}

.prose h1 { font-size: clamp(26px, 4vw, 34px); margin-top: 0; }
.prose h2 { font-size: clamp(20px, 3vw, 24px); margin-top: 2em; padding-top: 0.5em; border-top: 1px dashed var(--line); }

/* First section heading has no preceding content at prose-scope, so the
 * .prose h2 margin-top (2em ≈ 48px) collapses up through the wrapper
 * and the .prose container, producing a visible empty block + redundant
 * dashed separator above the very first content. The article-header's
 * own border-bottom already provides that separator. */
.prose > section:first-of-type > h2:first-of-type {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
}
.prose h3 { font-size: 17px; margin-top: 1.6em; color: var(--accent); }
.prose h4 { font-size: 15px; margin-top: 1.4em; color: var(--accent-dim); }

.prose p { color: var(--fg); }

.prose a {
  color: var(--accent);
  text-decoration: none;
}
.prose a:hover { color: var(--bright); }

.prose ul, .prose ol {
  padding-left: 1.4em;
}
.prose li { margin: 0.3em 0; }
.prose li::marker { color: var(--dim); }

.prose blockquote {
  border-left: 2px solid var(--accent-dim);
  padding: 0.2em 0 0.2em 1em;
  color: var(--dim);
  font-style: italic;
}

.prose .callout {
  margin: 24px 0;
  padding: 12px 20px;
  border-left: 2px solid var(--accent);
  background: rgba(0, 255, 156, 0.04);
  border-radius: 0 6px 6px 0;
}
.prose .callout--warn {
  border-left-color: var(--warn);
  background: rgba(255, 217, 61, 0.05);
}
.prose .callout__title {
  color: var(--accent);
  font-size: 13px;
  letter-spacing: 0.05em;
  margin-bottom: 8px;
}
.prose .callout--warn .callout__title { color: var(--warn); }
.prose .callout p:last-child { margin-bottom: 0; }

.prose code {
  font-family: var(--font-mono);
  font-size: 0.9em;
  background: rgba(0, 255, 156, 0.08);
  color: var(--accent);
  padding: 1px 6px;
  border-radius: 3px;
  overflow-wrap: anywhere;
  word-break: break-word;
}

.prose pre {
  background: rgba(255, 255, 255, 0.09);
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 6px;
  padding: 14px 16px;
  margin: 10px 0;
  overflow-x: auto;
  font-family: var(--font-mono);
  font-size: 13px;
  line-height: 1.6;
  overflow-wrap: normal;
}
.prose pre code {
  background: transparent;
  color: var(--fg);
  padding: 0;
  font-size: inherit;
}

.prose hr {
  border: 0;
  border-top: 1px dashed var(--line);
  margin: 2.5em 0;
}

.prose strong { color: var(--bright); font-weight: 700; }
.prose em { color: var(--fg); }

/* Tables — shared rule for every article that uses .prose (CQRS,
 * code-intelligence-stack, knowledge-vacuum, and future ones).
 * Left-aligned headers, subtle gray borders, generous post-table spacing.
 */
.prose table {
  width: 100%;
  border-collapse: collapse;
  margin: 28px 0 36px;
  font-size: 14px;
  line-height: 1.55;
  color: var(--fg);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.prose thead th {
  text-align: left;
  font-weight: 600;
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent-dim);
  padding: 12px 14px 12px 0;
  border-bottom: 1px solid var(--line);
}
.prose thead th:not(:last-child) { border-right: 1px solid var(--line); }
.prose tbody td {
  text-align: left;
  padding: 12px 14px 12px 0;
  vertical-align: top;
  border-bottom: 1px solid var(--line);
}
.prose tbody td:not(:last-child) { border-right: 1px solid var(--line); }
.prose tbody tr:last-child td { border-bottom: none; }

/* Article header (above prose) */
.article-header {
  margin-bottom: 40px;
  padding-bottom: 20px;
  border-bottom: 1px dashed var(--line);
}
.article-header__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 16px;
  align-items: center;
  font-size: 12px;
  color: var(--dim);
  margin-bottom: 22px;
}
.article-header__date { font-family: var(--font-mono); letter-spacing: 0.02em; }
.article-header__reading { color: var(--dim); }
.article-header__tags { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; flex-basis: 100%; }
.article-header__tags-label { color: var(--dim); font-size: 11px; }

.project-stats {
  display: inline-flex;
  gap: 6px;
  flex-wrap: wrap;
  margin-top: 10px;
}
.article-header h1 {
  font-size: clamp(26px, 4vw, 36px);
  font-weight: 700;
  color: var(--bright);
  letter-spacing: -0.02em;
  line-height: 1.25;
  margin-bottom: 8px;
}
.article-header__desc {
  color: var(--dim);
  font-size: 14px;
  line-height: 1.6;
  max-width: 60ch;
}

.article-nav {
  margin-top: 56px;
  padding-top: 24px;
  border-top: 1px dashed var(--line);
  display: grid;
  grid-template-columns: 1fr;
  gap: 12px;
}
@media (min-width: 600px) {
  .article-nav { grid-template-columns: 1fr 1fr; }
}

.article-nav__item {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-radius: 6px;
  text-decoration: none;
  transition: all 0.15s ease;
  min-height: 56px;
}
.article-nav__item:hover {
  border-color: var(--accent);
  text-decoration: none;
  transform: translateY(-1px);
}
.article-nav__item--next { text-align: right; }
.article-nav__label { color: var(--dim); font-size: 12px; letter-spacing: 0.05em; }
.article-nav__title { color: var(--bright); font-size: 14px; font-weight: 600; }
.article-nav__item:hover .article-nav__title { color: var(--accent); }
.article-nav__item--empty { visibility: hidden; }

@media (max-width: 480px) {
  .article-nav__label { font-size: 12px; }
}

/* TOC */
.toc {
  position: sticky;
  top: 76px;
  font-size: 12px;
  color: var(--dim);
  padding: 12px 0 12px 16px;
  border-left: 1px solid var(--line);
  margin-bottom: 32px;
  max-height: calc(100vh - 100px);
  overflow-y: auto;
}
.toc__label { color: var(--accent); font-size: 11px; letter-spacing: 0.05em; margin-bottom: 8px; text-transform: uppercase; }
.toc ul { list-style: none; padding: 0; margin: 0; }
.toc li { margin: 4px 0; }
.toc a { color: var(--dim); text-decoration: none; }
.toc a:hover, .toc a.is-active { color: var(--accent); }
.toc .toc-h3 { padding-left: 12px; font-size: 11px; }

/* ============== WIKI LAYOUT
 * Activated only when frontmatter `toc:` is set on a project page.
 * Resets the 68ch column and body max-width for wiki pages only —
 * articles, mentorship, hr, architecture and other project pages
 * are unaffected because they don't render .layout-wiki.
 *
 * TOC lives OUTSIDE the 800px body box via position: fixed.
 * Content always uses the full body width. The TOC hides itself
 * as a 20px tab on viewports where it would overlap the content,
 * and expands on hover/focus. At ≥1272px viewport there is enough
 * horizontal slack between the 800px body and the viewport edge
 * to seat the TOC fully without overlapping content.
 * ============== */

.layout-wiki {
  display: block;
  max-width: 1200px;
}

.layout-wiki > .prose--wide {
  max-width: none;
  min-width: 0;
}

.layout-wiki > .toc--wiki {
  position: fixed;
  top: 80px;
  right: 16px;
  width: 220px;
  max-height: calc(100vh - 100px);
  overflow-y: auto;
  font-size: 12px;
  color: var(--dim);
  padding: 12px 14px;
  background: var(--bg);
  border-left: 2px solid var(--accent);
  z-index: 5;
  transform: translateX(calc(100% - 24px));
  transition: transform 0.25s ease;
}

.layout-wiki > .toc--wiki:hover,
.layout-wiki > .toc--wiki:focus-within {
  transform: translateX(0);
}

@media (min-width: 1272px) {
  .layout-wiki > .toc--wiki {
    right: max(16px, calc((100vw - 800px) / 2 - 220px - 16px));
    transform: translateX(0);
  }
}

@media (max-width: 720px) {
  .layout-wiki > .toc--wiki { display: none; }
}

.toc__details { width: 100%; }
.toc__details > summary {
  cursor: pointer;
  list-style: none;
  padding: 0;
  color: var(--accent);
  font-size: 11px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  margin-bottom: 8px;
}
.toc__details > summary::-webkit-details-marker { display: none; }
.toc__details > summary::after {
  content: " ▾";
  color: var(--accent-dim);
  font-size: 10px;
}
.toc__details:not([open]) > summary::after { content: " ▸"; }

.toc--wiki ul { list-style: none; padding: 0; margin: 0; }
.toc--wiki li { margin: 4px 0; }
.toc--wiki a {
  color: var(--dim);
  text-decoration: none;
  display: block;
  padding: 2px 0;
  border-left: 2px solid transparent;
  padding-left: 8px;
  margin-left: -10px;
  transition: color 0.15s ease, border-color 0.15s ease;
}
.toc--wiki a:hover { color: var(--bright); }
.toc--wiki a.is-active {
  color: var(--accent);
  border-left-color: var(--accent);
}
.toc--wiki .toc-h3 { padding-left: 20px; font-size: 11px; }

/* ============================================================
   Agent-note aside (rendered via src/_includes/partials/agent-instruction.njk)
   Hidden from human readers in the rendered DOM. The text is kept in the
   HTML source so AI agents that fetch the raw HTML still see the note;
   the runtime middleware (lib/agent-serve.js) also strips the placeholder
   block for non-AI user-agents at the server. This CSS rule is a
   defense-in-depth backstop for the case where a dist file is opened
   directly without going through the middleware.
   ============================================================ */
.agent-note { display: none !important; }

/* ============================================================
   Article footer — separates a small disclaimer from the sources
   block at the end of long articles (e.g. knowledge-vacuum).
   Two clear visual zones: a single italic disclaimer line, and a
   distinct "Sources" card with its own left border, heading, and
   compact link list.
   ============================================================ */
.article-foot {
  margin-top: 48px;
  padding-top: 22px;
  border-top: 1px dashed var(--line);
  color: var(--dim);
  font-size: 12px;
  line-height: 1.6;
}
.article-foot__note {
  margin: 0 0 28px;
  font-style: italic;
  color: var(--dim);
  max-width: 60ch;
}
.sources {
  border-left: 2px solid var(--accent-dim);
  background: rgba(255, 255, 255, 0.02);
  padding: 16px 20px 14px 22px;
  border-radius: 0 6px 6px 0;
  font-size: 12px;
  line-height: 1.65;
}
.sources__title {
  color: var(--accent-dim);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  margin: 0 0 10px;
  font-weight: 600;
}
.sources__summary {
  margin: 0 0 12px;
  color: var(--fg);
}
.sources__list {
  list-style: none;
  padding: 0;
  margin: 0;
}
.sources__list li {
  margin: 4px 0;
  padding: 0;
  color: var(--dim);
}
.sources__list a {
  color: var(--accent);
  text-decoration: none;
}
.sources__list a:hover { color: var(--bright); text-decoration: none; }
@media (max-width: 540px) {
  .sources { padding: 14px 14px 12px 16px; }
}

/* ============================================================
   SVG zoom-on-click (wired by src/assets/js/svg-zoom.js).
   Inline diagrams inside .prose become keyboard-focusable,
   show a zoom-in cursor, and open a <dialog> lightbox on
   click / Enter / Space. The lightbox clones the SVG with
   id-renaming so <defs>, gradients, and filters resolve
   correctly in the cloned subtree.
   ============================================================ */
.prose svg.svg-zoomable {
  cursor: zoom-in;
  border-radius: 6px;
  transition: outline-color 0.15s ease;
  outline: 1px dashed transparent;
  outline-offset: 4px;
}
.prose svg.svg-zoomable:hover {
  outline-color: var(--accent-dim);
}
.prose svg.svg-zoomable:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 4px;
}

dialog.svg-zoom-dialog {
  width: 100vw;
  max-width: 100vw;
  height: 100vh;
  max-height: 100vh;
  margin: 0;
  padding: 0;
  border: 0;
  background: rgba(8, 12, 18, 0.94);
  color: var(--fg);
  overflow: auto;
}
dialog.svg-zoom-dialog::backdrop {
  background: rgba(0, 0, 0, 0.7);
}
dialog.svg-zoom-dialog .svg-zoom-stage {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  padding: 56px 32px;
  box-sizing: border-box;
}
dialog.svg-zoom-dialog .svg-zoom-clone {
  max-width: 100%;
  max-height: calc(100vh - 112px);
  height: auto;
  width: auto;
  display: block;
  cursor: zoom-out;
  border-radius: 6px;
}
dialog.svg-zoom-dialog .svg-zoom-close {
  position: fixed;
  top: 16px;
  right: 16px;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.2);
  background: rgba(255, 255, 255, 0.06);
  color: var(--bright);
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  z-index: 2;
  padding: 0;
  font-family: var(--font-mono, monospace);
}
dialog.svg-zoom-dialog .svg-zoom-close:hover {
  background: rgba(255, 255, 255, 0.12);
}
dialog.svg-zoom-dialog .svg-zoom-close:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
@media (max-width: 540px) {
  dialog.svg-zoom-dialog .svg-zoom-stage { padding: 64px 16px; }
}