/* =========================================================================
   Car lineup catalog
   -------------------------------------------------------------------------
   Loaded only on /catalog. Everything is built from the tokens in app.css,
   including the per-marque accent: a card carrying data-accent picks up that
   hue for its own rules and badge, which is how a page of a dozen companies
   still reads as one site rather than a dozen themes.
   ========================================================================= */

/* ---------- Per-marque accent -------------------------------------------- */

/*
 * app.css derives --accent and friends on :root, so a nested [data-accent]
 * changing the hue alone does nothing: the derived colours were already
 * resolved further up and simply inherit. Re-deriving them here is what makes
 * a company's own colour reach its badge and its rules — and the light theme
 * needs its own pass, because there the text variant is solved for contrast
 * rather than being the display colour.
 */
.marque-card[data-accent],
.marque-hero[data-accent],
.tl-note[data-accent] {
    --accent:        hsl(var(--accent-h) var(--accent-s) var(--accent-l));
    --accent-strong: hsl(var(--accent-h) var(--accent-s) calc(var(--accent-l) - 12%));
    --accent-text:   hsl(var(--accent-h) var(--accent-s) var(--accent-l));
    --accent-soft:   hsl(var(--accent-h) var(--accent-s) var(--accent-l) / 0.14);
    --accent-line:   hsl(var(--accent-h) var(--accent-s) var(--accent-l) / 0.35);
    --accent-glow:   hsl(var(--accent-h) var(--accent-s) var(--accent-l) / 0.22);
    --accent-ink:    hsl(var(--accent-h) 60% 8%);
    --accent-fill:   hsl(var(--accent-h) var(--accent-s) var(--accent-l));
}

[data-theme="light"] .marque-card[data-accent],
[data-theme="light"] .marque-hero[data-accent],
[data-theme="light"] .tl-note[data-accent] {
    --accent-text: hsl(var(--accent-h) var(--accent-s) 25%);
    --accent-fill: hsl(var(--accent-h) var(--accent-s) 62%);
}

/* ---------- Marque cards -------------------------------------------------- */

.marque-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 320px), 1fr));
    gap: var(--space-4);
}

.marque-card { position: relative; }

/* The marque's own colour, as a line under its picture: the one place a card shows it however the
   picture looks. */
.marque-card__media { border-bottom: 3px solid var(--accent); }

/* The picture is the card. Everything else is a caption under it, which is
   the garage's treatment and the reason a lineup reads at a glance. */
.marque-card__media,
.model-card__media,
.trim-card__media {
    position: relative;
    aspect-ratio: 16 / 10;
    overflow: hidden;
    background: var(--surface-sunken);
}

.marque-card__media img,
.model-card__media img,
.trim-card__media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* The marque's own badge, over the corner of the photograph. */
.marque-card__logo {
    position: absolute;
    left: var(--space-3);
    bottom: var(--space-3);
    display: grid;
    place-items: center;
    width: 46px;
    height: 46px;
    padding: 4px;
    overflow: hidden;
    background: var(--overlay);
    border: 1px solid var(--accent-line);
    border-radius: var(--radius-sm);
    backdrop-filter: blur(6px);
}

.marque-card__logo img { width: 100%; height: 100%; object-fit: contain; }

.marque-card__flag { position: absolute; right: var(--space-3); top: var(--space-3); }

.marque-card__name { font-size: var(--text-lg); line-height: 1.2; }
.marque-card__link { color: inherit; text-decoration: none; }
.marque-card:hover .marque-card__link { color: var(--accent-text); }
.marque-card__link::after { content: ""; position: absolute; inset: 0; }

.marque-card__tagline { margin-top: 2px; font-size: var(--text-sm); color: var(--text-muted); }

.marque-card__facts {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-4);
    margin: var(--space-3) 0 0;
    padding-top: var(--space-3);
    border-top: 1px solid var(--border);
}

.marque-card__facts dt {
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-dim);
}

.marque-card__facts dd { margin: 2px 0 0; font-weight: 600; font-variant-numeric: tabular-nums; }

.marque-card__lineup {
    margin: var(--space-3) 0 0;
    font-size: var(--text-sm);
    color: var(--text-muted);
}

/* ---------- The shape of a car nobody has photographed -------------------- */

.silhouette {
    display: grid;
    place-content: center;
    justify-items: center;
    gap: var(--space-2);
    width: 100%;
    height: 100%;
    padding: var(--space-4);
    background:
        radial-gradient(120% 100% at 50% 0%, var(--accent-soft), transparent 70%),
        var(--surface-sunken);
    color: var(--text-dim);
}

.silhouette svg { width: min(80%, 260px); height: auto; opacity: 0.75; }

.silhouette__label {
    font-size: var(--text-xs);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-dim);
}

/* The year picker sits in the filter bar beside the search box. */
.catalog-year { display: flex; align-items: center; gap: var(--space-2); }
.catalog-year .label { margin: 0; white-space: nowrap; }
.catalog-year .select { width: auto; min-width: 8rem; }

/* ---------- One marque ---------------------------------------------------- */

.marque-hero {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-5);
    margin-top: var(--space-5);
    padding: var(--space-5);
    background:
        radial-gradient(600px 200px at 0% 0%, var(--accent-glow), transparent 70%),
        var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
}

.marque-hero__badge {
    display: grid;
    place-items: center;
    flex: 0 0 auto;
    width: 96px;
    height: 96px;
    overflow: hidden;
    background: var(--bg-elevated);
    border: 1px solid var(--accent-line);
    border-radius: var(--radius-md);
}

.marque-hero__badge img { width: 100%; height: 100%; object-fit: contain; }
.marque-hero__badge .marque-card__initials { font-size: var(--text-2xl); }

.marque-hero__text { flex: 1 1 320px; }
.marque-hero__text h1 { font-size: var(--text-3xl); line-height: 1.1; }
.marque-hero__text .lede { margin-top: var(--space-2); }
.marque-hero__meta { margin-top: var(--space-3); font-size: var(--text-sm); color: var(--text-muted); }
.marque-hero__actions { flex: 0 0 auto; }

/* The year rail: a marque's whole history as one scrollable row. */
.year-rail {
    display: flex;
    gap: var(--space-2);
    overflow-x: auto;
    padding-bottom: var(--space-2);
    scrollbar-width: thin;
}

.year-rail__item {
    flex: 0 0 auto;
    padding: var(--space-2) var(--space-3);
    font-size: var(--text-sm);
    font-variant-numeric: tabular-nums;
    color: var(--text-muted);
    text-decoration: none;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-full);
}

.year-rail__item:hover { color: var(--text); border-color: var(--border-strong); }

.year-rail__item.is-current {
    color: var(--accent-ink);
    background: var(--accent-fill);
    border-color: var(--accent-fill);
    font-weight: 600;
}

.year-heading {
    display: flex;
    align-items: baseline;
    gap: var(--space-3);
    margin-top: var(--space-6);
    padding-bottom: var(--space-2);
    border-bottom: 1px solid var(--border);
    font-size: var(--text-xl);
    font-variant-numeric: tabular-nums;
}

.year-heading small { font-size: var(--text-sm); font-weight: 400; color: var(--text-dim); }

/* ---------- Models -------------------------------------------------------- */

.model-grid,
.trim-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr));
    gap: var(--space-4);
    margin-top: var(--space-4);
}

.model-card, .trim-card { position: relative; }

.model-card__years,
.trim-card__count {
    position: absolute;
    right: var(--space-3);
    top: var(--space-3);
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 3px 9px;
    font-size: var(--text-xs);
    font-variant-numeric: tabular-nums;
    /* Over a photograph: its own ink and scrim, as on .gallery__tag. */
    color: #fff;
    background: rgb(0 0 0 / 0.78);
    border-radius: var(--radius-full);
    backdrop-filter: blur(6px);
}

.trim-card__count svg { width: 13px; height: 13px; }

.model-card__name, .trim-card__name { font-size: var(--text-lg); line-height: 1.25; }
.model-card__link, .trim-card__link { color: inherit; text-decoration: none; }
.model-card:hover .model-card__link,
.trim-card:hover .trim-card__link { color: var(--accent-text); }
.model-card__link::after, .trim-card__link::after { content: ""; position: absolute; inset: 0; }

.model-card__meta, .trim-card__engine {
    margin-top: var(--space-2);
    font-size: var(--text-sm);
    color: var(--text-muted);
}

.model-card__blurb {
    margin-top: var(--space-2);
    font-size: var(--text-sm);
    color: var(--text-dim);
}

