/*
 * What every documented --fx-* token is when the theme doesn't set it, so a theme only has to say what it changes.
 * Loaded wherever a theme's tokens are: the app, the print page, an exported site and every block frame.
 *
 * Plain on purpose: system fonts, grey ink on white, a link blue. None of the built-in theme's look comes through here.
 * :where() gives the block no specificity, so a theme's own :root wins whichever stylesheet loads first.
 *
 * --fx-color-bg is left out. The page falls back to white where it's painted (app.css, site.css), and the app's chrome
 * falls back to its own light or dark canvas while no theme is loaded, which a value here would take away.
 * --fx-print-wide-outset and --fx-print-full-outset are left out too: unset, print-base.css works them out from each
 * page's margins.
 */
:where(:root) {
  --fx-font-body: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  /* Follows the body font, the theme's if it sets one. */
  --fx-font-heading: var(--fx-font-body);
  --fx-font-mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  --fx-font-size: 16px;
  --fx-print-font-size: 10.5pt;
  --fx-line-height: 1.6;

  --fx-color-text: #1c1d21;
  --fx-color-muted: #666a73;
  --fx-color-surface: #f2f3f5;
  --fx-color-border: #d9dbe0;
  --fx-color-accent: #2257c5;
  --fx-color-accent-contrast: #ffffff;
  --fx-color-accent-soft: #e4ebfa;

  --fx-radius: 6px;
  --fx-image-radius: 3px;
  --fx-space: 8px;
  --fx-width-wide: 960px;
  --fx-print-edge: 6mm;
}

/* Base document styles for screen and print. Themes restyle through --fx-* tokens and their own CSS. */

.fx-doc {
  font-family: var(--fx-font-body);
  color: var(--fx-color-text);
  font-size: var(--fx-font-size, 16px);
  line-height: var(--fx-line-height, 1.6);
  font-kerning: normal;
  text-rendering: optimizeLegibility;
  overflow-wrap: break-word;
}

.fx-doc h1,
.fx-doc h2,
.fx-doc h3,
.fx-doc h4,
.fx-doc h5,
.fx-doc h6 {
  font-family: var(--fx-font-heading);
  line-height: 1.22;
  margin: 1.7em 0 0.55em;
  font-weight: 650;
  break-after: avoid;
}
.fx-doc h1 { font-size: 2.05em; letter-spacing: -0.015em; margin-top: 0; }
.fx-doc h2 { font-size: 1.45em; letter-spacing: -0.01em; }
.fx-doc h3 { font-size: 1.18em; }
.fx-doc h4 { font-size: 1em; }
.fx-doc h5, .fx-doc h6 { font-size: 0.9em; color: var(--fx-color-muted); }

.fx-doc p,
.fx-doc ul,
.fx-doc ol,
.fx-doc blockquote,
.fx-doc pre,
.fx-doc table,
.fx-doc figure {
  margin: 0 0 1em;
}
.fx-doc ul, .fx-doc ol { padding-left: 1.4em; }
.fx-doc li + li { margin-top: 0.25em; }
.fx-doc a { color: var(--fx-color-accent); text-underline-offset: 0.15em; }
/* A [[link]] to nothing: readable, but visibly not a link. */
.fx-doc .fx-wikilink-unresolved {
  color: var(--fx-color-muted);
  text-decoration: underline dotted;
  text-underline-offset: 0.15em;
  cursor: help;
}
.fx-doc strong { font-weight: 650; }
.fx-doc hr { border: 0; border-top: 1px solid var(--fx-color-border); margin: 2em 0; }
.fx-doc img { max-width: 100%; }

.fx-doc blockquote {
  border-left: 3px solid var(--fx-color-accent);
  padding: 0.1em 0 0.1em 1em;
  color: var(--fx-color-muted);
}

