/* rt-base.css — the base of every robotap theme.
 *
 * Layers, lowest to highest. CSS outside any layer (your own) beats all of them, so you never need !important:
 *   rt-tokens      the variables: colours by ROLE, sizes, motion. A theme is mostly a different set of these.
 *   rt-base        elements and tones (what a thing means: info, positive, warning, danger, important).
 *   rt-components  table, badge, button, tabs, popup.
 *   rt-theme       what a theme package adds on top.
 *
 * Colour is never named after the colour: a row is not "red", it has the tone "danger". The data says what it means
 * (a column, usually computed), the theme says what that looks like.
 */
@layer rt-tokens, rt-base, rt-components, rt-theme;

/* ---- tokens ------------------------------------------------------------------------------------------------ */
@layer rt-tokens {
    :root {
        color-scheme: light dark;                       /* follows the system; [data-theme="light|dark"] on <html> forces one */

        --rt-surface:   light-dark(#ffffff, #171923);
        --rt-surface-2: light-dark(#f6f7f9, #1e212d);   /* raised or striped areas */
        --rt-text:      light-dark(#1f2328, #e5e7eb);
        --rt-muted:     light-dark(#6b7280, #9aa4b2);
        --rt-border:    light-dark(#e5e7eb, #2b3040);
        --rt-accent:    light-dark(#5b4bdb, #8b7cf8);
        --rt-on-accent: light-dark(#ffffff, #12131a);

        /* the tones */
        --rt-info:      light-dark(#2563eb, #60a5fa);
        --rt-positive:  light-dark(#15803d, #4ade80);
        --rt-warning:   light-dark(#b45309, #fbbf24);
        --rt-danger:    light-dark(#dc2626, #f87171);
        --rt-important: light-dark(#7c3aed, #c4b5fd);

        --rt-radius: .5rem;
        --rt-gap: .5rem;
        --rt-density: .5rem .75rem;                     /* cell padding: compact = .25rem .5rem */
        --rt-zebra: transparent;                        /* the background of every second row of a table or list; a theme can set it for all (var(--rt-surface-2)), `data-zebra` turns it on for one */
        --rt-table-height: 70vh;                        /* how high a table with a sticky header (`data-sticky="header"`) is before it scrolls */
        --rt-font: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
        --rt-font-size: .9375rem;
        --rt-line: 1.45;
        --rt-shadow: 0 1px 2px rgb(0 0 0 / .06), 0 10px 28px -14px rgb(0 0 0 / .28);
        --rt-speed: 150ms;                              /* every transition uses this: 0 turns the motion off */

        /* derived: change the roles above, these follow */
        --rt-hover: color-mix(in oklab, var(--rt-accent) 7%, var(--rt-surface));
        --rt-selected: color-mix(in oklab, var(--rt-accent) 14%, var(--rt-surface));

        /* the names used before the roles existed */
        --rt-fg: var(--rt-text);
        --rt-bg: var(--rt-surface);
    }
    :root[data-theme="light"] { color-scheme: light; }
    :root[data-theme="dark"]  { color-scheme: dark; }

    @media (prefers-reduced-motion: reduce) {
        :root { --rt-speed: 0ms; }
    }
}

/* ---- base: elements and tones ------------------------------------------------------------------------------ */
@layer rt-base {
    :where([data-rt]) {
        color: var(--rt-text);
        font: var(--rt-font-size)/var(--rt-line) var(--rt-font);
    }
    :where([data-rt] :focus-visible) {
        outline: 2px solid color-mix(in oklab, var(--rt-accent) 70%, transparent);
        outline-offset: 2px;
    }
    :where([data-rt] a) { color: var(--rt-accent); text-decoration: none; }
    :where([data-rt] a:hover) { text-decoration: underline; }

    /* A tone: set `data-tone` (or the class `rt-tone-…`) on a row, a cell, a badge, anything. `neutral` is a tone that
       looks like nothing: use it to say "no emphasis" explicitly. Components read --rt-tone, --rt-tone-bg, --rt-tone-fg.
       The six below are what this theme knows. Any other plain word is a tone too (the data says `gold`): it looks like the
       accent until a stylesheet says more, `[data-tone="gold"] { --rt-tone: gold }`. A level (a number from the data) is
       `--rt-level` and `data-level` on the element: nothing here draws it, a stylesheet turns it into a colour. */
    :where([data-tone], [class*="rt-tone-"]) { --rt-tone: var(--rt-accent); }
    :where([data-tone="neutral"],   .rt-tone-neutral)   { --rt-tone: var(--rt-muted); }
    :where([data-tone="info"],      .rt-tone-info)      { --rt-tone: var(--rt-info); }
    :where([data-tone="positive"],  .rt-tone-positive)  { --rt-tone: var(--rt-positive); }
    :where([data-tone="warning"],   .rt-tone-warning)   { --rt-tone: var(--rt-warning); }
    :where([data-tone="danger"],    .rt-tone-danger)    { --rt-tone: var(--rt-danger); }
    :where([data-tone="important"], .rt-tone-important) { --rt-tone: var(--rt-important); }

    :where([data-tone]:not([data-tone="neutral"]), [class*="rt-tone-"]:not(.rt-tone-neutral)) {
        --rt-tone-bg: color-mix(in oklab, var(--rt-tone) 11%, var(--rt-surface));
        --rt-tone-fg: color-mix(in oklab, var(--rt-tone) 78%, var(--rt-text));
        background: var(--rt-tone-bg);
        color: var(--rt-tone-fg);
    }
    :where([data-tone="important"], .rt-tone-important) { font-weight: 600; }
}

/* ---- components -------------------------------------------------------------------------------------------- */
@layer rt-components {
    /* the pieces a report's own markup is made of (designer guide, "Markup conventions"): a grid of cards, a card, an introduction, quiet text */
    :where(.grid) {
        display: grid;
        gap: calc(var(--rt-gap) * 2);
        grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
    }
    :where(.card) {
        background: var(--rt-surface);
        border: 1px solid var(--rt-border);
        border-radius: var(--rt-radius);
        padding: clamp(.875rem, 2.4vw, 1.125rem);
        box-shadow: var(--rt-shadow);
    }
    :where(.card > :is(h2, h3, h4):first-child) { margin-top: .125rem; }
    :where(.lead) { font-size: 1.1em; color: var(--rt-muted); max-width: 65ch; }
    :where(.muted) { color: var(--rt-muted); }
    /* a detail drawn in a cell, folded (a details element) or behind a loupe (the dataset cell renderer's as: fold | popup) */
    :where(.rt-detail > summary) { cursor: pointer; color: var(--rt-accent); }
    :where(.rt-detail[open] > summary) { margin-bottom: .5rem; }
    :where(.rt-detail-open) { padding: .2rem .5rem; line-height: 1; }
    /* a tree (the ds/tree layout): levels inside folders, a folder opens and closes (a details element), the page that is open is bold */
    :where(.rt-tree ul) { list-style: none; margin: 0; padding-left: 1rem; }
    :where(.rt-tree > ul) { padding-left: 0; }
    :where(.rt-tree li) { margin: .2rem 0; }
    :where(.rt-tree summary) { cursor: pointer; font-weight: 600; }
    :where(.rt-tree a[aria-current="true"]) { font-weight: 700; color: var(--rt-accent); }
    /* a table that is closer together: `data-layout="ds/table#compact"` */
    :where(.rt-compact) { --rt-density: .25rem .5rem; font-size: .875em; }

    /* a table wider than its place (a phone) scrolls inside it, and does not widen the page */
    :where(.rt-scroll, [data-rt]:has(> table)) { overflow-x: auto; max-width: 100%; }              /* `.rt-scroll`: the box round the table in a layout that has a bar above it (datatable) */
    /* a field in a cell of a table (a table that is edited: the `input` and `select` cell renderers) fills the cell, whatever the browser's own width for it */
    :where([data-rt] td > :is(input:not([type="checkbox"], [type="radio"], [type="color"]), select)) { width: 100%; min-width: 0; box-sizing: border-box; }
    :where([data-rt] td > select) { min-width: 5.5rem; }
    :where([data-rt] td > input:is(:not([type]), [type="text"], [type="search"])) { min-width: 8rem; }
    :where([data-rt] td > input[type="number"]) { min-width: 4.5rem; }
    /* table: works with any template that puts a <table> in a [data-rt] */
    :where([data-rt] table) {
        width: 100%;
        border-collapse: collapse;
        color: var(--rt-text);
        background: var(--rt-surface);
    }
    :where([data-rt] th, [data-rt] td) {
        padding: var(--rt-density);
        border-bottom: 1px solid var(--rt-border);
        text-align: left;
    }
    :where([data-rt] th) {
        font-weight: 600;
        font-size: .8125em;
        letter-spacing: .02em;
        color: var(--rt-muted);
        border-bottom-width: 2px;
        white-space: nowrap;
    }
    :where([data-rt] tbody tr) { transition: background-color var(--rt-speed) ease; }
    /* zebra: every second row (and every second item of a list) a little different, for tables with many columns; `data-zebra` on the slot turns it on, `data-zebra="off"` turns a theme's off.
       Before the hover, the selection and the tones: they win (all of these are :where, so the order decides). */
    :where([data-zebra]) { --rt-zebra: var(--rt-surface-2); }
    :where([data-zebra="off"]) { --rt-zebra: transparent; }
    :where([data-rt] tbody tr:nth-child(even)) { background: var(--rt-zebra); }
    :where(ul[data-rt] > li:nth-child(even)) { background: var(--rt-zebra); }
    :where([data-zebra] ul[data-rt] > li) { padding: .2rem .5rem; }
    /* sticky: `data-sticky="header"` keeps the header at the top of a table that scrolls in a box of its own (--rt-table-height); `data-sticky="column"` keeps the first column at the left of a wide one;
       both: `data-sticky="header column"`. The cells need a background of their own, or what scrolls under them shows through. */
    :where([data-sticky~="header"] :is(.rt-scroll, [data-rt]:has(> table))) { max-height: var(--rt-table-height); overflow: auto; }
    :where([data-sticky~="header"] [data-rt] thead th) { position: sticky; top: 0; z-index: 2; background: var(--rt-surface); }
    :where([data-sticky~="column"] [data-rt] tr > :first-child) {
        position: sticky; left: 0; z-index: 1;
        background-color: var(--rt-surface);
        background-image: linear-gradient(var(--rt-zebra), var(--rt-zebra));                 /* the stripe over the solid colour: transparent when there is no zebra */
    }
    :where([data-sticky~="column"] [data-rt] thead tr > :first-child, [data-sticky~="column"] [data-rt] tbody tr:nth-child(odd) > :first-child) { background-image: none; }
    :where([data-sticky~="column"] [data-rt] tbody tr:hover > :first-child) { background-image: linear-gradient(var(--rt-hover), var(--rt-hover)); }
    :where([data-sticky~="column"] [data-rt] tbody tr[data-selected] > :first-child) { background-image: linear-gradient(var(--rt-selected), var(--rt-selected)); }
    :where([data-sticky~="header"][data-sticky~="column"] [data-rt] thead th:first-child) { z-index: 3; }
    :where([data-rt] tbody tr:hover) { background: var(--rt-hover); }
    :where([data-rt] tbody tr[data-tone]:not([data-tone="neutral"]):hover) {
        background: color-mix(in oklab, var(--rt-tone) 18%, var(--rt-surface));
    }
    :where([data-rt] td[data-tone]:not([data-tone="neutral"])) { border-radius: 0; }

    /* rows that can be picked (data-select) and what is picked */
    :where([data-rt] tr[aria-selected]) { cursor: pointer; }
    :where([data-rt] tr[data-selected]) { background: var(--rt-selected); }
    :where([data-rt] tbody tr[data-selected]:hover) { background: color-mix(in oklab, var(--rt-accent) 20%, var(--rt-surface)); }
    :where(.rt-pick) { width: 1.1em; height: 1.1em; accent-color: var(--rt-accent); cursor: pointer; }
    :where(.popup--detail) { width: min(92vw, 44rem); max-height: 88vh; overflow: auto; }
    :where(.popup--detail[open]) { animation: rt-pop calc(var(--rt-speed) * 2) ease-out; }
    :where(.popup--detail)::backdrop { animation: rt-fade calc(var(--rt-speed) * 2) ease-out; }

    /* a sortable header: the arrow says how it is sorted, and shows a little on hover */
    :where([data-rt] th[data-sort]) {
        cursor: pointer;
        user-select: none;
        transition: color var(--rt-speed) ease;
    }
    :where([data-rt] th[data-sort]:hover) { color: var(--rt-text); }
    :where([data-rt] th[data-sort])::after {
        content: "↕";
        display: inline-block;
        margin-left: .35em;
        opacity: 0;
        transition: opacity var(--rt-speed) ease;
    }
    :where([data-rt] th[data-sort]:hover)::after { opacity: .4; }
    :where([data-rt] th[aria-sort="ascending"])::after  { content: "↑"; opacity: 1; color: var(--rt-accent); }
    :where([data-rt] th[aria-sort="descending"])::after { content: "↓"; opacity: 1; color: var(--rt-accent); }
    :where([data-rt] th[aria-sort="ascending"], [data-rt] th[aria-sort="descending"]) { color: var(--rt-text); }

    /* big numbers (`ds/stat`): a tile for each column of the first row, the name over the value; the tone of the value is the column `<column>__tone` */
    :where(.rt-stats) { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 8rem), 1fr)); gap: var(--rt-gap); }
    :where(.rt-stat) {
        display: flex; flex-direction: column; gap: .25rem;
        min-width: 0; container-type: inline-size;                         /* the number is sized by the width of its own tile (below) */
        padding: .75rem 1rem;
        border: 1px solid var(--rt-border); border-radius: var(--rt-radius); background: var(--rt-surface);
    }
    :where(.rt-stat__label) { color: var(--rt-muted); font-size: .8125em; font-weight: 600; letter-spacing: .02em; }
    :where(.rt-stat__value) {
        font-size: clamp(1.15rem, calc(100cqi / 8), 1.9rem);              /* about eight digits of it fit the tile: a longer number is a little smaller, so that it never goes out of it */
        font-weight: 700; line-height: 1.15; font-variant-numeric: tabular-nums; overflow-wrap: anywhere;
    }
    :where(.rt-stat__value[data-tone]:not([data-tone="neutral"])) { color: var(--rt-tone); }

    /* the bar above a table: filter, count, download */
    :where(.rt-tablebar) {
        display: flex;
        flex-wrap: wrap;                                                   /* on a phone the filter, the count and the button go on a second line, not out of the page */
        align-items: center;
        gap: var(--rt-gap);
        margin-bottom: var(--rt-gap);
    }
    :where(.rt-tablebar input[type="search"]) { flex: 0 1 18rem; }
    :where(.rt-count) { color: var(--rt-muted); font-size: .8125em; font-variant-numeric: tabular-nums; margin-right: auto; }

    /* pages: previous, where you are, next; and the end of an endless list */
    :where(.rt-pager) {
        display: flex;
        align-items: center;
        justify-content: flex-end;
        gap: var(--rt-gap);
        margin-top: var(--rt-gap);
    }
    :where(.rt-pager[hidden], .rt-endless[hidden]) { display: none; }
    :where(.rt-pager__label) { color: var(--rt-muted); font-size: .8125em; font-variant-numeric: tabular-nums; min-width: 9ch; text-align: center; }
    :where(.rt-endless) { display: flex; justify-content: center; padding: var(--rt-gap); }

    /* icon: an svg of assets/icons used as a mask, so it takes the colour of the text (or of the tone) */
    :where(.rt-icon) {
        display: inline-block;
        width: 1.1em;
        height: 1.1em;
        vertical-align: -.2em;
        background-color: var(--rt-tone, currentColor);
        -webkit-mask: var(--rt-icon) center / contain no-repeat;
        mask: var(--rt-icon) center / contain no-repeat;
    }

    /* badge: a short label with a tone */
    :where(.rt-badge) {
        display: inline-block;
        padding: .05em .65em;
        border-radius: 999px;
        font-size: .8125em;
        font-weight: 600;
        line-height: 1.5;
        white-space: nowrap;
        background: var(--rt-tone-bg, var(--rt-surface-2));
        color: var(--rt-tone-fg, var(--rt-muted));
        border: 1px solid color-mix(in oklab, var(--rt-tone, var(--rt-muted)) 28%, var(--rt-border));
    }

    /* bar: a number against a maximum. The width is --rt-fill (set by the renderer: a number), the colour the tone's. */
    :where(.rt-bar) {
        display: inline-flex;
        align-items: center;
        gap: .6em;
        min-width: 9rem;
        background: none;
        color: inherit;
        font-weight: inherit;
    }
    :where(.rt-bar__track) {
        flex: 1 1 6rem;
        max-width: 8rem;
        height: .5rem;
        min-width: 4rem;
        border-radius: 999px;
        overflow: hidden;
        background: color-mix(in oklab, var(--rt-muted) 18%, transparent);
    }
    :where(.rt-bar__fill) {
        display: block;
        height: 100%;
        width: var(--rt-fill, 0%);
        border-radius: inherit;
        background: var(--rt-tone, var(--rt-accent));
        transition: width calc(var(--rt-speed) * 4) ease;
        @starting-style { width: 0%; }
    }
    :where(.rt-bar__text) { min-width: 2.5ch; text-align: right; font-variant-numeric: tabular-nums; }

    /* sparkline: an inline line of a series */
    :where(.rt-spark) {
        display: inline-block;
        vertical-align: middle;
        overflow: visible;
        background: none;
        color: var(--rt-tone, var(--rt-accent));
    }
    :where(.rt-spark__line) { fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
    :where(.rt-spark__area) { fill: color-mix(in oklab, currentColor 14%, transparent); stroke: none; }
    :where(.rt-spark__dot)  { fill: currentColor; }

    /* chart (Observable Plot draws the svg; it scales down with the page) */
    :where(.rt-chart) { width: 100%; }
    :where(.rt-chart svg) { max-width: 100%; height: auto; }
    :where(.rt-chart figure) { margin: 0; }
    /* marks that can be picked (data-select, data-hover): a hand, the picked one outlined, the others quieter while one is picked */
    :where(.rt-chart [data-row-id]) { cursor: pointer; }
    :where(.rt-chart [data-row-id]:focus-visible) { outline: 2px solid var(--rt-accent); outline-offset: 1px; }
    :where(.rt-chart [data-row-id][data-selected]) { stroke: var(--rt-text); stroke-width: 2px; }
    :where(.rt-chart:has([data-selected]) [data-row-id]:not([data-selected])) { opacity: .45; }
    /* a place that a dataset shows or hides (data-show, data-hide): hidden wins over the display of the layout's own classes */
    [data-show][hidden], [data-hide][hidden] { display: none !important; }
    :where(.rt-chart [aria-label="swatches"], .rt-chart > figure > div) { margin-bottom: .5rem; }
    :where(.rt-chart__message) {
        padding: .5rem .75rem;
        border-radius: var(--rt-radius);
        margin: 0;
    }

    /* forms (ds/form, ds/submit): a grid of label and field */
    :where(.form-grid) {
        --gap: 1rem;
        --label-width: 200px;
        display: grid;
        gap: var(--gap);
        max-width: 700px;
        background: var(--rt-surface);
        padding: 1.5rem 2rem;
        border-radius: var(--rt-radius);
        border: 1px solid var(--rt-border);
        box-shadow: var(--rt-shadow);
        font-family: var(--rt-font);
    }
    :where(.form-grid h2) { grid-column: 1 / -1; margin-bottom: .5rem; font-size: 1.25rem; }
    :where(.form-row) { display: grid; grid-template-columns: var(--label-width) 1fr; align-items: center; gap: .5rem 1rem; }
    :where(.form-row.full-width) { grid-template-columns: 1fr; }
    :where(.form-row label) { font-weight: 500; }
    :where(.form-row input, .form-row select, .form-row textarea) { width: 100%; font-size: 1rem; }
    :where(fieldset) {
        border: 1px solid var(--rt-border);
        border-radius: var(--rt-radius);
        padding: .75rem 1rem;
        background: var(--rt-surface-2);
        grid-column: 1 / -1;
    }
    :where(legend) { font-weight: 600; padding: 0 .5rem; }
    :where(.form-actions) { grid-column: 1 / -1; display: flex; justify-content: flex-end; gap: .75rem; margin-top: 1rem; }
    @media (max-width: 600px) {
        :where(.form-row) { grid-template-columns: 1fr; }
    }

    /* a form that folds: the summary line says what it was run with, a click opens it (ds/form-fold) */
    :where(.rt-fold) {
        margin-bottom: var(--rt-gap);
        background: var(--rt-surface);
        border: 1px solid var(--rt-border);
        border-radius: var(--rt-radius);
        interpolate-size: allow-keywords;
    }
    :where(.rt-fold > summary) {
        display: flex;
        align-items: center;
        gap: .75rem;
        padding: .6rem .9rem;
        cursor: pointer;
        user-select: none;
        list-style: none;
    }
    :where(.rt-fold > summary::-webkit-details-marker) { display: none; }
    :where(.rt-fold > summary::before) {
        content: "▸";
        color: var(--rt-muted);
        transition: transform var(--rt-speed) ease;
    }
    :where(.rt-fold[open] > summary::before) { transform: rotate(90deg); }
    :where(.rt-fold > summary:hover) { background: var(--rt-hover); border-radius: var(--rt-radius); }
    :where(.rt-fold__title) { font-weight: 600; }
    :where(.rt-fold__values) { display: flex; flex-wrap: wrap; gap: .4rem; }
    :where(.rt-fold[open] .rt-fold__values) { display: none; }
    :where(.rt-chip) {
        padding: .05em .65em;
        border-radius: 999px;
        font-size: .8125em;
        background: var(--rt-surface-2);
        border: 1px solid var(--rt-border);
        white-space: nowrap;
    }
    :where(.rt-chip__name) { color: var(--rt-muted); }
    :where(.rt-chip__value) { font-weight: 600; }
    :where(.rt-chip:has(.rt-chip__value:empty)) { display: none; }
    :where(.rt-fold .form-grid) { border: 0; box-shadow: none; background: none; padding: .25rem 1rem 1rem; }
    @supports selector(::details-content) {
        :where(.rt-fold)::details-content {
            block-size: 0;
            overflow: clip;
            transition: block-size calc(var(--rt-speed) * 2) ease, content-visibility calc(var(--rt-speed) * 2) allow-discrete;
        }
        :where(.rt-fold[open])::details-content { block-size: auto; }
    }

    /* nav: the reports, folders that open, the current page marked */
    /* map: OpenStreetMap tiles with SVG pins (mapRenderer.ts) */
    /* tabs (panels of a layout, see tabs.ts) */
    :where(.rt-tablist) { display: flex; flex-wrap: wrap; gap: .25rem; margin: 0 0 1rem; border-bottom: 1px solid var(--rt-border); }
    :where(.rt-tabbutton) { background: none; border: 0; border-bottom: 3px solid transparent; border-radius: 0; padding: .5rem .9rem; margin: 0 0 -1px; color: var(--rt-muted); font: inherit; font-weight: 600; cursor: pointer; box-shadow: none; }
    :where(.rt-tabbutton:hover) { color: var(--rt-text, inherit); background: none; }
    :where(.rt-tabbutton[aria-selected="true"]) { color: var(--rt-accent); border-bottom-color: var(--rt-accent); }
    :where(.rt-tabbutton:focus-visible) { outline: 2px solid var(--rt-accent); outline-offset: -2px; }
    :where(.rt-tabpanel[hidden]) { display: none; }
    @media print {
        :where(.rt-tablist) { display: none; }
        .rt-tabpanel[hidden] { display: block; }
    }
    :where(.rt-map) { margin: 0; max-width: 100%; }
    :where(.rt-map__view) { position: relative; overflow: hidden; max-width: 100%; border: 1px solid var(--rt-border); border-radius: var(--rt-radius); background: var(--rt-surface-2); }
    :where(.rt-map__tile) { position: absolute; width: 256px; height: 256px; max-width: none; user-select: none; }
    :where(.rt-map__marks) { position: absolute; inset: 0; max-width: none; pointer-events: none; }
    :where(.rt-map__line) { stroke: var(--rt-accent); stroke-width: 3; stroke-dasharray: 6 5; opacity: .85; }
    :where(.rt-map__pin) { pointer-events: all; }
    :where(.rt-map__pin circle) { fill: var(--rt-accent); stroke: var(--rt-surface); stroke-width: 2; }
    :where(.rt-map__pin--0 circle) { fill: var(--rt-positive); }
    :where(.rt-map__pin--1 circle) { fill: var(--rt-danger); }
    :where(.rt-map__pin--me circle) { fill: var(--rt-text, #222); stroke-width: 3; }
    :where(.rt-map__pin--pickable) { cursor: pointer; }
    :where(.rt-map__pin--pickable:focus-visible circle) { stroke: var(--rt-accent); stroke-width: 3; }
    :where(.rt-map__pin--picked circle) { stroke: var(--rt-accent); stroke-width: 4; r: 11; }
    :where(.rt-map__pin text) { fill: var(--rt-on-accent); font: 700 11px system-ui, sans-serif; pointer-events: none; }       /* the number on a pin: the colour that is read on the accent, in light and in dark */
    :where(.rt-map__credit) { margin-top: .25rem; font-size: .75rem; color: var(--rt-muted); }
    /* a light street map in a dark page is glare: the tiles are dimmed in dark mode (the system's, or `data-theme="dark"`); the pins and the credit line are not touched */
    @media (prefers-color-scheme: dark) { :where(:root:not([data-theme="light"]) .rt-map__tile) { filter: brightness(.78) contrast(1.05) saturate(.9); } }
    :where(:root[data-theme="dark"] .rt-map__tile) { filter: brightness(.78) contrast(1.05) saturate(.9); }

    /* a piece of the page around the report (the navigation, who is signed in) that could not load is not shown at all: the report is still good */
    :where([data-chrome][data-state="error"]) { display: none; }

    /* presets: quick-pick buttons that fill the fields of a form (presetsRenderer.ts) */
    :where(.rt-presets) { display: flex; flex-wrap: wrap; gap: .35rem; }
    :where(.rt-preset) { padding: .2rem .65rem; font-size: .8125rem; }
    .rt-preset[aria-pressed="true"] { background: var(--rt-accent); border-color: var(--rt-accent); color: var(--rt-on-accent); }       /* (not :where: it has to beat the theme's button.secondary) */

    /* account: who is signed in, with the way out (or in) — the shell's corner */
    :where(.rt-account) { display: flex; gap: .75rem; align-items: center; justify-content: flex-end; font-size: .875rem; color: var(--rt-muted); }
    :where(.rt-account__name) { font-weight: 600; color: var(--rt-text); }
    :where(.rt-account__out) { margin: 0; }
    :where(.rt-account__button) {
        font: inherit; padding: 0; border: 0; background: none; cursor: pointer;
        color: var(--rt-accent); text-decoration: underline; text-underline-offset: .15em;
    }
    :where(.rt-account__button:hover) { text-decoration-thickness: 2px; }

    :where(.rt-nav) { font-size: .9375rem; }
    :where(.rt-nav ul) { list-style: none; margin: 0; padding: 0; }
    :where(.rt-nav ul ul) { margin-left: .6rem; padding-left: .6rem; border-left: 1px solid var(--rt-border); }
    :where(.rt-nav a, .rt-nav summary) {
        display: block;
        padding: .35rem .6rem;
        border-radius: calc(var(--rt-radius) * .75);
        color: var(--rt-text);
        text-decoration: none;
        transition: background-color var(--rt-speed) ease, color var(--rt-speed) ease;
    }
    :where(.rt-nav a:hover, .rt-nav summary:hover) { background: var(--rt-hover); text-decoration: none; }
    :where(.rt-nav a[aria-current]) {
        background: var(--rt-selected);
        color: color-mix(in oklab, var(--rt-accent) 80%, var(--rt-text));         /* the accent itself is a little under 4.5:1 on the selected background in dark mode */
        font-weight: 600;
    }
    :where(.rt-nav summary) { cursor: pointer; list-style: none; color: var(--rt-muted); font-weight: 600; user-select: none; }
    :where(.rt-nav summary::-webkit-details-marker) { display: none; }
    :where(.rt-nav summary::before) {
        content: "▸";
        display: inline-block;
        width: 1em;
        transition: transform var(--rt-speed) ease;
    }
    :where(.rt-nav details[open] > summary::before) { transform: rotate(90deg); }
    /* the button that folds the whole list on a narrow screen (the renderer opens the fold on a wide one: the button is only there when the nav is above the page) */
    :where(.rt-nav__toggle) { display: none; }
    @media (max-width: 800px) {
        :where(.rt-nav__toggle) {
            display: block;
            padding: .6rem .8rem;
            border: 1px solid var(--rt-border);
            background: var(--rt-surface);
            color: var(--rt-text);
            font-weight: 600;
        }
        :where(.rt-nav__menu[open] > .rt-nav__toggle) { margin-bottom: .5rem; }
        :where(.rt-nav__menu a) { padding-block: .6rem; }                /* a finger, not a pointer */
    }

    /* the button that hides the menu by hand (a wide screen; on a narrow one the Menu button above is the way): the nav gives its column to the page and leaves the button, at the top */
    :where(.rt-nav__collapse) {
        display: block; margin: 0 0 .4rem auto; width: 2rem; height: 2rem; padding: 0; line-height: 1;
        font-size: 1.25rem; border: 1px solid var(--rt-border); border-radius: calc(var(--rt-radius) * .75);
        background: var(--rt-surface); color: var(--rt-muted); cursor: pointer;
    }
    :where(.rt-nav__collapse:hover) { background: var(--rt-hover); color: var(--rt-text); }
    :where(.rt-nav[data-collapsed] > .rt-nav__menu) { display: none; }
    @media (max-width: 800px) { :where(.rt-nav__collapse) { display: none; } :where(.rt-nav[data-collapsed] > .rt-nav__menu) { display: block; } }

    /* a page with the nav beside it */
    :where(.rt-shell) { display: grid; grid-template-columns: 14rem minmax(0, 1fr); gap: 1.5rem; align-items: start; }
    :where(.rt-shell > aside) { position: sticky; top: 4.5rem; }
    :where(.rt-shell:has(> aside > .rt-nav[data-collapsed])) { grid-template-columns: 2.5rem minmax(0, 1fr); }      /* the menu is hidden by hand: a strip for the button */
    :where(.rt-shell:has(> aside:empty)) { grid-template-columns: minmax(0, 1fr); }      /* a page with no nav (chrome: false) */
    :where(.rt-shell > aside:empty) { display: none; }
    @media (max-width: 800px) {
        :where(.rt-shell) { grid-template-columns: minmax(0, 1fr); }
        :where(.rt-shell > aside) { position: static; }
    }

    /* states: the page says what a dataset is doing. data-state is on the slot ([data-ds]) of a dataset, data-busy on the report's
       element while anything is on its way, data-changed for a moment after a reload that brought other data. All of it is
       transform / opacity / background, nothing that moves the page, and none of it moves under prefers-reduced-motion. */
    :where([data-ds][data-state="loading"], [data-ds][data-state="reloading"]) { position: relative; }
    :where([data-ds][data-state="loading"]) { color: var(--rt-muted); }
    :where([data-ds][data-state="loading"], [data-ds][data-state="reloading"])::after {
        content: "";
        position: absolute;
        inset: 0 0 auto 0;
        height: 2px;
        background: linear-gradient(90deg, transparent, var(--rt-accent), transparent) no-repeat;
        background-size: 40% 100%;
        animation: rt-slide 1.1s ease-in-out infinite;
        pointer-events: none;
    }
    :where([data-ds][data-state="reloading"]) > * { opacity: .55; }
    :where([data-ds] > *) { transition: opacity calc(var(--rt-speed) * 2) ease; }
    :where([data-ds][data-state="error"])::before {
        content: "⚠  " attr(data-error);
        display: block;
        margin-bottom: var(--rt-gap);
        padding: .4rem .75rem;
        border-radius: var(--rt-radius);
        font-size: .875em;
        background: color-mix(in oklab, var(--rt-danger) 11%, var(--rt-surface));
        color: color-mix(in oklab, var(--rt-danger) 78%, var(--rt-text));
    }
    /* a channel that cut a result at its maxRows: the slot says how many rows there are (data-truncated), and this says that there are more. Translate it, or word it
       otherwise, in rt-user.css: [data-ds][data-state="ready"][data-truncated]::after { content: "Eerste " attr(data-truncated) " rijen." } */
    :where([data-ds][data-state="ready"][data-truncated])::after {
        content: "Showing the first " attr(data-truncated) " rows. There are more.";
        display: block;
        margin-top: var(--rt-gap);
        font-size: .875em;
        color: var(--rt-muted);
    }
    :where([data-ds][data-changed]) { animation: rt-flash calc(var(--rt-speed) * 9) ease-out; }
    :where([data-ds][data-state] > *) { animation: rt-fade calc(var(--rt-speed) * 2) ease-out; }
    :where([data-busy])::before {
        content: "";
        position: fixed;
        inset: 0 0 auto 0;
        height: 2px;
        z-index: 100;
        background: linear-gradient(90deg, transparent, var(--rt-accent), transparent) no-repeat;
        background-size: 30% 100%;
        animation: rt-slide 1.1s ease-in-out infinite;
        pointer-events: none;
    }
    @keyframes rt-slide { from { background-position: -40% 0; } to { background-position: 140% 0; } }
    @keyframes rt-fade  { from { opacity: 0; } to { opacity: 1; } }
    @keyframes rt-flash { from { background: color-mix(in oklab, var(--rt-accent) 16%, transparent); } to { background: transparent; } }
    @media (prefers-reduced-motion: reduce) {
        :where([data-ds][data-state]::after, [data-busy]::before) { animation: none; background-size: 100% 100%; opacity: .5; }
    }

    /* a list beside a document (a master list and its page) */
    :where(.rt-split) { display: grid; grid-template-columns: 15rem minmax(0, 1fr); gap: 1.5rem; align-items: start; }
    :where(.rt-split > aside) { position: sticky; top: 4.5rem; max-height: calc(100vh - 6rem); overflow: auto; }
    @media (max-width: 800px) {
        :where(.rt-split) { grid-template-columns: minmax(0, 1fr); }
        :where(.rt-split > aside) { position: static; max-height: 16rem; }
    }
    :where(.rt-menu a) { overflow-wrap: anywhere; }

    /* a document (ds/document, the markdown renderer) */
    :where(.rt-doc__body) { max-width: 80ch; line-height: 1.6; }
    :where(.rt-doc__body :is(h1, h2, h3, h4, h5, h6)) { scroll-margin-top: 4.5rem; line-height: 1.25; margin: 1.6em 0 .5em; }
    :where(.rt-doc__body h1) { font-size: 1.9em; margin-top: 0; }
    :where(.rt-doc__body h2) { font-size: 1.45em; }
    :where(.rt-doc__body h3) { font-size: 1.2em; }
    :where(.rt-doc__body :is(p, ul, ol, pre, blockquote, table)) { margin: 0 0 1em; }
    :where(.rt-doc__body :is(ul, ol)) { padding-left: 1.5rem; }
    :where(.rt-doc__body li > :is(ul, ol)) { margin: .25em 0; }
    :where(.rt-doc__body li:has(> input[type="checkbox"])) { list-style: none; margin-left: -1.25rem; }
    :where(.rt-doc__body code) {
        font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
        font-size: .875em;
        background: var(--rt-surface-2);
        border: 1px solid var(--rt-border);
        border-radius: calc(var(--rt-radius) * .5);
        padding: .05em .35em;
    }
    :where(.rt-doc__body pre) {
        background: var(--rt-surface-2);
        border: 1px solid var(--rt-border);
        border-radius: var(--rt-radius);
        padding: .75rem 1rem;
        overflow-x: auto;
        line-height: 1.45;
    }
    :where(.rt-doc__body pre code) { background: none; border: 0; padding: 0; font-size: .8125em; }
    :where(.rt-doc__body blockquote) { border-left: 3px solid var(--rt-accent); padding: .1em 1em; color: var(--rt-muted); background: none; }
    :where(.rt-doc__body hr) { border: 0; border-top: 1px solid var(--rt-border); margin: 2em 0; }
    :where(.rt-doc__body img) { max-width: 100%; height: auto; }
    :where(.rt-doc__body table) { width: auto; max-width: 100%; display: block; overflow-x: auto; }

    /* button */
    :where([data-rt] button, .rt-btn) {
        display: inline-flex; align-items: center; justify-content: center; gap: .4em;
        padding: .45rem .9rem;
        font: inherit; font-weight: 600;
        color: var(--rt-on-accent);
        background: var(--rt-accent);
        border: 1px solid transparent;
        border-radius: var(--rt-radius);
        cursor: pointer;
        transition: filter var(--rt-speed) ease, transform var(--rt-speed) ease;
    }
    :where([data-rt] button:hover, .rt-btn:hover) { filter: brightness(1.08); }
    :where([data-rt] button:active, .rt-btn:active) { transform: translateY(1px); }
    [data-rt] [hidden] { display: none; }                  /* hidden means not shown: a button's own display (above) must not win over the attribute */
    :where([data-rt] button:disabled, .rt-btn:disabled) { opacity: .5; cursor: not-allowed; }

    /* A finger needs a target of about 44 px (Apple's guideline; WCAG asks for 24 at the least). On a touch screen or a narrow one the hit area grows and the look stays: a link
       in a cell is padded and pulled back by the same margin (the row is as high as before), buttons, fields and sortable headers are taller. */
    @media (pointer: coarse), (max-width: 800px) {
        :where([data-rt] td a) { display: inline-block; padding-block: .8rem; margin-block: -.8rem; min-width: 2.75rem; }
        :where([data-rt] button, .rt-btn, [data-rt] select, [data-rt] input:not([type="checkbox"], [type="radio"])) { min-height: 2.75rem; }
        :where([data-rt] th[data-sort]) { padding-block: .85rem; }
        :where(.rt-account__in, .rt-account__button) { display: inline-block; padding-block: .6rem; }
    }
    :where(.rt-btn.secondary, [data-rt] button.secondary) {
        color: var(--rt-text);
        background: var(--rt-surface-2);
        border-color: var(--rt-border);
    }

    /* inputs */
    :where([data-rt] input:not([type="checkbox"], [type="radio"]), [data-rt] select, [data-rt] textarea) {
        font: inherit;
        color: var(--rt-text);
        background: var(--rt-surface);
        border: 1px solid var(--rt-border);
        border-radius: calc(var(--rt-radius) * .75);
        padding: .4rem .6rem;
        transition: border-color var(--rt-speed) ease, box-shadow var(--rt-speed) ease;
    }
    :where([data-rt] input:focus, [data-rt] select:focus, [data-rt] textarea:focus) {
        outline: none;
        border-color: var(--rt-accent);
        box-shadow: 0 0 0 3px color-mix(in oklab, var(--rt-accent) 22%, transparent);
    }

    /* the report's own errors (ds/errors.html) */
    :where([data-rt].errors li) {
        list-style: none;
        padding: .5rem .75rem;
        margin: .25rem 0;
        border-radius: var(--rt-radius);
        --rt-tone: var(--rt-danger);
        background: color-mix(in oklab, var(--rt-danger) 11%, var(--rt-surface));
        color: color-mix(in oklab, var(--rt-danger) 78%, var(--rt-text));
    }

    /* tabs */
    :where(.rt-tabs) { display: flex; flex-direction: column; height: 100%; }
    :where(.rt-tablist) { display: flex; gap: .25rem; border-bottom: 1px solid var(--rt-border); }
    :where(.rt-tablist [role="tab"]) {
        padding: .5rem .75rem;
        border: none;
        border-bottom: 2px solid transparent;
        border-radius: 0;
        color: var(--rt-muted);
        background: transparent;
        cursor: pointer;
        transition: color var(--rt-speed) ease, border-color var(--rt-speed) ease;
    }
    :where(.rt-tablist [role="tab"]:hover) { color: var(--rt-text); }
    :where(.rt-tablist [role="tab"][aria-selected="true"]) {
        color: var(--rt-text);
        border-bottom-color: var(--rt-accent);
        font-weight: 600;
    }
    :where([role="tabpanel"]) { padding: .75rem 0; }

    /* popup (<dialog>) */
    :where(.popup) {
        max-width: 700px;
        width: 90vw;
        padding: 0;
        color: var(--rt-text);
        background: var(--rt-surface);
        border: 1px solid var(--rt-border);
        border-radius: calc(var(--rt-radius) * 1.5);
        box-shadow: var(--rt-shadow);
    }
    :where(.popup::backdrop) { background: rgb(0 0 0 / .4); }
    :where(.popup__inner) { padding: 1.25rem 1.5rem 1rem; }
    :where(.popup__header) { display: flex; justify-content: space-between; align-items: center; }
    :where(.popup__title) { margin: 0; font-size: 1.1rem; }
    :where(.popup__close) {
        border: none; background: transparent; color: var(--rt-muted);
        font-size: 1.2rem; cursor: pointer; padding: .1rem .4rem;
    }
    :where(.popup__close:hover) { color: var(--rt-text); filter: none; }

    /* a report in a window (a drill-down link): wide, and it scrolls inside */
    :where(.popup--report) { width: min(92vw, 62rem); max-height: 88vh; overflow: auto; }
    :where(.popup--report .popup__header) { gap: .75rem; }
    :where(.popup--report .popup__title) { margin-right: auto; }
    :where(.popup--report .popup__page) { font-size: .8125em; color: var(--rt-muted); white-space: nowrap; }
    :where(.popup--report .popup__body) { margin-top: .75rem; min-height: 6rem; }
    :where(.popup--report[open]) { animation: rt-pop calc(var(--rt-speed) * 2) ease-out; }
    :where(.popup--report)::backdrop { animation: rt-fade calc(var(--rt-speed) * 2) ease-out; }
    @keyframes rt-pop { from { opacity: 0; transform: translateY(.5rem) scale(.985); } to { opacity: 1; transform: none; } }
}