.model-card__trims, .trim-card__tail {
    margin-top: var(--space-3);
    font-size: var(--text-xs);
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text-dim);
}

.trim-card__year {
    font-size: var(--text-sm);
    font-weight: 400;
    font-variant-numeric: tabular-nums;
    color: var(--text-dim);
}

/* Four figures in two columns: the ones anybody compares first. */
.trim-card__figures {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-2) var(--space-4);
    margin: var(--space-3) 0 0;
    padding: 0;
    list-style: none;
}

.trim-card__label {
    display: block;
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-dim);
}

.trim-card__value { font-weight: 600; font-variant-numeric: tabular-nums; }

/* ---------- One model ----------------------------------------------------- */

.model-hero {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-5);
    align-items: start;
}

@media (min-width: 900px) {
    .model-hero { grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); }
}

.model-hero__media {
    overflow: hidden;
    aspect-ratio: 16 / 10;
    background: var(--surface-sunken);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
}

.model-hero__media img { width: 100%; height: 100%; object-fit: cover; }

.model-hero__text h1 { font-size: var(--text-3xl); line-height: 1.1; margin-top: var(--space-2); }

.model-hero__years {
    margin-top: var(--space-2);
    font-size: var(--text-lg);
    font-variant-numeric: tabular-nums;
    color: var(--accent-text);
}

.section-title { font-size: var(--text-xl); }

/* The comparison table is a second opinion, folded away until asked for. */
.compare > summary {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-4);
    font-size: var(--text-sm);
    color: var(--text-muted);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-full);
    cursor: pointer;
}

.compare > summary:hover { color: var(--text); border-color: var(--border-strong); }
.compare[open] > summary { margin-bottom: var(--space-2); }

/* ---------- One trim ------------------------------------------------------ */

.trim-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-5);
    align-items: start;
}

@media (min-width: 980px) {
    .trim-layout { grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); }
}

.trim-layout__text h1 { font-size: var(--text-3xl); line-height: 1.1; }
.trim-layout__text .eyebrow a { color: inherit; text-decoration: none; }
.trim-layout__text .eyebrow a:hover { text-decoration: underline; }

.trim-layout__year {
    margin-top: var(--space-2);
    font-size: var(--text-lg);
    font-variant-numeric: tabular-nums;
    color: var(--accent-text);
}

.spec-list {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 150px), 1fr));
    gap: var(--space-3) var(--space-4);
    margin: 0;
    padding-top: var(--space-4);
    border-top: 1px solid var(--border);
}

.spec-list dt {
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-dim);
}

.spec-list dd {
    margin: 2px 0 0;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

/* ---------- Gallery ------------------------------------------------------- */

.gallery__lead {
    position: relative;
    display: block;
    overflow: hidden;
    aspect-ratio: 16 / 10;
    background: var(--surface-sunken);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
}

.gallery__lead img { width: 100%; height: 100%; object-fit: cover; }

.gallery__open {
    position: absolute;
    left: var(--space-3);
    bottom: var(--space-3);
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-3);
    font-size: var(--text-sm);
    /* Over a photograph: its own ink and scrim, as on .gallery__tag. */
    color: #fff;
    background: rgb(0 0 0 / 0.78);
    border: 1px solid rgb(255 255 255 / 0.35);
    border-radius: var(--radius-full);
    backdrop-filter: blur(8px);
}

.gallery__open svg { width: 16px; height: 16px; }
.gallery__lead:hover .gallery__open { border-color: var(--accent); }

.gallery__strip {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 150px;
    gap: var(--space-3);
    margin-top: var(--space-3);
    overflow-x: auto;
    padding-bottom: var(--space-2);
    scrollbar-width: thin;
}

.gallery__thumb {
    display: block;
    overflow: hidden;
    aspect-ratio: 16 / 10;
    background: var(--surface-sunken);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
}

.gallery__thumb img { width: 100%; height: 100%; object-fit: cover; }
.gallery__thumb:hover { border-color: var(--accent-line); }

.gallery__empty {
    display: grid;
    gap: var(--space-3);
    justify-items: center;
    aspect-ratio: 16 / 10;
    align-content: center;
    border: 1px dashed var(--border-strong);
    border-radius: var(--radius-lg);
    overflow: hidden;
}

/* Other trims, as a rail rather than a second grid — they are a way back
   into the sub-catalog, not the subject of the page. */
.trim-rail {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(180px, 220px);
    gap: var(--space-3);
    overflow-x: auto;
    padding-bottom: var(--space-2);
    scrollbar-width: thin;
}

.trim-rail__item {
    display: grid;
    gap: 2px;
    padding-bottom: var(--space-3);
    text-decoration: none;
    color: inherit;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    overflow: hidden;
}

.trim-rail__item:hover { border-color: var(--accent-line); }

.trim-rail__media {
    display: block;
    aspect-ratio: 16 / 10;
    overflow: hidden;
    background: var(--surface-sunken);
}

.trim-rail__media img { width: 100%; height: 100%; object-fit: cover; }
.trim-rail__name { padding: var(--space-3) var(--space-3) 0; font-weight: 600; }
.trim-rail__meta { padding: 0 var(--space-3); font-size: var(--text-sm); color: var(--text-muted); }

/* ---------- Lightbox ------------------------------------------------------ */

body.has-lightbox { overflow: hidden; }

/*
 * A photo viewer is dark in both themes — that is what a light room does to a
 * projector — so it states its own colours rather than inheriting the page's.
 * Inheriting them is how the light theme ended up with charcoal captions on a
 * near-black ground.
 */
.lightbox {
    position: fixed;
    inset: 0;
    z-index: 300;
    display: grid;
    place-items: center;
    color-scheme: dark;

    --lightbox-ink:     hsl(210 30% 96%);
    --lightbox-muted:   hsl(214 16% 80%);
    --lightbox-dim:     hsl(214 12% 68%);
    --lightbox-surface: hsl(222 20% 14%);
    --lightbox-line:    hsl(215 18% 30%);
}

.lightbox[hidden] { display: none; }

.lightbox__backdrop {
    position: absolute;
    inset: 0;
    /* Nearly opaque and blurred: the page behind should not compete with the
       photograph, and a caption over live text is unreadable. */
    background: hsl(222 40% 2% / 0.97);
    backdrop-filter: blur(4px);
}

.lightbox__panel {
    position: relative;
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: center;
    gap: var(--space-3);
    width: min(1200px, 96vw);
    max-height: 94vh;
    padding: var(--space-4);
}

.lightbox__figure {
    grid-column: 2;
    margin: 0;
    display: grid;
    gap: var(--space-3);
    justify-items: center;
}

.lightbox__figure img {
    max-width: 100%;
    max-height: 78vh;
    object-fit: contain;
    border-radius: var(--radius-md);
    background: hsl(222 26% 8%);
}

.lightbox__caption {
    font-size: var(--text-sm);
    color: var(--lightbox-muted);
    text-align: center;
}

.lightbox__live {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
    align-items: baseline;
    justify-content: center;
}

.lightbox__count { font-variant-numeric: tabular-nums; color: var(--lightbox-dim); }

.lightbox__nav,
.lightbox__close {
    display: grid;
    place-items: center;
    width: 44px;
    height: 44px;
    font-size: 26px;
    line-height: 1;
    color: var(--lightbox-ink);
    background: var(--lightbox-surface);
    border: 1px solid var(--lightbox-line);
    border-radius: var(--radius-full);
    cursor: pointer;
}

.lightbox__nav:hover,
.lightbox__close:hover { border-color: var(--accent-line); color: var(--accent-text); }
.lightbox__nav[hidden] { visibility: hidden; display: grid; }

.lightbox__close {
    position: absolute;
    right: var(--space-4);
    top: var(--space-4);
    z-index: 1;
    font-size: 22px;
}

@media (max-width: 640px) {
    .lightbox__panel { grid-template-columns: minmax(0, 1fr); padding: var(--space-3); }
    .lightbox__figure { grid-column: 1; }
    .lightbox__nav--prev { position: absolute; left: var(--space-3); bottom: var(--space-4); }
    .lightbox__nav--next { position: absolute; right: var(--space-3); bottom: var(--space-4); }
}

/* ---------- Managing your own --------------------------------------------- */

.manage-list { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-3); }

.manage-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-4);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
}