.fx-doc code {
  font-family: var(--fx-font-mono);
  font-size: 0.88em;
  background: var(--fx-color-surface);
  border-radius: 4px;
  padding: 0.1em 0.3em;
}
.fx-doc pre {
  font-family: var(--fx-font-mono);
  font-size: 0.85em;
  line-height: 1.5;
  background: var(--fx-color-surface);
  border: 1px solid var(--fx-color-border);
  border-radius: var(--fx-radius);
  padding: 0.9em 1.1em;
  overflow-x: auto;
  white-space: pre;
}
.fx-doc pre code { background: none; padding: 0; font-size: inherit; }

.fx-doc table { border-collapse: collapse; width: 100%; font-size: 0.95em; }
.fx-doc th, .fx-doc td { text-align: left; padding: 0.45em 0.6em; border-bottom: 1px solid var(--fx-color-border); vertical-align: top; }
.fx-doc th { font-weight: 600; border-bottom-color: var(--fx-color-text); }

.fx-doc figure figcaption {
  font-size: 0.85em;
  color: var(--fx-color-muted);
  margin-top: 0.5em;
}

/* Core blocks */

.fx-page-break {
  display: flex;
  align-items: center;
  gap: 0.75em;
  margin: 2em 0;
  color: var(--fx-color-muted);
  font-size: 0.75em;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.fx-page-break::before,
.fx-page-break::after {
  content: "";
  flex: 1;
  border-top: 1px dashed var(--fx-color-border);
}

.fx-toc { margin: 0 0 1.5em; }
.fx-toc-title { font-family: var(--fx-font-heading); font-weight: 650; margin-bottom: 0.5em; }
.fx-toc ol { list-style: none; padding: 0; margin: 0; }
.fx-toc li { margin: 0.2em 0; }
.fx-toc a { color: inherit; text-decoration: none; }
.fx-toc a:hover { color: var(--fx-color-accent); }
.fx-toc-level-2 { padding-left: 1.2em; }
.fx-toc-level-3 { padding-left: 2.4em; font-size: 0.95em; }
.fx-toc-level-4, .fx-toc-level-5, .fx-toc-level-6 { padding-left: 3.6em; font-size: 0.9em; }

.fx-children { margin: 0 0 1.5em; }
.fx-children-title { font-family: var(--fx-font-heading); font-weight: 650; margin-bottom: 0.5em; }
.fx-children ul { list-style: none; padding: 0; margin: 0; }
.fx-children ul ul { padding-left: 1.2em; font-size: 0.95em; }
.fx-children li { margin: 0.2em 0; }
.fx-children a { color: inherit; text-decoration: none; }
.fx-children a:hover { color: var(--fx-color-accent); }
.fx-children-empty { color: var(--fx-color-muted); }
/* A subfolder with pages under it folds. The arrow sits in front of its name; other rows keep the same room. */
.fx-children summary { display: flex; align-items: center; cursor: pointer; list-style: none; }
.fx-children summary::-webkit-details-marker { display: none; }
.fx-children summary::before {
  content: "";
  flex: none;
  width: 0.4em;
  height: 0.4em;
  margin: 0 0.5em 0 0.1em;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(-45deg);
  opacity: 0.6;
  transition: transform 120ms;
}
.fx-children details[open] > summary::before { transform: rotate(45deg); }
.fx-children-tree li > a { margin-left: 1em; }

.fx-image { text-align: center; }
.fx-image.fx-align-left { text-align: left; }
.fx-image.fx-align-right { text-align: right; }
.fx-image img { display: inline-block; height: auto; }
/* Pictures in the document take the theme's image radius, 3px when the theme doesn't set one. A template's own images (a cover or footer logo) don't. */
.fx-image img,
.fx-md img,
.fx-section > :not(.fx-running-header, .fx-running-footer) img {
  border-radius: var(--fx-image-radius, 3px);
}

/*
 * A block written with {width="wide"} or {width="full"}, or a markdown element under a <!-- {width="..."} --> comment
 * (block-width.ts), on screen: in the app's infinite layout and on an exported site. A markdown element sits inside a
 * run of .fx-md, which is as wide as the column, so it measures the same way a block does.
 *
 * The room is --fx-room, the width of the scroll area inside its padding, which DocView.tsx measures; on a site page
 * it's the main column, an inline-size container. Either way a sidebar or the block panel never counts as room. The
 * app's scroll area isn't a container, because containment would also make it the box position: fixed is placed in.
 * Full is all of the room. Wide is halfway between the text column and full, as it's halfway into the margins on
 * paper, and no wider than --fx-width-wide. Narrow is a fixed size that doesn't follow the room: the column less what
 * wide adds at its widest, so 400px against a 680px column, and never less than half the column. The element stays centred on the text column. The paginated layout's rules are in print-base.css.
 */
.fx-doc:not(.fx-print) > [data-fx-width],
.fx-doc:not(.fx-print) > .fx-md > [data-fx-width] {
  --fx-width-to: var(--fx-room, 100cqi);
  box-sizing: border-box;
  width: max(100%, var(--fx-width-to));
  max-width: none;
  margin-left: min(0px, calc((100% - var(--fx-width-to)) / 2));
}
.fx-doc:not(.fx-print) > [data-fx-width="wide"],
.fx-doc:not(.fx-print) > .fx-md > [data-fx-width="wide"] {
  --fx-width-to: min(var(--fx-width-wide, 960px), (100% + var(--fx-room, 100cqi)) / 2);
}
.fx-doc:not(.fx-print) > [data-fx-width="narrow"],
.fx-doc:not(.fx-print) > .fx-md > [data-fx-width="narrow"] {
  --fx-width-to: max(50%, 200% - var(--fx-width-wide, 960px));
  width: var(--fx-width-to);
  /* Auto rather than worked out from the width: a table whose cells can't wrap any narrower is wider than it's told to
     be, and auto margins centre the box it actually gets. */
  margin-left: auto;
  margin-right: auto;
}

/*
 * A header image: an image block set to full width that's the first thing in the document. It runs up to the top of the
 * view and out to its sides, through the padding around the document, the way a cover does, and its corners are square
 * there. --fx-room-top and --fx-room-side are that padding, set by whoever draws the room (app.css, site.css); with
 * neither it's an ordinary full-width image. On paper it fills the head of its page, up to the sheet's printable edge
 * (print-base.css).
 */
.fx-doc:not(.fx-print) > [data-fx-width="full"]:first-child:has(> .fx-image) {
  --fx-width-to: calc(var(--fx-room, 100cqi) + 2 * var(--fx-room-side, 0px));
  margin-top: calc(-1 * var(--fx-room-top, 0px));
}
.fx-doc:not(.fx-print) > [data-fx-width="full"]:first-child:has(> .fx-image) > .fx-image img {
  border-radius: 0;
}

/*
 * A <!-- {width="..."} --> comment with no element directly below it (doc.ts): shown as its text, faintly, so it can be
 * found and deleted. It's left out of PDFs and exported sites before it gets here.
 */
.fx-doc .fx-detached-attributes {
  opacity: 0.3;
}

/* Blocks that could not run */
.fx-block-placeholder {
  border: 1px dashed var(--fx-color-border);
  border-radius: var(--fx-radius);
  padding: 0.8em 1em;
  color: var(--fx-color-muted);
  font-size: 0.85em;
  margin: 0 0 1em;
}
.fx-block-error {
  border: 1px solid #f0c4bb;
  background: #fbece9;
  color: #9b2c1b;
  border-radius: var(--fx-radius);
  padding: 0.7em 1em;
  font-size: 0.85em;
  margin: 0 0 1em;
}
.fx-block-error ul { margin: 0.3em 0 0; padding-left: 1.2em; }

/*
 * Callouts: `> [!type] Title` in markdown, or the callout core block. Themes recolour through --fx-callout-color.
 * Every core block rule below carries .fx-doc, so it outranks the element rules above (.fx-doc h3, .fx-doc p).
 */

.fx-doc .fx-callout {
  --fx-callout-color: var(--fx-color-accent);
  margin: 0 0 1em;
  padding: 0.7em 1em 0.75em;
  border-left: 3px solid var(--fx-callout-color);
  border-radius: 0 var(--fx-radius) var(--fx-radius) 0;
  background: color-mix(in srgb, var(--fx-callout-color) 9%, transparent);
  break-inside: avoid;
}
.fx-doc .fx-callout-title {
  display: flex;
  align-items: center;
  gap: 0.45em;
  margin: 0;
  font-weight: 650;
  color: var(--fx-callout-color);
}
.fx-doc .fx-callout-title::before {
  content: "";
  flex: none;
  width: 1.1em;
  height: 1.1em;
  background: currentColor;
  /* Longhands on purpose: the CSS minifier drops a var() inside the mask shorthand. */
  -webkit-mask-image: var(--fx-callout-icon);
  mask-image: var(--fx-callout-icon);
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-position: center;
  mask-position: center;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
}
.fx-doc .fx-callout-body { margin-top: 0.4em; }
.fx-doc .fx-callout-body > :last-child { margin-bottom: 0; }
.fx-doc .fx-callout-body > :is(p, ul, ol, blockquote, pre, table, figure, .fx-doc .fx-callout) { margin-bottom: 0.6em; }
.fx-doc .fx-callout .fx-callout { margin-top: 0.6em; }

.fx-doc details.fx-callout > summary { cursor: pointer; list-style: none; }
.fx-doc details.fx-callout > summary::-webkit-details-marker { display: none; }
.fx-doc details.fx-callout > summary::after {
  content: "";
  width: 0.5em;
  height: 0.5em;
  margin-left: auto;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(-45deg);
  transition: transform 120ms;
  opacity: 0.7;
}
.fx-doc details.fx-callout[open] > summary::after { transform: rotate(45deg); }

/* Icons after Lucide (ISC). Only their shape is used: the colour is the title's. */
.fx-doc .fx-callout-note, .fx-doc .fx-callout-info, .fx-doc .fx-callout-todo { --fx-callout-color: #2f7bd8; }
.fx-doc .fx-callout-abstract, .fx-doc .fx-callout-tip { --fx-callout-color: #0f9f92; }
.fx-doc .fx-callout-success { --fx-callout-color: #1f9d55; }
.fx-doc .fx-callout-question, .fx-doc .fx-callout-warning { --fx-callout-color: #d97a12; }
.fx-doc .fx-callout-failure, .fx-doc .fx-callout-danger, .fx-doc .fx-callout-bug { --fx-callout-color: #d63a4a; }
.fx-doc .fx-callout-example { --fx-callout-color: #7c5ce6; }
.fx-doc .fx-callout-quote { --fx-callout-color: var(--fx-color-muted); }

.fx-doc .fx-callout-note { --fx-callout-icon: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M12 20h9'/><path d='M16.5 3.5a2.1 2.1 0 0 1 3 3L7 19l-4 1 1-4Z'/></svg>"); }
.fx-doc .fx-callout-abstract { --fx-callout-icon: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><rect x='8' y='2' width='8' height='4' rx='1'/><path d='M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2'/><path d='M12 11h4'/><path d='M12 16h4'/><path d='M8 11h.01'/><path d='M8 16h.01'/></svg>"); }
.fx-doc .fx-callout-info { --fx-callout-icon: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='10'/><path d='M12 16v-4'/><path d='M12 8h.01'/></svg>"); }
.fx-doc .fx-callout-todo { --fx-callout-icon: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='10'/><path d='m9 12 2 2 4-4'/></svg>"); }
.fx-doc .fx-callout-tip { --fx-callout-icon: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M9 18h6'/><path d='M10 22h4'/><path d='M15.1 14c.2-1 .7-1.7 1.4-2.5A4.6 4.6 0 0 0 18 8a6 6 0 0 0-12 0c0 1 .2 2.2 1.5 3.5.8.8 1.2 1.5 1.4 2.5'/></svg>"); }
.fx-doc .fx-callout-success { --fx-callout-icon: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M20 6 9 17l-5-5'/></svg>"); }
.fx-doc .fx-callout-question { --fx-callout-icon: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='10'/><path d='M9.1 9a3 3 0 0 1 5.8 1c0 2-3 3-3 3'/><path d='M12 17h.01'/></svg>"); }
.fx-doc .fx-callout-warning { --fx-callout-icon: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='m21.7 18-8-14a2 2 0 0 0-3.5 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.7-3Z'/><path d='M12 9v4'/><path d='M12 17h.01'/></svg>"); }
.fx-doc .fx-callout-failure { --fx-callout-icon: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M18 6 6 18'/><path d='m6 6 12 12'/></svg>"); }
.fx-doc .fx-callout-danger { --fx-callout-icon: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M13 2 3 14h9l-1 8 10-12h-9l1-8z'/></svg>"); }
.fx-doc .fx-callout-bug { --fx-callout-icon: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M8 2l1.9 1.9'/><path d='M16 2l-1.9 1.9'/><path d='M9 7.1V6a3 3 0 0 1 6 0v1.1'/><path d='M12 20a6 6 0 0 1-6-6v-2a6 6 0 0 1 12 0v2a6 6 0 0 1-6 6Z'/><path d='M12 20v-9'/><path d='M6.5 9H3'/><path d='M6 13H2'/><path d='M3 21c0-2.1 1.7-3.9 3.8-4'/><path d='M17.5 9H21'/><path d='M18 13h4'/><path d='M21 21c0-2.1-1.7-3.9-3.8-4'/></svg>"); }
.fx-doc .fx-callout-example { --fx-callout-icon: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M8 6h13'/><path d='M8 12h13'/><path d='M8 18h13'/><path d='M3 6h.01'/><path d='M3 12h.01'/><path d='M3 18h.01'/></svg>"); }
.fx-doc .fx-callout-quote { --fx-callout-icon: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M10 11H6a2 2 0 0 1-2-2V7a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v6a4 4 0 0 1-4 4'/><path d='M20 11h-4a2 2 0 0 1-2-2V7a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v6a4 4 0 0 1-4 4'/></svg>"); }

/* Columns: a grid of items, each its own element. */

.fx-doc .fx-columns {
  /* One source of spacing for both layouts: grid gap can't reach a multi-column box. */
  --fx-columns-gap-y: 0.8em;
  --fx-columns-gap-x: 1.2em;
  display: grid;
  gap: var(--fx-columns-gap-y) var(--fx-columns-gap-x);
  margin: 0 0 1em;
}
/* An item fills its row, so a card next to a longer one is the same height rather than ragged. */
.fx-doc .fx-column-item {
  display: flex;
  flex-direction: column;
  min-width: 0;
  break-inside: avoid;
}
.fx-doc .fx-column-item > .fx-card { flex: 1; }

/*
 * Staggered: the block deals its items into one stack per column, so every column starts at the top of the block and
 * each item is only as tall as its content. The columns pack tight and end wherever their last item does.
 */
.fx-doc .fx-columns-staggered > .fx-column {
  display: flex;
  flex-direction: column;
  align-content: start;
  gap: var(--fx-columns-gap-y);
  min-width: 0;
}

/* Cards: a box around markdown. What's inside is the theme's business. */

.fx-doc .fx-card {
  border: 1px solid var(--fx-color-border);
  border-radius: var(--fx-radius);
  padding: 0.8em 1em;
  margin: 0 0 1em;
  break-inside: avoid;
}
.fx-doc .fx-column-item > .fx-card { margin-bottom: 0; }
.fx-doc .fx-card > :first-child { margin-top: 0; }
.fx-doc .fx-card > :last-child { margin-bottom: 0; }
.fx-doc .fx-card :is(h1, h2, h3, h4, h5, h6) { font-size: 1.05em; margin: 0 0 0.35em; }
.fx-doc .fx-card p { font-size: 0.92em; color: var(--fx-color-muted); margin-bottom: 0.5em; }
/* Cards sit closer than text does. Set as the variables, so a block's own rowGap and columnGap still win. */
.fx-doc .fx-columns:has(> .fx-column-item > .fx-card) { --fx-columns-gap-y: 0.5em; --fx-columns-gap-x: 0.8em; }
