/* Markdown content styling — consumes portal tokens only. */
.markdown-body {
  font-family: var(--portal-font);
  color: var(--portal-color-body);
  /* 1rem rather than MudBlazor's inherited 14px. 14px is a UI scale — right for a chip or
     a nav item, small for a page someone reads end to end. */
  font-size: 1rem;
  max-width: var(--portal-prose-width);
  line-height: 1.6;
}

/* Line length is capped on the blocks, not on the article, so that tables can still use
   the whole column. At 14px in a 1152px column a paragraph ran 177 characters per line,
   which is why the measure is 1rem text, not 14px. Code fences share the measure: left to
   stretch they filled the column while the prose beside them did not, which read as a
   full-bleed band across the page. Direct children only, so a paragraph nested in a list
   or a callout takes its container's width rather than being capped twice. */
.markdown-body > p,
.markdown-body > ul,
.markdown-body > ol,
.markdown-body > dl,
.markdown-body > pre,
.markdown-body > blockquote,
.markdown-body > figure,
.markdown-body > hr,
.markdown-body > h1,
.markdown-body > h2,
.markdown-body > h3,
.markdown-body > h4,
.markdown-body > h5,
.markdown-body > h6 {
  max-width: var(--portal-prose-width);
}
/* The heading rule below gives every heading a 1.2em top margin to separate sections.
   On the first element that margin has nothing to separate from and just opens a gap
   under the app bar, so collapse it. Scoped to the first child so later headings keep
   their separation. */
.markdown-body > :first-child {
  margin-top: 0;
}
.markdown-body > :last-child {
  margin-bottom: 0;
}

/* Block rhythm. MudBlazor's reset zeroes the margins and list padding these would
   otherwise take from the UA stylesheet, which ran paragraphs and lists together and
   left list markers with no indent to sit in. */
.markdown-body p,
.markdown-body ul,
.markdown-body ol {
  margin: 0 0 1em;
}
.markdown-body ul,
.markdown-body ol {
  padding-left: 1.5em;
}
.markdown-body li + li {
  margin-top: 0.35em;
}
/* A nested list belongs to its parent item, so it sits tight rather than a block apart. */
.markdown-body li > ul,
.markdown-body li > ol {
  margin: 0.35em 0 0;
}
/* Headings take the top of the ramp, prose the middle — see tokens.css. Size alone was
   carrying the whole hierarchy before, which on a long page reads as one undifferentiated
   block of white. */
.markdown-body h1, .markdown-body h2, .markdown-body h3 {
  color: var(--portal-color-heading);
  margin: 1.2em 0 0.5em;
  /* A section opened from the rail or a deep link lands below the fixed app bar, not under it. */
  scroll-margin-top: calc(var(--mud-appbar-height, 64px) + 1rem);
}
.markdown-body h1 { font-size: 2rem; letter-spacing: -0.01em; }

/* The rule under a section is the one place a hue helps: it marks the boundary without
   colouring any text, so it cannot be mistaken for a link. */
.markdown-body h2 {
  font-size: 1.5rem;
  border-bottom: 1px solid color-mix(in srgb, var(--portal-color-primary) 35%, var(--portal-color-border));
  padding-bottom: 0.3em;
}
.markdown-body a { color: var(--portal-color-primary); }
.markdown-body code {
  font-family: var(--portal-font-code);
  background: var(--mud-palette-background-gray);
  border-radius: var(--portal-radius);
  padding: 0.15em 0.4em;
  font-size: 0.9em;
}
.markdown-body pre {
  background: var(--mud-palette-background-gray);
  border: 1px solid var(--portal-color-border);
  border-radius: var(--portal-radius);
  padding: 1em;
  overflow-x: auto;
}
.markdown-body pre code { background: none; padding: 0; }
.markdown-body table { border-collapse: collapse; margin: 1em 0; }
.markdown-body th, .markdown-body td {
  border: 1px solid var(--portal-color-border);
  padding: 0.4em 0.8em;
}
/* A table header is a label, not prose, so it takes the heading step. */
.markdown-body th { color: var(--portal-color-heading); }

/* Definition terms are the heading of their own little section. */
.markdown-body dt { color: var(--portal-color-heading); }

/* Both pipelines run Markdig's full advanced set, and neither sanitizes any more, so
   classes survive — see the ::: containers further down. Element selectors still do most
   of the work here, because ordinary Markdown produces no classes to hook. */

.markdown-body h4, .markdown-body h5, .markdown-body h6 {
  color: var(--portal-color-heading);
  margin: 1.2em 0 0.5em;
  font-size: 1.05rem;
}
/* Below h4 a heading is doing less work than the prose under it, so it steps down rather
   than up — the only place in the ramp where a heading is dimmer than body text. */