.manage-row__text { flex: 1 1 240px; min-width: 0; }
.manage-row__title { font-size: var(--text-base); font-weight: 600; overflow-wrap: anywhere; }
.manage-row__title a { color: var(--accent-text); text-decoration: none; }
.manage-row__meta { margin-top: 2px; font-size: var(--text-sm); color: var(--text-muted); overflow-wrap: anywhere; }
.manage-row__actions { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-left: auto; }

.manage-columns {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-5);
    align-items: start;
}

@media (min-width: 1000px) {
    .manage-columns { grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); }
}

/* Creating something has nothing to put in a second column yet. */
.manage-single { max-width: 680px; }

.manage-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr));
    gap: var(--space-4);
}

/* The gallery editor: a thumbnail, its caption, its place in the running
   order, and the way out. */
.image-rows { display: grid; gap: var(--space-3); }

.image-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3);
    background: var(--surface-sunken);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
}

.image-row__thumb {
    position: relative;
    flex: 0 0 auto;
    width: 108px;
    aspect-ratio: 16 / 10;
    overflow: hidden;
    background: var(--bg-elevated);
    border-radius: var(--radius-sm);
}

.image-row__thumb img { width: 100%; height: 100%; object-fit: cover; }

.image-row__lead {
    position: absolute;
    left: 4px;
    bottom: 4px;
    padding: 1px 6px;
    font-size: 10px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--accent-ink);
    background: var(--accent-fill);
    border-radius: var(--radius-full);
}

/* Aqua's accent fill is a light gel; the badge's dark ink needs the stronger one. */
[data-skin="aqua"] .image-row__lead { background: var(--accent-fill-strong); }

.image-row__fields {
    flex: 1 1 220px;
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    min-width: 0;
}

.image-row__fields .input {
    flex: 1 1 180px;
    padding: 0.35rem 0.6rem;
    font-size: var(--text-sm);
}

/* An uploaded logo or photo, with the control to replace it underneath. */
.image-drop {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    padding: var(--space-3);
    background: var(--surface-sunken);
    border: 1px dashed var(--border-strong);
    border-radius: var(--radius-md);
}

.image-drop__preview {
    display: grid;
    place-items: center;
    flex: 0 0 auto;
    width: 88px;
    height: 88px;
    overflow: hidden;
    background: var(--bg-elevated);
    border-radius: var(--radius-sm);
}

.image-drop__preview img { width: 100%; height: 100%; object-fit: contain; }
.image-drop__controls { flex: 1 1 auto; min-width: 0; }
.image-drop input[type="file"] { max-width: 100%; font-size: var(--text-sm); color: var(--text-muted); }

/* ---------- Switching views ------------------------------------------------ */

.view-switch {
    display: inline-flex;
    gap: 2px;
    padding: 3px;
    background: var(--surface-sunken);
    border: 1px solid var(--border);
    border-radius: var(--radius-full);
}
.view-switch__item {
    padding: 0.4rem 0.95rem;
    color: var(--text-muted);
    font-size: var(--text-sm);
    font-weight: 600;
    text-decoration: none;
    border-radius: var(--radius-full);
}
.view-switch__item:hover { color: var(--text); }
.view-switch__item.is-current { color: var(--text); background: var(--surface); box-shadow: var(--shadow-sm); }

/* ---------- The timeline -------------------------------------------------- */

/*
 * Newest at the top, oldest at the bottom, a spine down the middle with the
 * cars either side of it. Card heights are fixed on purpose: the page changes
 * typeface as it moves between era skins, and a card that grew or shrank with
 * the font would move everything below it while you were reading.
 */
.tl {
    --tl-gap: var(--space-7);
    position: relative;
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-5);
    margin-top: var(--space-6);
}

/* The rail's column exists only when the rail does (.tl--railed). Reserving it
   for every timeline put a one-decade marque's whole history in 96 pixels. */
@media (min-width: 1100px) {
    .tl--railed { grid-template-columns: 96px minmax(0, 1fr); gap: var(--space-6); }
}

/* Decades: a column on the left of a wide screen, a strip under the header
   on a narrow one. */
.tl-rail {
    position: sticky;
    top: var(--header-height);
    z-index: 5;
    display: flex;
    gap: var(--space-1);
    margin-inline: calc(-1 * clamp(var(--space-4), 4vw, var(--space-6)));
    padding: var(--space-2) clamp(var(--space-4), 4vw, var(--space-6));
    overflow-x: auto;
    background: var(--bg);
    border-bottom: 1px solid var(--border);
    scrollbar-width: none;
}
.tl-rail::-webkit-scrollbar { display: none; }

@media (min-width: 1100px) {
    .tl-rail {
        top: calc(var(--header-height) + var(--space-5));
        align-self: start;
        flex-direction: column;
        margin: 0;
        padding: 0;
        overflow: visible;
        background: none;
        border: 0;
    }
}

.tl-rail__item {
    flex: 0 0 auto;
    padding: 0.35rem 0.75rem;
    color: var(--text-dim);
    font-size: var(--text-sm);
    font-variant-numeric: tabular-nums;
    text-decoration: none;
    border-radius: var(--radius-full);
}
.tl-rail__item:hover { color: var(--text); background: var(--surface-hover); }
.tl-rail__item.is-current { color: var(--accent-text); background: var(--accent-soft); font-weight: 650; }

.tl-decades { position: relative; margin: 0; padding: 0; list-style: none; }

/* The spine. */
.tl-decades::before {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: 50%;
    width: 2px;
    transform: translateX(-1px);
    background: linear-gradient(180deg, var(--accent-line), var(--border-strong) 30%, var(--border));
}

.tl-decade + .tl-decade { margin-top: var(--space-8); }

.tl-decade__head {
    position: relative;
    z-index: 1;
    display: grid;
    justify-items: center;
    gap: 2px;
    width: fit-content;
    min-width: min(100%, 260px);
    margin-inline: auto;
    padding: var(--space-4) var(--space-6);
    text-align: center;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow);
    scroll-margin-top: calc(var(--header-height) + 4rem);
}
.tl-decade__title { font-size: var(--text-3xl); line-height: 1; font-variant-numeric: tabular-nums; }
.tl-decade__era { margin-top: var(--space-2); color: var(--accent-text); font-size: var(--text-xs); font-weight: 650; letter-spacing: 0.1em; text-transform: uppercase; }
.tl-decade__count { color: var(--text-dim); font-size: var(--text-sm); }

.tl-years { display: grid; gap: var(--space-6); margin: var(--space-6) 0 0; padding: 0; list-style: none; }
.tl-year { position: relative; display: grid; gap: var(--space-3); }

.tl-year__label { position: relative; z-index: 1; justify-self: center; margin: 0; font-size: var(--text-lg); line-height: 1; }
.tl-year__number {
    position: relative;
    display: inline-block;
    padding: 0.3rem 0.9rem;
    color: var(--text);
    font-variant-numeric: tabular-nums;
    background: var(--bg-elevated);
    border: 2px solid var(--accent);
    border-radius: var(--radius-full);
}

.tl-events {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-auto-flow: row dense;
    gap: var(--space-3) var(--tl-gap);
    margin: 0;
    padding: 0;
    list-style: none;
}
.tl-event { position: relative; }

/* A short arm from each card to the spine. */
.tl-event::after {
    content: "";
    position: absolute;
    top: 50%;
    width: calc(var(--tl-gap) / 2);
    height: 2px;
    background: var(--border-strong);
}
.tl-event--left { grid-column: 1; }
.tl-event--right { grid-column: 2; }
.tl-event--left::after { right: calc(var(--tl-gap) / -2); }
.tl-event--right::after { left: calc(var(--tl-gap) / -2); }

.tl-card {
    position: relative;
    display: grid;
    grid-template-columns: 136px minmax(0, 1fr);
    grid-template-rows: auto minmax(0, 1fr);
    /* A minimum, not a height: a card says what kind of car it is and how far it goes, and that line
       wraps where the card is narrow rather than being cut off. */
    min-height: 100px;
    overflow: hidden;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    transition: border-color var(--normal) var(--ease), transform var(--normal) var(--ease), box-shadow var(--normal) var(--ease);
}
/* A skin's title bar spans the card rather than taking the picture's cell. */
.tl-card::before { grid-column: 1 / -1; }
.tl-card:hover { border-color: var(--accent-line); transform: translateY(-2px); box-shadow: var(--shadow-md); }

