/* Classic — the article body itself.
 *
 * Loaded twice on purpose: by the public article page, and by TinyMCE as its `content_css`, so
 * an editor sees the published formatting while writing. Everything here is therefore scoped to
 * `.article-body`, which is also the editor's `body_class`, and depends only on tokens that
 * base/base.css defines — nothing outside this file may be assumed to exist.
 */

.article-body {
    max-width: var(--theme-text-width, 44rem);
    color: var(--fg, #16181c);
    /* Inherited on the page anyway; spelled out for the editor's iframe, which has no base.css. */
    font-family: var(--font-body, system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif);
    font-size: var(--step-1, 1.15rem);
    line-height: 1.7;
}

/* Spacing is set with margin-top alone. The browser's default paragraph and heading margins are
 * cleared first, or they collapse with these and every gap ends up the larger of the two. */
.article-body > * {
    margin-block: 0;
}

.article-body > * + * {
    margin-top: 1em;
}

.article-body h2,
.article-body h3,
.article-body h4 {
    /* In the heading's own em, so an h2 gets about 1.9rem above it, an h3 about 1.4rem. */
    margin-top: 1.1em;
    margin-bottom: 0;
    font-family: var(--font-heading, system-ui, sans-serif);
    line-height: 1.25;
    letter-spacing: -0.015em;
}

.article-body h2 {
    font-size: 1.6em;
}

.article-body h3 {
    font-size: 1.25em;
}

.article-body > :is(h2, h3, h4) + * {
    margin-top: 0.5em;
}

.article-body h4 {
    font-size: 1.05em;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--fg-muted, #5c6370);
}

.article-body a {
    color: var(--accent, #1d4ed8);
    text-underline-offset: 0.15em;
}

.article-body ul,
.article-body ol {
    padding-left: 1.4em;
}

.article-body li + li {
    margin-top: 0.4em;
}

.article-body blockquote {
    margin-inline: 0;
    padding-left: 1.1em;
    border-left: 3px solid var(--accent, #1d4ed8);
    color: var(--fg-muted, #5c6370);
    font-style: italic;
}

.article-body figure {
    margin-inline: 0;
}

.article-body img {
    display: block;
    width: 100%;
    height: auto;
    border-radius: var(--radius, 0.375rem);
    background: var(--bg-sunken, #eceef1);
}

.article-body figcaption {
    margin-top: 0.5em;
    font-size: 0.8em;
    color: var(--fg-muted, #5c6370);
}

/* A body image's caption and credit come from the library at render time, in the hero's markup:
 * a dot between them only when both are there. */
.article-body figcaption .caption + .credit::before {
    content: " · ";
}

/* A narrow picture — a program's side panel, a phone screen — at its own size, centred, rather
 * than stretched across the column: `panel` on the figure, or on the image (the editor's image
 * dialog, *Class*). `revert-layer` gives the width back to the image's `width` attribute, which
 * the renderer writes, so a lazy image's box is reserved before it arrives. Never wider than the
 * smallest body rendition (480 px): a screenshot narrower than that is shown pixel for pixel. The
 * figure shrinks to the picture and the caption wraps under it; on a phone the column wins. */
.article-body :is(figure.panel, figure:has(img.panel)) {
    width: fit-content;
    max-width: 30rem;
    margin-inline: auto;
}

.article-body :is(.panel img, img.panel) {
    width: revert-layer;
    max-width: min(100%, 30rem);
    margin-inline: auto;
}

.article-body :is(.panel, figure:has(img.panel)) > figcaption {
    contain: inline-size;
}

.article-body code,
.article-body pre {
    font-family: var(--font-mono, ui-monospace, monospace);
    font-size: 0.9em;
}

.article-body code {
    padding: 0.1em 0.3em;
    border-radius: 0.2em;
    background: var(--bg-sunken, #eceef1);
}

.article-body pre {
    overflow-x: auto;
    padding: 1em;
    border-radius: var(--radius, 0.375rem);
    background: var(--bg-sunken, #eceef1);
}

.article-body pre code {
    padding: 0;
    background: none;
}

/* A table stays a table, here and in the editor (TinyMCE selects and resizes its cells). One
 * wider than the measure scrolls in the box the renderer puts around it, styled by base.css. */
.article-body table {
    border-collapse: collapse;
}

.article-body th,
.article-body td {
    padding: 0.5em 0.7em;
    border: 1px solid var(--line, #d7dae0);
    text-align: left;
    vertical-align: top;
}

.article-body th {
    background: var(--bg-sunken, #eceef1);
}

.article-body hr {
    border: 0;
    border-top: 1px solid var(--line, #d7dae0);
}

/* Placeholders the pipeline leaves behind. A link card whose preview has not arrived — and every
 * embed, until ED-05 is built — holds the plain link it was made from, so it must read as
 * content, not as a broken widget. */
.article-body [data-link-card],
.article-body [data-embed] {
    padding: 0.9em 1.1em;
    border: 1px solid var(--line, #d7dae0);
    border-radius: var(--radius, 0.375rem);
    background: var(--bg-raised, #f6f7f9);
}

/* A resolved link card (ED-03): the picture beside what the page says about itself. The card is
 * one link, so the whole thing reacts, and its padding comes from the placeholder rule above. */
.article-body .link-card {
    padding: 0;
    overflow: hidden;
}

.article-body .link-card__link {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 0;
    color: inherit;
    text-decoration: none;
}

.article-body .link-card__link:hover .link-card__title,
.article-body .link-card__link:focus-visible .link-card__title {
    text-decoration: underline;
}

.article-body .link-card__media {
    display: block;
    position: relative;
}

.article-body .link-card__image {
    display: block;
    width: 100%;
    height: 100%;
    aspect-ratio: 16 / 9;
    object-fit: cover;
    margin: 0;
    border-radius: 0;
}

.article-body .link-card__text {
    display: block;
    padding: 0.9em 1.1em;
}

.article-body .link-card__site {
    display: block;
    font-size: 0.8em;
    color: var(--fg-muted, #5c6370);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.article-body .link-card__title {
    display: block;
    margin-top: 0.15em;
    font-family: var(--font-heading, inherit);
    font-weight: 600;
    line-height: 1.3;
}

.article-body .link-card__description {
    display: block;
    margin-top: 0.35em;
    font-size: 0.9em;
    color: var(--fg-muted, #5c6370);
}

/* Said for anyone reading the page aloud; the card's look already says it to everyone else. */
.article-body .link-card__hint {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* Wide enough for two columns: the picture keeps a fixed measure beside the text. Only a card
 * that has a picture: without one the text would be the first cell and get the picture's width. */
@media (min-width: 30rem) {
    .article-body .link-card__link:has(> .link-card__media) {
        grid-template-columns: 13.75rem minmax(0, 1fr);
        align-items: stretch;
    }

    .article-body .link-card__media {
        height: 100%;
    }
}

/* A card standing in for a video (ED-05 is not built yet, see rendering/cards.py). The still is
 * the video's own thumbnail, so it needs a play glyph to read as a video rather than a photo:
 * a dark disc and a triangle, both drawn — no icon font and no image request. They hang off the
 * picture's wrapper, so a card whose picture could not be fetched simply has no glyph. */
.article-body .link-card--video .link-card__media::before,
.article-body .link-card--video .link-card__media::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    pointer-events: none;
}

.article-body .link-card--video .link-card__media::before {
    width: 3rem;
    height: 3rem;
    margin: -1.5rem 0 0 -1.5rem;
    border-radius: 50%;
    background: rgba(17, 19, 23, 0.72);
}

.article-body .link-card--video .link-card__media::after {
    width: 0;
    height: 0;
    /* A triangle from borders, nudged right so it looks centred inside the disc. */
    margin: -0.55rem 0 0 -0.35rem;
    border-top: 0.55rem solid transparent;
    border-bottom: 0.55rem solid transparent;
    border-left: 0.95rem solid #ffffff;
}