.markdown-body h5, .markdown-body h6 {
  font-size: 1rem;
  color: var(--portal-color-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

/* The plain callout. A blockquote is the one an author reaches for without thinking, so
   it stays styled as an aside; the typed containers below are for when the kind matters. */
.markdown-body blockquote {
  margin: 1em 0;
  padding: 0.6em 1em;
  border-left: 3px solid var(--portal-color-primary);
  background: var(--mud-palette-background-gray);
  border-radius: 0 var(--portal-radius) var(--portal-radius) 0;
}
.markdown-body blockquote > :first-child { margin-top: 0; }
.markdown-body blockquote > :last-child { margin-bottom: 0; }

/* Typed callouts, written as Markdig custom containers:
 *
 *     :::warning
 *     Reusing a key with a different body fails 422.
 *     :::
 *
 * The container's name becomes the div's class, which is only useful now that neither
 * pipeline sanitizes — until then the class was stripped and every container rendered as
 * an anonymous div. The label is generated from the type rather than typed by the author,
 * so a callout cannot say "Warning" while being styled as a tip.
 *
 * These need their own max-width: the prose cap is applied by element, and a container is
 * a div, which is not in that list. */
.markdown-body .note,
.markdown-body .tip,
.markdown-body .info,
.markdown-body .warning,
.markdown-body .danger {
  --callout-accent: var(--portal-color-primary);
  max-width: var(--portal-prose-width);
  margin: 1.5em 0;
  padding: 0.9em 1.1em;
  border-left: 3px solid var(--callout-accent);
  border-radius: 0 var(--portal-radius) var(--portal-radius) 0;
  background: color-mix(in srgb, var(--callout-accent) 8%, var(--mud-palette-background-gray));
}

.markdown-body .note::before,
.markdown-body .tip::before,
.markdown-body .info::before,
.markdown-body .warning::before,
.markdown-body .danger::before {
  display: block;
  margin-bottom: 0.4em;
  color: var(--callout-accent);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.markdown-body .note::before { content: "Note"; }
.markdown-body .tip::before { content: "Tip"; }
.markdown-body .info::before { content: "Good to know"; }
.markdown-body .warning::before { content: "Warning"; }
.markdown-body .danger::before { content: "Careful"; }

.markdown-body .tip { --callout-accent: var(--mud-palette-success); }
.markdown-body .info { --callout-accent: var(--mud-palette-info); }
.markdown-body .warning { --callout-accent: var(--mud-palette-warning); }
.markdown-body .danger { --callout-accent: var(--mud-palette-error); }

.markdown-body .note > :first-child,
.markdown-body .tip > :first-child,
.markdown-body .info > :first-child,
.markdown-body .warning > :first-child,
.markdown-body .danger > :first-child { margin-top: 0; }
.markdown-body .note > :last-child,
.markdown-body .tip > :last-child,
.markdown-body .info > :last-child,
.markdown-body .warning > :last-child,
.markdown-body .danger > :last-child { margin-bottom: 0; }

/* A grid of cards, for the "where to go next" shape that reads badly as a list:
 *
 *     ::::grid
 *     :::card
 *     ### Authentication
 *     Tokens, scopes and environments.
 *     :::
 *     ::::
 *
 * Four colons on the outside: Markdig closes a container on the first fence of matching
 * length, so a grid of three-colon cards has to be fenced with more. auto-fit rather than
 * a fixed column count, so the same markup is a row on a monitor and a stack on a phone
 * without a breakpoint. */
.markdown-body .grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  gap: 1rem;
  max-width: var(--portal-prose-width);
  margin: 1.5em 0;
}

.markdown-body .card {
  padding: 1rem 1.1rem;
  border: 1px solid var(--portal-color-border);
  border-radius: var(--portal-radius);
  background: var(--mud-palette-surface);
}

.markdown-body .card:hover {
  border-color: color-mix(in srgb, var(--portal-color-primary) 45%, var(--portal-color-border));
}

/* A card's heading is a label for the card, not a section of the page, so it drops to the
   size of the text beside it and loses the h2 rule. */
.markdown-body .card h2,
.markdown-body .card h3,
.markdown-body .card h4 {
  margin: 0 0 0.4em;
  font-size: 1rem;
  border-bottom: none;
  padding-bottom: 0;
}

.markdown-body .card > :first-child { margin-top: 0; }
.markdown-body .card > :last-child { margin-bottom: 0; }

/* Numbered steps. The list inside is an ordinary Markdown ordered list — the container
 * only changes how it is drawn, so the source stays readable and the numbers stay the
 * list's own rather than being typed by the author:
 *
 *     :::steps
 *     1. Register an application.
 *     2. Exchange the credentials for a token.
 *     :::
 */
.markdown-body .steps {
  max-width: var(--portal-prose-width);
  margin: 1.5em 0;
}

.markdown-body .steps ol {
  margin: 0;
  padding-left: 0;
  list-style: none;
  counter-reset: step;
}

/* The border is the connecting line between markers; the last item drops it so the line
   stops at the final step rather than trailing past it. */
.markdown-body .steps ol > li {
  counter-increment: step;
  position: relative;
  margin: 0 0 0 0.9rem;
  padding: 0 0 1.4em 2.2rem;
  border-left: 1px solid var(--portal-color-border);
}

.markdown-body .steps ol > li:last-child {
  border-left-color: transparent;
  padding-bottom: 0;
}

.markdown-body .steps ol > li::before {
  content: counter(step);
  position: absolute;
  left: -0.9rem;
  top: -0.2em;
  display: grid;
  place-items: center;
  width: 1.75rem;
  height: 1.75rem;
  border: 1px solid var(--portal-color-border);
  border-radius: 50%;
  background: var(--mud-palette-background-gray);
  color: var(--portal-color-heading);
  font-size: 0.8rem;
  font-weight: 700;
}

.markdown-body .steps ol > li > :first-child { margin-top: 0; }

/* Tabbed panels. Each tab's own first heading names it — the container syntax drops
 * anything written after the name, so the label has to come from the content:
 *
 *     ::::tabs
 *     :::tab
 *     #### C#
 *     …
 *     :::
 *     ::::
 *
 * portal-markdown.js lifts those headings into the bar. Until it runs — or if it never
 * does — the panels are stacked sections under their own headings, which is a worse
 * layout but a complete one. */
.markdown-body .tabs {
  max-width: var(--portal-prose-width);
  margin: 1.5em 0;
}

.markdown-body .tabs-bar {
  display: flex;
  gap: 0.25rem;
  margin-bottom: 1em;
  border-bottom: 1px solid var(--portal-color-border);
}

.markdown-body .tabs-bar button {
  padding: 0.5rem 0.9rem;
  border: none;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  background: none;
  color: var(--portal-color-muted);
  font: inherit;
  font-size: 0.9rem;
  cursor: pointer;
}

.markdown-body .tabs-bar button:hover { color: var(--portal-color-body); }

.markdown-body .tabs-bar button[aria-selected="true"] {
  color: var(--portal-color-primary);
  border-bottom-color: var(--portal-color-primary);
}

.markdown-body .tab > :first-child { margin-top: 0; }
.markdown-body .tab > :last-child { margin-bottom: 0; }

/* Mathematics. Markdig emits the TeX still wrapped in its delimiters and KaTeX replaces
   it in place, so an unrendered formula shows its source rather than disappearing. */
.markdown-body span.math { overflow-x: auto; }

.markdown-body div.math {
  max-width: var(--portal-prose-width);
  margin: 1.5em 0;
  overflow-x: auto;
  text-align: center;
}

.markdown-body hr {
  margin: 2em 0;
  border: 0;
  border-top: 1px solid var(--portal-color-border);
}

/* A wide table must scroll inside its own box rather than widening the page. */
.markdown-body table {
  display: block;
  max-width: 100%;
  overflow-x: auto;
}
.markdown-body th { text-align: left; background: var(--mud-palette-background-gray); }

/* Definition lists carry the status glossaries. */
.markdown-body dt { font-weight: 600; font-family: var(--portal-font-code); margin-top: 0.9em; }
.markdown-body dd { margin: 0.2em 0 0 1.5em; color: var(--portal-color-body); }

/* Task lists: the checkbox input is the only marker left after sanitizing, so key the
   bullet removal off it rather than off Markdig's stripped class. */
.markdown-body li:has(> input[type="checkbox"]) { list-style: none; margin-left: -1.2em; }
.markdown-body input[type="checkbox"] { margin-right: 0.5em; accent-color: var(--portal-color-primary); }

.markdown-body abbr[title] { text-decoration: underline dotted; cursor: help; }
.markdown-body mark { background: var(--mud-palette-primary-hover); color: var(--portal-color-text); padding: 0 0.2em; }
.markdown-body ins { text-decoration: none; border-bottom: 1px solid var(--portal-color-primary); }
.markdown-body del { color: var(--portal-color-muted); }
.markdown-body sup, .markdown-body sub { font-size: 0.75em; }

.markdown-body img { max-width: 100%; height: auto; border-radius: var(--portal-radius); }
.markdown-body figure { margin: 1.5em 0; }
.markdown-body figcaption { color: var(--portal-color-muted); font-size: 0.9em; margin-top: 0.5em; }

/* Prose diff (docs/reference/devportal.md#docs-diff). Scoped to .prose-diff so it outranks the plain ins/del rules
   above, which exist for a document that uses those tags as prose. Colour is never the only
   channel — an underline and a strikethrough survive a colour-blind reader and a monochrome
   print — and the accents are the ones the callouts already use rather than a second palette. */
.markdown-body.prose-diff ins {
  background: color-mix(in srgb, var(--mud-palette-success) 20%, transparent);
  color: var(--portal-color-heading);
  border-bottom: 0;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}

.markdown-body.prose-diff del {
  background: color-mix(in srgb, var(--mud-palette-error) 18%, transparent);
  color: var(--portal-color-muted);
  text-decoration: line-through;
}

/* A wholly added or removed paragraph reads better with room around it than as a solid band. */
.markdown-body.prose-diff p > ins:only-child,
.markdown-body.prose-diff p > del:only-child {
  display: block;
  padding: 0.25em 0.5em;
  border-radius: var(--portal-radius);
}