.tl-card__media { grid-row: 2; height: 100%; overflow: hidden; background: var(--surface-sunken); }
.tl-card__media img { width: 100%; height: 100%; object-fit: cover; }
.tl-card__media .silhouette { padding: var(--space-2); gap: 0; }
.tl-card__media .silhouette svg { width: 92%; }
.tl-card__media .silhouette__label { display: none; }

.tl-card__body {
    grid-row: 2;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 2px;
    min-width: 0;
    padding: 0 var(--space-4);
}
.tl-card__body > * { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tl-card__marque { color: var(--text-dim); font-size: var(--text-xs); letter-spacing: 0.06em; text-transform: uppercase; }
.tl-card__name { font-size: var(--text-md); line-height: 1.3; }
.tl-card__link { color: inherit; text-decoration: none; }
.tl-card__link::after { content: ""; position: absolute; inset: 0; z-index: 1; }
.tl-card:hover .tl-card__link { color: var(--accent-text); }
.tl-card__meta { color: var(--text-muted); font-size: var(--text-sm); }
/* Wraps, whatever the card's width: the kind of car and how far it goes are the end of the line. */
.tl-card__body > .tl-card__meta { white-space: normal; overflow: visible; text-wrap: pretty; }

.tl-markers { display: grid; justify-items: center; gap: var(--space-2); margin: 0; padding: 0; list-style: none; }
.tl-marker {
    position: relative;
    z-index: 1;
    max-width: 100%;
    padding: 0.3rem 0.9rem;
    color: var(--text-muted);
    font-size: var(--text-sm);
    background: var(--bg-elevated);
    border: 1px dashed var(--border-strong);
    border-radius: var(--radius-full);
}
.tl-marker::before { content: "◆"; margin-right: 0.45em; color: var(--accent-text); }
.tl-marker--ended::before,
.tl-marker--closed::before { content: "◇"; color: var(--text-dim); }

/* One column with the spine down the left on anything narrower. */
@media (max-width: 820px) {
    .tl { --tl-gap: var(--space-5); }
    .tl-decades::before { left: 15px; }
    .tl-decade__head { justify-items: start; margin-inline: 0 0; text-align: left; padding: var(--space-3) var(--space-4); margin-left: 0; }
    .tl-years, .tl-markers, .tl-concepts { padding-left: 38px; }
    .tl-year__label { justify-self: start; margin-left: -38px; }
    .tl-events { grid-template-columns: minmax(0, 1fr); }
    .tl-event--left, .tl-event--right { grid-column: 1; }
    .tl-event--left::after,
    .tl-event--right::after { left: calc(-38px + 16px); right: auto; width: 22px; }
    .tl-markers { justify-items: start; }
    .tl-concepts { justify-content: flex-start; }
    .tl-card { grid-template-columns: 108px minmax(0, 1fr); min-height: 92px; }
}

/* ---------- Which era you are in ----------------------------------------- */

.tl-era {
    position: fixed;
    left: var(--space-4);
    bottom: var(--space-4);
    z-index: 60;
    display: flex;
    align-items: center;
    gap: var(--space-3);
    max-width: calc(100vw - 2rem);
    padding: 0.4rem 0.45rem 0.4rem 1rem;
    color: var(--text);
    font-size: var(--text-sm);
    background: var(--bg-elevated);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-full);
    box-shadow: var(--shadow-lg);
}
.tl-era__label { overflow: hidden; font-weight: 650; font-variant-numeric: tabular-nums; text-overflow: ellipsis; white-space: nowrap; }
.tl-era__toggle {
    flex: 0 0 auto;
    padding: 0.3rem 0.75rem;
    color: var(--accent-text);
    font-size: var(--text-xs);
    font-weight: 650;
    background: var(--accent-soft);
    border: 1px solid var(--accent-line);
    border-radius: var(--radius-full);
}
.tl-era__toggle[aria-pressed="false"] { color: var(--text-muted); background: var(--surface); border-color: var(--border); }

/* Room under the footer for the badge, so it never sits on the last line. */
body:has(.tl-era:not([hidden])) :is(.site-footer, .vip-footer) { padding-bottom: 5.5rem; }

/* The badge gives a little bounce when the era changes under it. */
@keyframes tl-era-new {
    from { transform: scale(0.94); }
    60%  { transform: scale(1.03); }
    to   { transform: none; }
}
.tl-era.is-new { animation: tl-era-new 0.5s var(--ease-out); }

/* ---------- Managing: prices and photographs (manage side) ----------------
   Merge into catalog.css under "Managing your own". Delete `.image-row__order`
   (the numeric position input is gone). Tokens only. */

/* A text box with the marque's currency sign in front of it. The sign is
   decoration: the label already says which currency. */
.input-affix { display: flex; align-items: stretch; }

.input-affix__prefix {
    display: flex;
    align-items: center;
    flex: 0 0 auto;
    padding: 0 var(--space-3);
    color: var(--text-muted);
    background: var(--surface-sunken);
    border: 1px solid var(--border);
    border-right: 0;
    border-radius: var(--radius) 0 0 var(--radius);
}

.input-affix .input {
    flex: 1 1 auto;
    min-width: 0;
}

.input-affix__prefix + .input {
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
}

/* Fieldsets used only to group: no border, no padding, and free to shrink. */
.photo-cover,
.photo-add {
    min-width: 0;
    margin-inline: 0;
    padding: 0;
    border: 0;
}

/* A legend is not reliably a flex container, so .label's flex is undone here. */
.photo-add__legend { display: block; padding: 0; margin-bottom: var(--space-3); }

/* The "Still missing" hint above the rows. */
.photo-missing { color: var(--text-muted); }

/* One single-file input per view the trim still lacks. */
.photo-slots {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr));
    gap: var(--space-3);
}

/* The view of a photograph. A photograph with none says so in words
   ("Which view?"); the dashed edge is only a second cue. */
.image-row__view { flex: 0 1 14rem; min-width: 12rem; padding: 0.35rem 2.25rem 0.35rem 0.6rem; font-size: var(--text-sm); }
.image-row__view.is-unset { border-style: dashed; border-color: var(--accent-line); color: var(--text-muted); }

/* The cover radio and the Remove button, together at the end of the row. */
.image-row__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-3);
    margin-left: auto;
}

.image-row__cover {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    min-height: 2.75rem;
    font-size: var(--text-sm);
    cursor: pointer;
}

.image-row__cover input {
    flex: 0 0 auto;
    width: 1.1rem;
    height: 1.1rem;
    margin: 0;
    accent-color: var(--accent);
    cursor: pointer;
}

/* ==========================================================================
   PUBLIC SIDE: catalog prices, trim browsing, view-tagged photographs.
   Fragment for public/assets/css/catalog.css. Theme tokens only; nothing here
   puts a grid or flex on a .container. Mobile-first (one column at 360px).

   Classes: .model-hero__price, .model-card__price, .trim-card__price,
   .trim-controls (+ __field, __actions), .trim-status,
   .trim-group (+ __head, __title, __summary), .gallery__tag,
   and position: relative on .gallery__thumb.
   ========================================================================== */

/* ---------- Prices ---------------------------------------------------------- */

/* The model's price range under its years in the hero: the figure is the
   headline, "6 of 8 trims priced" is the small print. */
.model-hero__price {
    margin-top: var(--space-2);
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}

.model-hero__price strong { color: var(--text); font-size: var(--text-lg); }

.model-card__price,
.trim-card__price {
    margin-top: var(--space-2);
    font-variant-numeric: tabular-nums;
}

.model-card__price {
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--accent-text);
}

.trim-card__price {
    font-size: var(--text-lg);
    font-weight: 650;
    color: var(--text);
}

/* ---------- Browsing a long lineup ------------------------------------------ */

/* The controls are .filter-bar (skins already style it) laid out as a grid of
   labelled selects: one column on a phone, as many as fit from there. The
   double class beats .filter-bar's own margin and display wherever the
   stylesheets load. */
.filter-bar.trim-controls {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-3);
    align-items: end;
    margin: var(--space-4) 0 var(--space-2);
}

@media (min-width: 30em) {
    .filter-bar.trim-controls {
        grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
    }
}

.trim-controls__field { min-width: 0; }

/* On a phone the selects pair up, with Sort and the buttons across the full
   width, so the bar is about 340px tall rather than 627px and the first card
   is on screen after Apply. Under 22em two columns would clip the option text. */
@media (min-width: 22em) and (max-width: 29.999em) {
    .filter-bar.trim-controls { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .trim-controls__field:first-child,
    .trim-controls__actions { grid-column: 1 / -1; }
    .trim-controls__actions .btn { min-height: 2.75rem; }
}

.trim-controls .select { font-size: var(--text-sm); }

/* Apply is always there; Reset only appears once something is set. */
.trim-controls__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
}

/* "Showing 4 of 9 trims" */
.trim-status {
    margin: 0 0 var(--space-3);
    font-variant-numeric: tabular-nums;
}

/* A lineup split by engine (or year, or gearbox): a heading with its own
   one-line summary over each group's cards. */
.trim-group { margin-top: var(--space-6); }

.trim-group__head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--space-1) var(--space-4);
    padding-bottom: var(--space-2);
    border-bottom: 1px solid var(--border);
}

.trim-group__title { font-size: var(--text-xl); line-height: 1.2; overflow-wrap: anywhere; }

.trim-group__summary {
    overflow-wrap: anywhere;
    font-size: var(--text-sm);
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}

.trim-group .trim-grid { margin-top: var(--space-4); }

/* ---------- Photograph view tags -------------------------------------------- */

/* The view ("Side") on a picture, top left so it never meets the "Open
   gallery" pill at the bottom. Hidden from assistive technology: the alt text
   already says it. A label drawn on a photograph has to bring its own ink and
   scrim, because the photograph does not follow the skin: with the skin's
   tokens the pill was dark text on a dark scrim in eight of thirteen looks. */
.gallery__thumb { position: relative; }

.gallery__tag {
    position: absolute;
    left: var(--space-2);
    top: var(--space-2);
    width: max-content;
    max-width: calc(100% - var(--space-4));
    padding: 2px 9px;
    font-size: var(--text-xs);
    line-height: 1.4;
    letter-spacing: 0.04em;
    color: #fff;
    background: rgb(0 0 0 / 0.78);
    border: 1px solid rgb(255 255 255 / 0.35);
    border-radius: var(--radius-md);
    backdrop-filter: blur(6px);
    pointer-events: none;
}

/* ==========================================================================
   PUBLIC SIDE, STREAM D: an engine on every trim, engines side by side.
   Fragment for public/assets/css/catalog.css. Theme tokens only; nothing here
   puts a grid or flex on a .container. Mobile-first (390px, then wider).

   Classes: .price-label, .engine-overview (+ __hint, __wrap), .engine-table
   (+ __num, __note), the Engine link in .spec-list, and a pinned first column
   for .engine-table.
   ========================================================================== */

/* ---------- A bare number that is a price ------------------------------------ */

/* A marque with no currency prints plain numbers, and among the specs on a
   card "16,490" reads as one of them: "Price" in front says what it is. Small
   and muted, so the figure stays the headline. */
.price-label {
    font-size: var(--text-xs);
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-muted);
}

/* ---------- The engine on a trim's own page ---------------------------------- */

/* The Engine value links to the model's trims on that engine. The plain link
   colour fails contrast in several looks (see .compare-table thead th a). */
.spec-list dd a { color: var(--accent-text); }
.spec-list dd a:hover { color: var(--text); }

/* The rail's meta line now carries the engine as well: let a long one wrap
   rather than push the card wider than its column. */
.trim-rail__meta { overflow-wrap: anywhere; }

/* ---------- Engines side by side --------------------------------------------- */

.engine-overview__hint { margin-top: var(--space-1); }

/* The table is a .table in a .table-wrap, which scrolls sideways inside itself,
   so a phone never scrolls the page. */
.engine-table th,
.engine-table td {
    padding-inline: var(--space-3);
    vertical-align: baseline;
}

.engine-table td,
.engine-table th[scope="col"] { white-space: nowrap; }

/* Figures read down a column: right-aligned and tabular. */
.engine-table .engine-table__num {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* "Manual, Dual-clutch" may wrap; a column of figures may not. */
.engine-table td:last-child { white-space: normal; min-width: 9rem; }

/* "1 of 2 priced" under a price that is only some of the trims'. */
.engine-table__note {
    display: block;
    font-size: var(--text-xs);
    font-weight: 400;
}

.engine-table a { color: var(--accent-text); font-weight: 600; }
.engine-table a:hover { color: var(--text); }

/* The engine the trims below are filtered to. */
.engine-table tbody tr.is-current { background: var(--accent-soft); }

/* ---------- A pinned first column -------------------------------------------- */

/* Scrolled sideways, a row of figures must still say whose they are, so the
   name stays at the left edge. It has to be opaque or the figures sliding
   under it show through, and several looks make --surface see-through, so
   the tint is laid over --bg. Its states are spelled out because a cell's own
   background hides the row's. The corner cell sits above the other headings,
   which are sticky too. */
.engine-table tbody th[scope="row"] {
    position: sticky;
    left: 0;
    z-index: 1;
    min-width: 6rem;
    max-width: 10rem;
    padding-inline: var(--space-3);
    overflow-wrap: anywhere;
    background: linear-gradient(var(--surface), var(--surface)), var(--bg);
    box-shadow: 1px 0 0 var(--border);
}

.engine-table tbody tr:hover > th[scope="row"] {
    background: linear-gradient(var(--surface-hover), var(--surface-hover)), var(--bg);
}

.engine-table tbody tr.is-current > th[scope="row"] {
    background: linear-gradient(var(--accent-soft), var(--accent-soft)), linear-gradient(var(--surface), var(--surface)), var(--bg);
}

.engine-table thead th:first-child {
    position: sticky;
    left: 0;
    z-index: 2;
    padding-inline: var(--space-3);
    box-shadow: 1px 0 0 var(--border);
}

@media (min-width: 40em) {
    .engine-table tbody th[scope="row"] { max-width: 16rem; }
}

/* ---------- Long names ----------------------------------------------------- */

/* A 60-character name with no space in it (a model code, a pasted URL) has
   nowhere to break: without these it pushes the page sideways on the trim page
   and in the editor, and is cut off at the edge of a card. */
.trim-layout__text h1,
.trim-layout__year,
.spec-list dd,
.section-head h1,
.section-head p,
.breadcrumb li,
.trim-card__name,
.trim-card__engine,
.trim-rail__name,
.trim-rail__meta,
.silhouette__label { overflow-wrap: anywhere; }

.silhouette__label { text-align: center; }

/* "Save and add another like this" is longer than a phone's panel is wide. */
.panel .btn[name="then"] { max-width: 100%; white-space: normal; text-align: left; }

/* ==========================================================================
   Release order, a chosen cover, electric and hybrid cars, and a comparison
   table that reads down the page. Theme tokens only; nothing here puts a grid
   or flex on a .container. Mobile-first.
   ========================================================================== */

/* ---------- What a car runs on ---------------------------------------------- */

/* A small badge with a coloured dot. The dot is decoration: the words say it. */
.kind-badge {
    --kind: var(--accent);
    display: inline-flex;
    align-items: center;
    gap: 0.4em;
    padding: 2px 9px;
    font-size: var(--text-xs);
    font-weight: 600;
    line-height: 1.5;
    white-space: nowrap;
    border-radius: var(--radius-full);
}

.kind-badge::before {
    content: "";
    flex: none;
    width: 0.55em;
    height: 0.55em;
    background: var(--kind);
    border-radius: 50%;
}

.kind-badge[data-kind="electric"]   { --kind: hsl(152 66% 46%); }
.kind-badge[data-kind="plugin"]     { --kind: hsl(186 70% 48%); }
.kind-badge[data-kind="hybrid"]     { --kind: hsl(84 62% 50%); }
.kind-badge[data-kind="combustion"] { --kind: hsl(30 80% 56%); }

/* On the page itself: a quiet pill. */
.kind-badge--solid {
    color: var(--text);
    background: var(--surface-sunken);
    border: 1px solid var(--border);
}

/* Over a photograph: its own ink and scrim, as on .gallery__tag and the year. */
.kind-badge--over,
.model-card__kinds .kind-badge {
    color: #fff;
    background: rgb(0 0 0 / 0.78);
    backdrop-filter: blur(6px);
}

.kind-badge--over { position: absolute; left: var(--space-3); top: var(--space-3); }

/* The years sit at the top right of a card's picture, so the kinds take the left. */
.model-card__kinds {
    position: absolute;
    left: var(--space-3);
    top: var(--space-3);
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    max-width: calc(100% - 6.5rem);
}

.model-hero__kinds {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2) var(--space-3);
    margin-top: var(--space-3);
}

.model-hero__range { font-size: var(--text-sm); color: var(--text-muted); }
.model-hero__range strong { color: var(--text); font-variant-numeric: tabular-nums; }
.trim-layout__kind { margin-top: var(--space-2); }

/* ---------- Putting a lineup in order ----------------------------------------- */

.lineup-head {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--space-3) var(--space-5);
}

.lineup-sort {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
}

.lineup-sort .label { margin: 0; white-space: nowrap; }
.lineup-sort .select { flex: 1 1 11rem; width: auto; min-width: 0; }

/* A label stays with its select when the form wraps on a narrow screen. */
.lineup-sort__field { display: flex; flex: 1 1 14rem; align-items: center; gap: var(--space-2); min-width: 0; }
.lineup-sort__field .select { flex: 1 1 8rem; }

/* With both a sort and a grouping the form holds two selects: on a wide screen it stays one line
   rather than leaving its button alone on a second. */
@media (min-width: 701px) {
    .lineup-sort { flex-wrap: nowrap; }
}

/* ---------- A trim's figures, in groups --------------------------------------- */

.spec-group__title {
    margin-bottom: var(--space-1);
    font-size: var(--text-xs);
    font-weight: 650;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-dim);
}

/* The kilowatts beside the horsepower, the "from battery and range" beside a worked-out figure. */
.spec-note { font-size: var(--text-sm); color: var(--text-dim); }

/* ---------- Trims side by side -------------------------------------------------- */

/* Both ways inside itself: the names stay in view going down, and the figures'
   names going across. Without a height it would scroll the page instead, and the
   header would have nothing to stay in view of. The box is as wide as its table
   and no wider: two trims are a narrow box, not a page of empty cells. */
.compare-wrap {
    width: fit-content;
    max-width: 100%;
    max-height: min(78vh, 52rem);
    overflow: auto;
}

.compare-table {
    width: auto;
    font-size: var(--text-sm);
}

/* A comparison has a lot of rows and a few words in each: tight, not a form. */
.compare-table th,
.compare-table td {
    padding: 0.3rem 0.75rem;
    line-height: 1.35;
    vertical-align: baseline;
}

.compare-table td {
    min-width: 7.5rem;
    font-variant-numeric: tabular-nums;
    /* A figure and its unit stay together... */
    white-space: nowrap;
}

/* ...and words may wrap, in a column that will not grow for them. A table cell's
   own max-width is not reliably honoured, so the words sit in a box that has one. */
.compare-table td.is-text { min-width: 9rem; white-space: normal; }

.compare-table__words {
    display: inline-block;
    max-width: 12rem;
    overflow-wrap: anywhere;
}

/* The names: headings, but not the small capitals the other tables use. The link
   colour fails contrast in five of the looks, and it only shows once the table
   is opened. */
.compare-table thead th {
    min-width: 8rem;
    max-width: 14rem;
    padding-block: 0.5rem;
    font-size: var(--text-sm);
    font-weight: 650;
    letter-spacing: 0;
    text-transform: none;
    white-space: normal;
    vertical-align: bottom;
    color: var(--text);
}

.compare-table thead th > a { display: inline-block; max-width: 12rem; overflow-wrap: anywhere; }

/* Several looks give a table's heading row a band of its own, with a text colour chosen for it
   (themes.css, ".table thead th"). The names are links, and a link colour chosen for the page
   fails on those bands (an orange accent on a teal one), so they take the band's colour and are
   marked as links by the underline, as the words under them are by being smaller. */
.compare-table thead th a {
    color: inherit;
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 0.2em;
}
.compare-table thead th a:hover { text-decoration-thickness: 2px; }

.compare-table__sub {
    display: block;
    max-width: 12rem;
    margin-top: 2px;
    font-size: var(--text-xs);
    font-weight: 450;
    color: inherit;
}

/* The figure names stay at the left when it scrolls sideways. They have to be
   opaque or the figures sliding under them show through, and several looks make
   --surface see-through, so the tint is laid over --bg. The states are spelled
   out because a cell's own background hides the row's. The corner is above the
   other headings, which are sticky as well. */
.compare-table tbody th[scope="row"] {
    position: sticky;
    left: 0;
    z-index: 1;
    min-width: 8rem;
    max-width: 12rem;
    font-weight: 600;
    color: var(--text-muted);
    white-space: normal;
    background: linear-gradient(var(--surface), var(--surface)), var(--bg);
    box-shadow: 1px 0 0 var(--border);
}

.compare-table tbody tr:hover > th[scope="row"] {
    background: linear-gradient(var(--surface-hover), var(--surface-hover)), var(--bg);
}

.compare-table thead th:first-child {
    position: sticky;
    left: 0;
    z-index: 3;
    box-shadow: 1px 0 0 var(--border);
}

/* A heading for the rows under it. Its words are what stays at the left, since
   the cell itself is as wide as the table. */
.compare-table__group th {
    padding-block: 0.25rem;
    font-size: var(--text-xs);
    font-weight: 650;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-dim);
    background: linear-gradient(var(--surface-sunken), var(--surface-sunken)), var(--bg);
    border-top: 1px solid var(--border-strong);
}

.compare-table__group th span { position: sticky; left: var(--space-3); }
.compare-table tbody tr.compare-table__group:hover { background: none; }

/* The best figure of a row where better is clear. Colour is not the only
   signal: it is bold, it has a bar, and a screen reader is told. */
.compare-table td.is-best {
    font-weight: 650;
    color: var(--text);
    background: var(--accent-soft);
    box-shadow: inset 3px 0 0 var(--accent);
}

.compare-table td.is-missing { color: var(--text-dim); }

.compare-table__note {
    margin-left: 0.35em;
    font-size: var(--text-xs);
    font-weight: 400;
    color: var(--text-dim);
}

.compare__legend { display: flex; align-items: center; gap: var(--space-2); }

.compare__key {
    flex: none;
    width: 1.1rem;
    height: 0.9rem;
    background: var(--accent-soft);
    border-radius: 2px;
    box-shadow: inset 3px 0 0 var(--accent);
}

/* "Only what differs" is a checkbox and a selector, so a browser that cannot
   do the selector is not shown a control that does nothing. */
.compare__fold { display: none; margin-top: var(--space-3); }

@supports selector(:has(*)) {
    .compare__fold { display: inline-flex; }
    .compare:has(#compare-differences:checked) .compare-table .is-same { display: none; }
}

@media (max-width: 40em) {
    .compare-table tbody th[scope="row"] { min-width: 6.5rem; max-width: 8rem; }
    .compare-table td { min-width: 6.5rem; }
    .compare-wrap { max-height: 72vh; }
}

/* ---------- The editors: order, cover, electric ---------------------------------- */

/* The year a group of models came out in, in the lineup panel. */
.manage-year {
    margin: var(--space-4) 0 var(--space-2);
    font-size: var(--text-xs);
    font-weight: 650;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-dim);
}

.manage-year:first-child { margin-top: 0; }

/* Earlier and later: two small buttons, each its own form so neither needs a script. */
.order-buttons { display: inline-flex; gap: 2px; align-items: center; }
.order-buttons form { margin: 0; }
.order-buttons .btn { min-width: 2.25rem; padding-inline: 0.55rem; }
.order-buttons .btn[disabled] { opacity: 0.35; cursor: not-allowed; }

/* Choosing a model's picture from its trims' photographs. */
.cover-picker {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(8.5rem, 1fr));
    gap: var(--space-3);
    margin: 0;
    padding: 0;
    border: 0;
}

.cover-option {
    position: relative;
    display: grid;
    gap: var(--space-2);
    align-content: start;
    padding: var(--space-2);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    cursor: pointer;
}

.cover-option:hover { border-color: var(--border-strong); }
.cover-option:has(input:checked) { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft); }
.cover-option:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }

/* The real radio, kept visible over the picture: it is what a keyboard and a
   screen reader use, and what shows the choice where :has() is not supported. */
.cover-option__radio { position: absolute; left: var(--space-3); top: var(--space-3); z-index: 1; }

.cover-option__thumb {
    display: grid;
    place-items: center;
    aspect-ratio: 16 / 10;
    overflow: hidden;
    color: var(--text-dim);
    background: var(--surface-sunken);
    border-radius: var(--radius-sm);
}

.cover-option__thumb img { width: 100%; height: 100%; object-fit: cover; }
.cover-option__text { font-size: var(--text-xs); color: var(--text-muted); overflow-wrap: anywhere; }
.cover-option__text strong { display: block; color: var(--text); font-size: var(--text-sm); }

/* An electric car has no capacity or aspiration, and a combustion one no battery:
   the form says so by putting away what does not apply to the powertrain chosen.
   Everything shows while it is "not said", and wherever :has() cannot do this.
     .combustion-only  an engine's figures: capacity, aspiration, fuel economy
     .hybrid-only      a hybrid's two halves: engine alone, motor alone, total range
     .plugs-only       anything about a socket: AC and DC charging, the charge time
     .electric-only    the whole battery section */
.trim-form:has(#field-powertrain option[value="bev"]:checked) :is(.combustion-only, .hybrid-only),
.trim-form:has(#field-powertrain option[value="fcev"]:checked) :is(.combustion-only, .hybrid-only, .plugs-only),
.trim-form:has(#field-powertrain option[value="ice"]:checked) :is(.electric-only, .hybrid-only, .plugs-only),
.trim-form:has(#field-powertrain option[value="mhev"]:checked) .plugs-only,
.trim-form:has(#field-powertrain option[value="hev"]:checked) .plugs-only { display: none; }


/* ---------- Production, limited and concept cars -------------------------------- */

/*
 * A limited run is a card like the rest with a gold edge and a badge; a concept or
 * prototype is not a card at all (see .concepts and .tl-concept). The gold is a
 * fixed hue, not the marque's accent: "limited" means the same thing on every marque.
 */
.type-badge {
    --type: hsl(215 14% 62%);
    display: inline-flex;
    align-items: center;
    padding: 2px 9px;
    font-size: var(--text-xs);
    font-weight: 650;
    line-height: 1.5;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    white-space: nowrap;
    border-radius: var(--radius-full);
}

.type-badge[data-type="limited"] { --type: hsl(44 92% 56%); }

/* Over a photograph, bottom left: the kinds of car take its top left and the years its top right. */
.type-badge--over {
    position: absolute;
    left: var(--space-3);
    bottom: var(--space-3);
    color: hsl(44 90% 8%);
    background: var(--type);
}

/* On the page itself. */
.type-badge--solid {
    color: var(--text);
    background: var(--surface-sunken);
    border: 1px solid var(--type);
}

.model-card--limited { border-color: hsl(44 70% 50% / 0.55); box-shadow: 0 0 0 1px hsl(44 70% 50% / 0.2); }
.tl-card--limited { border-color: hsl(44 70% 50% / 0.55); }

.model-hero__tags {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2) var(--space-3);
    margin-top: var(--space-3);
}

.gen-badge {
    display: inline-flex;
    gap: 0.3em;
    padding: 2px 10px;
    font-size: var(--text-xs);
    font-weight: 600;
    color: var(--text);
    text-decoration: none;
    background: var(--surface-sunken);
    border: 1px solid var(--border);
    border-radius: var(--radius-full);
}
.gen-badge:hover { border-color: var(--accent-line); }

/* The concepts drawer: closed, a line that says how many and names them; open, small tiles. */
.concepts {
    margin-top: var(--space-6);
    border: 1px dashed var(--border-strong);
    border-radius: var(--radius-lg);
}
.concepts[open] { background: var(--surface-sunken); }

.concepts__summary {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--space-1) var(--space-3);
    padding: var(--space-3) var(--space-4);
    color: var(--text-muted);
    cursor: pointer;
    list-style: none;
}
.concepts__summary::-webkit-details-marker { display: none; }
.concepts__summary::before { content: "▸"; color: var(--text-dim); }
.concepts[open] > .concepts__summary::before { content: "▾"; }
.concepts__summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: var(--radius-md); }

.concepts__title { color: var(--text); font-weight: 650; }
.concepts__count {
    padding: 0 0.6em;
    font-size: var(--text-xs);
    font-variant-numeric: tabular-nums;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-full);
}
.concepts__names {
    flex: 1 1 14rem;
    min-width: 0;
    overflow: hidden;
    color: var(--text-dim);
    font-size: var(--text-sm);
    text-overflow: ellipsis;
    white-space: nowrap;
}
.concepts[open] .concepts__names { display: none; }

.concepts__note { margin: 0; padding: 0 var(--space-4); color: var(--text-dim); font-size: var(--text-sm); }

.concepts__list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 15rem), 1fr));
    gap: var(--space-2);
    margin: 0;
    padding: var(--space-3) var(--space-4) var(--space-4);
    list-style: none;
}

.concept__link {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-2);
    color: inherit;
    text-decoration: none;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
}
.concept__link:hover { border-color: var(--accent-line); }

.concept__thumb {
    flex: 0 0 4.5rem;
    aspect-ratio: 16 / 10;
    overflow: hidden;
    background: var(--surface-sunken);
    border-radius: var(--radius-sm);
    filter: grayscale(0.7);
}
.concept__link:hover .concept__thumb { filter: none; }
.concept__thumb img { width: 100%; height: 100%; object-fit: cover; }
.concept__thumb .silhouette { padding: 2px; gap: 0; }
.concept__thumb .silhouette svg { width: 92%; }
.concept__thumb .silhouette__label { display: none; }

.concept__text { display: grid; min-width: 0; }
.concept__name { font-size: var(--text-sm); font-weight: 600; overflow-wrap: anywhere; }
.concept__meta { color: var(--text-dim); font-size: var(--text-xs); }

/* The timeline's concepts: a faint line under the year's cars that still says it happened. */
.tl-concepts {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--space-2);
    margin: 0;
    padding: 0;
    list-style: none;
}
.tl-concept { position: relative; z-index: 1; max-width: 100%; }

.tl-concept__link {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.1rem 0.5em;
    max-width: 100%;
    padding: 0.25rem 0.8rem;
    color: var(--text-dim);
    font-size: var(--text-xs);
    text-decoration: none;
    background: var(--bg-elevated);
    border: 1px dashed var(--border);
    border-radius: var(--radius-full);
}
.tl-concept__link:hover { color: var(--text); border-color: var(--accent-line); }

.tl-concept__tag { font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; }
.tl-concept__tag::before { content: "◇ "; }
.tl-concept__marque { text-transform: uppercase; letter-spacing: 0.05em; }
.tl-concept__name { color: var(--text-muted); font-weight: 600; overflow-wrap: anywhere; }

/* A marque's own note on its timeline: a card of words, edged in the marque's colour. */
.tl-note {
    position: relative;
    padding: var(--space-3) var(--space-4);
    overflow-wrap: anywhere;
    background: var(--surface);
    border: 1px solid var(--border);
    border-left: 3px solid var(--accent);
    border-radius: var(--radius-md);
}
.tl-note__kind {
    color: var(--accent-text);
    font-size: var(--text-xs);
    font-weight: 650;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}
.tl-note__title { margin-top: 2px; font-size: var(--text-md); line-height: 1.3; }
.tl-note__body { margin-top: var(--space-2); color: var(--text-muted); font-size: var(--text-sm); }
.tl-note__body p + p { margin-top: var(--space-2); }

/* ---------- Generations ----------------------------------------------------------- */

/* On the marque's page: a heading, the years the generation spans, and its own grid. */
.generation + .generation,
.generation + .concepts { margin-top: var(--space-7); }

.generation { scroll-margin-top: calc(var(--header-height) + var(--space-4)); }

.generation__head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--space-1) var(--space-4);
    margin-bottom: var(--space-4);
    padding-bottom: var(--space-3);
    border-bottom: 1px solid var(--border);
}
.generation__title { font-size: var(--text-xl); }
.generation__meta { color: var(--text-muted); font-size: var(--text-sm); font-variant-numeric: tabular-nums; }
.generation__about { flex-basis: 100%; max-width: 68ch; color: var(--text-muted); font-size: var(--text-sm); }

/* In the editor: one generation is a name, some words, and the way out. */
.generation-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2) var(--space-3);
    padding: var(--space-3);
    background: var(--surface-sunken);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
}
.generation-row > form { margin: 0; }
.generation-row__form { display: flex; flex-wrap: wrap; gap: var(--space-2); flex: 1 1 280px; min-width: 0; }
.generation-row__form .input { flex: 1 1 140px; min-width: 0; padding: 0.35rem 0.6rem; font-size: var(--text-sm); }
.generation-row__form--new { padding-top: var(--space-3); border-top: 1px solid var(--border); }
.generation-row__meta { flex-basis: 100%; margin: 0; color: var(--text-muted); font-size: var(--text-sm); }

/* ---------- Accent colour picker ---------------------------------------------------- */

.accent-picker { display: flex; flex-wrap: wrap; gap: var(--space-2); }

.accent-option {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: 4px 12px 4px 8px;
    font-size: var(--text-sm);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-full);
    cursor: pointer;
}
.accent-option:hover { border-color: var(--border-strong); }
.accent-option:has(input[type="radio"]:checked) { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft); }
.accent-option:has(input[type="radio"]:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }
.accent-option__radio { margin: 0; accent-color: var(--accent); }

.accent-option__swatch {
    flex: none;
    width: 1.25rem;
    height: 1.25rem;
    border: 1px solid rgb(255 255 255 / 0.3);
    border-radius: 50%;
}

.accent-option__color {
    width: 2rem;
    height: 1.5rem;
    padding: 0;
    background: none;
    border: 0;
    cursor: pointer;
}

/* ---------- Limited-edition trims ------------------------------------------------ */

/* A trim limited by number has no end date, and one limited by time has no run: the form says so by
   putting away the figure that does not go with the kind chosen. Everything shows wherever :has()
   cannot do this, and the server keeps the unused figure empty either way (LimitedEdition::unusedColumns).
     .limited-number  how many were built
     .limited-time    the last year and month it was on sale */
.trim-form:has(#field-limited-type option[value=""]:checked) :is(.limited-number, .limited-time),
.trim-form:has(#field-limited-type option[value="number"]:checked) .limited-time,
.trim-form:has(#field-limited-type option[value="time"]:checked) .limited-number { display: none; }

/* Catalog files: the import page and the buttons that lead to it. */
.import-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.import-list { margin: var(--space-2) 0 0; padding-left: 1.2em; display: grid; gap: var(--space-1); }
.import-list li { overflow-wrap: anywhere; }
.import-where { font-weight: 600; }
.import-paste summary { cursor: pointer; color: var(--text-muted); font-size: var(--text-sm); }
.import-paste__box { width: 100%; margin-top: var(--space-2); font-family: var(--font-mono); font-size: var(--text-sm); }
.import-counts th[scope="row"] { font-weight: 500; }
/* Four columns on a phone: tighter cells and headings, and "Timeline notes" may take two lines. */
@media (max-width: 480px) {
    .import-counts th, .import-counts td { padding-left: 0.375rem; padding-right: 0.375rem; }
    .import-counts thead th { letter-spacing: 0.02em; }
}

/* A trim's colours, as swatches, and its equipment highlights. */
.trim-colours__label { font-size: var(--text-sm); font-weight: 600; color: var(--text-muted); margin: var(--space-3) 0 var(--space-2); }
.trim-colours { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-4); list-style: none; margin: 0; padding: 0; }
.trim-colour { display: inline-flex; align-items: center; gap: var(--space-2); font-size: var(--text-sm); }
.trim-colour__swatch { width: 1.25rem; height: 1.25rem; border-radius: 50%; flex: none; border: 1px solid var(--border-strong); box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.15); }
.trim-colour__swatch--unknown { background: repeating-linear-gradient(45deg, var(--surface-sunken) 0 3px, var(--border) 3px 6px); }
.trim-highlights { margin: var(--space-2) 0 0; padding-left: 1.2em; columns: 2 16rem; column-gap: var(--space-6); }
.trim-highlights li { break-inside: avoid; margin-bottom: var(--space-1); }

/* A trim's audio: the badge of each package fitted to it, and its owner's controls. */
.trim-audio dd { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.trim-audio__remove { margin-left: auto; }
/* The badge is the way to the package's page. */
.trim-audio__link { display: inline-flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); min-width: 0; color: inherit; text-decoration: none; border-radius: 999px; }
.trim-audio__link .audio-badge { transition: filter var(--fast) var(--ease); }
.trim-audio__link:hover .audio-badge { filter: brightness(1.12) saturate(1.1); }
.trim-audio__link:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.trim-audio__name { color: var(--accent-text); font-weight: 560; }
.trim-audio__link:hover .trim-audio__name { text-decoration: underline; }
.trim-audio__fit-row { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-1); }
.trim-audio__fit-row .select { flex: 1 1 14rem; min-width: 0; }
/* On a trim's card, its packages' badges under its figures (the card is the link); in the comparison table, a
   Sound system row, each badge the way to its package. */
.trim-card__audio { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); margin: var(--space-3) 0 0; padding-top: var(--space-3); border-top: 1px solid var(--border); }
.trim-card__audio .trim-card__label { flex-basis: 100%; }
.trim-card__audio .audio-badge { max-width: 100%; }
/* A badge is never cut short: the column is as wide as its widest badge, each package on a line of its own. */
.compare-table__audio td.is-text { min-width: 0; white-space: nowrap; }
.compare-table__audio-link { display: flex; flex-direction: column; align-items: flex-start; gap: 0.2rem; width: max-content; margin: 0.2rem 0; color: inherit; text-decoration: none; border-radius: 999px; }
.compare-table__audio-link .compare-table__note { margin-left: 0; }
.compare-table__audio-link:hover .audio-badge { filter: brightness(1.12) saturate(1.1); }
.compare-table__audio-link:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* -------------------------------------------------- Engine and platform registry */
/* The marque's registry page: one card per engine family and per platform, each with the cars that share it. */
.registry > h2 { margin-bottom: var(--space-3); }
.registry-card {
    padding: var(--space-4);
    margin-bottom: var(--space-4);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface);
    scroll-margin-top: var(--space-6);
}
.registry-card:target { border-color: var(--accent); }
.registry-card__head { margin-bottom: var(--space-3); }
.registry-card__title { margin: 0; font-size: var(--text-lg); }
.registry-card__meta { margin: 0.25rem 0 0; color: var(--text-muted); font-size: var(--text-sm); }
.registry-card__label { margin: var(--space-3) 0 var(--space-2); font-size: var(--text-sm); color: var(--text-muted); }
.registry-table { width: 100%; margin-top: var(--space-3); border-collapse: collapse; font-size: var(--text-sm); }
.registry-table th, .registry-table td { padding: 0.4rem 0.6rem; text-align: left; border-bottom: 1px solid var(--border); vertical-align: top; }
.registry-table thead th { color: var(--text-muted); font-weight: 500; }
@media (max-width: 640px) {
    .registry-table { display: block; overflow-x: auto; }
}
.registry-usage { margin: 0; padding-left: 1.2rem; font-size: var(--text-sm); }
.registry-usage li { margin: 0.2rem 0; }
.registry-usage a, .trim-engine a, .model-lineage a, .marque-hero__registry a { color: var(--accent-text); }
.marque-hero__registry { margin-top: var(--space-2); font-size: var(--text-sm); }
.trim-engine { margin-top: var(--space-2); font-size: var(--text-sm); }

/* What a model follows and what followed it: "Facelift of …", "Succeeded by …". */
.model-lineage { list-style: none; margin: var(--space-3) 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--space-2); font-size: var(--text-sm); }
.model-lineage li { padding: 0.2rem 0.65rem; border: 1px solid var(--border); border-radius: 999px; }
.model-lineage li[data-kind="facelift"] { border-style: dashed; }
.model-lineage__label { color: var(--text-muted); margin-right: 0.25rem; }

/* The short number boxes of an in-place row: a revision's years and figures, a platform's code. */
.generation-row__form .input--year { flex: 0 1 6.5rem; }

/* An engine's revisions: name, years and figures on one line, what changed and Save on the next, each
   box with a small label of its own above it. */
.revision-grid { display: grid; grid-template-columns: minmax(0, 2fr) repeat(4, minmax(0, 1fr)); gap: var(--space-2); align-items: end; flex: 1 1 0; min-width: 0; }
.revision-cell { display: flex; flex-direction: column; gap: 0.15rem; min-width: 0; margin: 0; }
.revision-cell > span { font-size: var(--text-xs, 0.75rem); color: var(--text-muted); }
.generation-row__form.revision-grid .input { flex: 0 0 auto; width: 100%; min-width: 0; }
.revision-cell:has(input[name="notes"]) { grid-column: 1 / 5; }
.revision-grid > .btn { justify-self: stretch; }
.generation-row:has(.revision-grid) { flex-wrap: nowrap; align-items: end; }
@media (max-width: 720px) {
    .revision-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .revision-cell:first-of-type, .revision-cell:has(input[name="notes"]) { grid-column: 1 / -1; }
    .generation-row:has(.revision-grid) { flex-wrap: wrap; }
    .generation-row > .revision-grid { flex-basis: 100%; }
}
