@charset "UTF-8";

/* ==========================================================================
   Asia Tech Times — stylesheet

   A single hand-written file, no build step. Everything is driven by the
   custom properties below, so re-skinning the site means changing one block.

   Contents
     1.  Tokens
     2.  Reset
     3.  Base typography
     4.  Layout primitives
     5.  Utilities
     6.  Buttons and links
     7.  Masthead
     8.  Guides strip and search
     9.  Main navigation
     10. Sections and headings
     11. Story cards and lists
     12. Pagination
     13. Forms
     14. Article body
     15. Footer
     16. Error pages and diagnostics
     17. Responsive
   ========================================================================== */

/* 1. Tokens
   ========================================================================== */

:root {
    /* Palette mirrored from the reference site: one warm accent against
       Tailwind's neutral greys and slates. The accent itself is set inline on
       <html> from the settings table, and the ink and tint are derived from it,
       so re-theming is a single value. The plain hex values come first as a
       fallback for browsers without color-mix(); the later declaration wins
       where it parses.

       The reference accent is hsl(353 84% 56%) — a crimson. */
    --accent: #ED3147;
    --accent-ink: #D8132A;
    --accent-tint: #FCDFE2;
    --accent-ink: color-mix(in srgb, var(--accent) 84%, #000);
    --accent-tint: color-mix(in srgb, var(--accent) 12%, #fff);

    /* Surfaces, in the same order they appear down the page: the title strip,
       the masthead band, white body, then the dark footer. */
    --paper: #FFFFFF;
    --band: #F3F4F6;
    --paper-tint: #F3F4F6;
    --strip: #D1D5DC;
    --strip-ink: #4A5565;
    --footer: #0F172B;
    --footer-ink: #FFFFFF;

    /* Ink */
    --ink: #020618;
    --ink-soft: #314158;
    --muted: #6A7282;

    /* Rules */
    --rule: #E2E8F0;
    --rule-strong: #CAD5E2;

    /* Status */
    --ok: #067647;
    --ok-tint: #ECFDF3;
    --danger: #B42318;
    --danger-tint: #FEF3F2;

    /* Type. The reference sets everything in the system stack, so there is no
       webfont to download and the site renders the same offline. --font-display
       is kept as a separate name so a distinct headline face can be introduced
       later without touching every rule.

       --font-serif is deliberately NOT a headline face. The reference keeps
       every heading in the sans stack and reserves a system serif for exactly
       two article accents — the pull quote and the drop cap on an article's
       opening paragraph. Defining it once here keeps those two rules in step,
       and it is used nowhere else. */
    --font-system: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
        "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji",
        "Segoe UI Emoji";
    --font-serif: ui-serif, Georgia, Cambria, "Times New Roman", Times, serif;
    --font-display: var(--font-system);
    --font-body: var(--font-system);

    /* Type scale. These are Tailwind's default steps, which is what the
       reference site is built on — matching them is most of what makes the two
       pages feel alike, more than the choice of family. */
    --text-xs: 0.75rem;      /* 12px  labels, meta       */
    --text-sm: 0.875rem;     /* 14px  secondary copy     */
    --text-base: 1rem;       /* 16px  body               */
    --text-lg: 1.125rem;     /* 18px  card titles        */
    --text-xl: 1.25rem;      /* 20px                     */
    --text-2xl: 1.5rem;      /* 24px  section headings   */
    --text-3xl: 1.875rem;    /* 30px                     */
    --text-4xl: 2.25rem;     /* 36px  lead headline      */

    /* Leading, from the same scale. */
    --leading-none: 1;
    --leading-tight: 1.25;
    --leading-snug: 1.375;
    --leading-normal: 1.5;
    --leading-relaxed: 1.625;
    /* Article copy sits between normal and relaxed: at 16px the reference runs
       articles tight (leading-normal), and this is our compromise between that
       and a comfortable long read. */
    --leading-copy: 1.6;

    /* Tracking. Uppercase labels run wide; only the largest headline runs tight. */
    --tracking-tight: -0.025em;
    --tracking-wider: 0.05em;

    /* Space */
    --gap: 1.25rem;
    --gap-lg: 2rem;
    --section-y: 3.5rem;

    /* Shape and width */
    --radius: 6px;
    --radius-sm: 4px;
    --radius-lg: 0.5rem;
    --container: 1240px;
    --container-narrow: 46rem;

    /* Elevation. The reference leans on shadow-sm for panels and steps up to
       shadow-md on hover; these are its values. */
    --shadow-sm: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
    --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
    --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);

    /* Band backgrounds. The reference separates content types by background
       rather than by headings alone: white for the lead, a near-white grey band
       for the second tier, and a full dark band for a different kind of content.
       An all-white page was the thing that made ours look flat. */
    --band-tint: #F8FAFC;
    --band-dark: #0F172B;
    --band-dark-card: #1D293D;
    --band-dark-rule: rgb(255 255 255 / 0.12);
    --band-dark-muted: #94A3B8;

    /* Motion. The reference uses transition-colors almost everywhere and
       transition-transform for pictures. */
    --speed: 150ms;
    --speed-slow: 250ms;
}

/* 2. Reset
   ========================================================================== */

*,
*::before,
*::after {
    box-sizing: border-box;
}

html {
    -webkit-text-size-adjust: 100%;
    scroll-behavior: smooth;
}

body {
    margin: 0;
    background-color: var(--paper);
    color: var(--ink-soft);
    font-family: var(--font-body);
    font-size: var(--text-base);
    line-height: var(--leading-normal);
    -webkit-font-smoothing: antialiased;
}

img,
picture,
svg,
video {
    display: block;
    max-width: 100%;
    height: auto;
}

h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd, ul, ol {
    margin: 0;
}

ul,
ol {
    padding: 0;
    list-style: none;
}

/* 3. Base typography
   ========================================================================== */

a {
    color: var(--accent);
    text-decoration: none;
    transition: color var(--speed) ease, text-decoration-color var(--speed) ease;
}

a:hover {
    text-decoration: underline;
    text-underline-offset: 3px;
}

/* Headlines use the same stack as body copy, matching the reference: the
   hierarchy comes from size, weight and leading, never from a change of face.
   Tracking is left alone at heading sizes except on the lead. */
h1, h2, h3, h4 {
    font-family: var(--font-display);
    font-weight: 700;
    letter-spacing: normal;
    line-height: var(--leading-tight);
    color: var(--ink);
}

h1 { font-size: var(--text-2xl); }
h2 { font-size: var(--text-2xl); }
h3 { font-size: var(--text-lg); }
h4 { font-size: var(--text-base); }

strong,
b {
    font-weight: 600;
}

code {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.9em;
    background-color: var(--paper-tint);
    border: 1px solid var(--rule);
    border-radius: var(--radius-sm);
    padding: 0.1em 0.35em;
}

/* Visible focus for keyboard users, never removed. */
:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
    border-radius: var(--radius-sm);
}

/* 4. Layout primitives
   ========================================================================== */

.container {
    width: 100%;
    max-width: var(--container);
    margin-inline: auto;
    padding-inline: var(--gap);
}

.container--narrow {
    max-width: var(--container-narrow);
}

.section {
    padding-block: var(--section-y);
}

/* A near-white band. Enough to separate a block of content from the white
   sections above and below it without becoming a colour of its own. */
.section--tint {
    background-color: var(--band-tint);
    border-top: 1px solid var(--rule);
    border-bottom: 1px solid var(--rule);
}

/* The dark band, used for a content type that should read as clearly not
   editorial: commercial material. Taken from the reference, which gives whole
   sections this treatment. */
.section--dark {
    background-color: var(--band-dark);
    color: #FFFFFF;
}

.section--dark .section__head,
.section--dark .pagehead {
    border-bottom-color: var(--band-dark-rule);
}

.section--dark .section__title,
.section--dark .storylist__title a,
.section--dark .card__title a {
    color: #FFFFFF;
}

.section--dark .card {
    background-color: var(--band-dark-card);
    border: 1px solid var(--band-dark-rule);
    box-shadow: none;
}

.section--dark .card:hover {
    box-shadow: var(--shadow-lg);
}

.section--dark .card__summary,
.section--dark .card__meta,
.section--dark .storylist__meta,
.section--dark .storymeta,
.section--dark .section__more {
    color: var(--band-dark-muted);
}

.section--dark .card__media,
.section--dark .storylist__thumb {
    border-color: var(--band-dark-rule);
}

/* The lead story on a dark band. It is not a .card, so it needs its own set of
   inversions. */
.section--dark .hero {
    border-bottom-color: var(--band-dark-rule);
}

.section--dark .hero__media {
    border-color: var(--band-dark-rule);
}

.section--dark .hero__title a {
    color: #FFFFFF;
}

.section--dark .hero__title a:hover,
.section--dark .hero:hover .hero__title a {
    color: var(--accent);
}

.section--dark .hero__summary {
    color: rgb(255 255 255 / 0.82);
}

.section--dark .hero__meta {
    color: var(--band-dark-muted);
}

/* A single hairline rule marks the seam between two story blocks. */
.rule {
    height: 1px;
    background-color: var(--rule);
    border: 0;
    margin-block: var(--gap-lg);
}

/* 5. Utilities
   ========================================================================== */

.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* The narrow band across the very top of the page, taken from the reference:
   the publication name sits in a grey strip above the masthead. It carries the
   page's h1, which is why the heading defaults are overridden here. */
.sitestrip {
    margin: 0;
    padding: 0.5rem 1rem;
    background-color: var(--strip);
    color: var(--strip-ink);
    text-align: center;
    font-family: var(--font-body);
    font-size: var(--text-xs);
    font-weight: 400;
    letter-spacing: 0;
    line-height: 1.5;
}

.skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 100;
    background-color: var(--accent);
    color: #fff;
    padding: 0.75rem 1rem;
    border-radius: 0 0 var(--radius) 0;
}

.skip-link:focus {
    left: 0;
}

.muted {
    color: var(--muted);
    font-size: var(--text-sm);
}

/* Section label. Uppercase with wide tracking is the reference's house style for
   this kind of label, so it is kept even though it is usually a default to avoid. */
.kicker {
    display: inline-block;
    font-family: var(--font-body);
    font-size: var(--text-xs);
    font-weight: 700;
    letter-spacing: var(--tracking-wider);
    text-transform: uppercase;
    color: var(--accent);
}

.lede {
    font-size: var(--text-base);
    line-height: var(--leading-relaxed);
    color: var(--ink-soft);
    max-width: 62ch;
}

.notice {
    margin-top: var(--gap-lg);
    padding: 1rem 1.25rem;
    border: 1px solid var(--rule);
    border-left: 3px solid var(--accent);
    border-radius: var(--radius);
    background-color: var(--accent-tint);
    font-size: var(--text-sm);
}

.notice--error {
    border-left-color: var(--danger);
    background-color: var(--danger-tint);
}

.notice--success {
    border-left-color: var(--ok);
    background-color: var(--ok-tint);
}

/* Pushed off-screen rather than hidden with display:none, because a fair number
   of bots skip fields that are display:none and fill ones that merely sit out
   of view. Also removed from the tab order in the markup. */
.honeypot {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

.notice p + p {
    margin-top: 0.5rem;
}

/* 6. Buttons
   ========================================================================== */

.button {
    display: inline-block;
    padding: 0.625rem 1.125rem;
    border: 1px solid var(--accent);
    border-radius: var(--radius);
    background-color: var(--accent);
    color: #fff;
    font-size: var(--text-sm);
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
    transition: background-color 120ms ease, border-color 120ms ease;
}

.button:hover {
    background-color: var(--accent-ink);
    border-color: var(--accent-ink);
    color: #fff;
    text-decoration: none;
}

.button--ghost {
    background-color: transparent;
    color: var(--accent);
}

.button--ghost:hover {
    background-color: var(--accent-tint);
    color: var(--accent-ink);
}

/* 7. Masthead
   ========================================================================== */

.masthead {
    background-color: var(--band);
}

.masthead__inner {
    width: 100%;
    max-width: var(--container);
    margin-inline: auto;
    padding: 1.75rem var(--gap);
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--gap);
}

.masthead__brand {
    display: block;
    color: inherit;
    text-decoration: none;
}

.masthead__brand:hover {
    text-decoration: none;
}

/* The wordmark is a vector lockup rather than live text: the letterforms are
   drawn as paths, so they render identically whatever fonts a machine happens to
   have installed. The link around it carries the site name for screen readers
   and search engines, so the image needs no text of its own. */
.logo {
    display: block;
    height: clamp(2.375rem, 4.6vw, 3.25rem);
    width: auto;
}

.masthead__region {
    font-size: var(--text-xs);
    font-weight: 700;
    letter-spacing: var(--tracking-wider);
    text-transform: uppercase;
    color: var(--accent);
}

/* The right of the masthead would otherwise be an empty void. The tagline earns
   the space and says what the publication is for. Hidden on narrow screens,
   where the guides strip is already doing a lot of work. */
.masthead__tagline {
    display: none;
    max-width: 24rem;
    text-align: right;
    font-size: var(--text-sm);
    line-height: 1.45;
    color: var(--muted);
}

/* 8. Guides strip and search
   ========================================================================== */

.guides {
    background-color: var(--paper);
    border-bottom: 1px solid var(--rule);
    /* The reference lifts this strip off the grey masthead above it. */
    box-shadow: var(--shadow-sm);
}

.guides__inner {
    width: 100%;
    max-width: var(--container);
    margin-inline: auto;
    padding: 0.75rem var(--gap);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem var(--gap);
}

.guides__links {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 1.25rem;
}

/* The short accent bar beside the label is the reference's one piece of
   decoration in the header, and it is where the brand colour first appears. */
.guides__label {
    display: inline-flex;
    align-items: center;
    gap: 0.75rem;
    padding-right: 0.875rem;
    border-right: 1px solid var(--rule-strong);
    font-size: var(--text-xs);
    font-weight: 700;
    letter-spacing: var(--tracking-wider);
    text-transform: uppercase;
    color: var(--accent);
}

.guides__label::before {
    content: "";
    width: 4px;
    height: 1.5rem;
    border-radius: 999px;
    background-color: var(--accent);
}

.guides__links a {
    font-size: var(--text-sm);
    font-weight: 500;
    color: var(--ink-soft);
}

.guides__links a:hover {
    color: var(--accent);
}

.search {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    border: 1px solid var(--rule-strong);
    border-radius: var(--radius);
    background-color: var(--paper);
    padding: 0.25rem 0.375rem 0.25rem 0.625rem;
}

.search input {
    flex: 1;
    min-width: 0;
    width: 12rem;
    border: 0;
    background: transparent;
    padding: 0.375rem 0;
    font: inherit;
    font-size: var(--text-sm);
    color: var(--ink);
}

.search input::placeholder {
    color: var(--muted);
}

.search input:focus {
    outline: none;
}

.search button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 0;
    background: transparent;
    padding: 0.375rem;
    color: var(--muted);
    cursor: pointer;
}

.search button:hover {
    color: var(--accent);
}

.search:focus-within {
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-tint);
}

.search--wide {
    width: 100%;
    margin-top: var(--gap-lg);
}

.search--wide input {
    width: 100%;
}

.search--wide button {
    padding-inline: 1rem;
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--accent);
}

/* 9. Main navigation
   ========================================================================== */

.mainnav {
    border-bottom: 1px solid var(--rule);
    background-color: var(--paper);
}

.mainnav__inner {
    width: 100%;
    max-width: var(--container);
    margin-inline: auto;
    padding-inline: var(--gap);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.25rem 1.5rem;
}

.mainnav__link {
    display: inline-block;
    padding: 0.875rem 0;
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--ink-soft);
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
}

.mainnav__link:hover {
    color: var(--accent);
    text-decoration: none;
}

.mainnav__link.is-active {
    color: var(--accent);
    border-bottom-color: var(--accent);
}

/* 10. Sections and headings
   ========================================================================== */

.section__head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.5rem var(--gap);
    margin-bottom: var(--gap);
    padding-bottom: 0.625rem;
    border-bottom: 1px solid var(--ink);
}

.section__title {
    font-size: var(--text-2xl);
    line-height: var(--leading-tight);
    margin: 0;
}

.section__more {
    font-size: var(--text-sm);
    font-weight: 600;
}

/* The first section sits directly under the navigation, so it needs less
   breathing room above than the sections that follow it. */
.section--lead {
    padding-top: var(--gap-lg);
}

/* Inside the tinted sponsored band a full-strength ink rule would shout. */
.section__head--sponsored {
    border-bottom-color: var(--rule-strong);
}

/* Heading block at the top of a listing page. */
.pagehead {
    margin-bottom: var(--gap-lg);
    padding-bottom: var(--gap);
    border-bottom: 1px solid var(--ink);
}

.pagehead__title {
    font-size: var(--text-3xl);
    line-height: var(--leading-tight);
}

.pagehead .lede {
    margin-top: 0.5rem;
}

.pagehead__count {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem 1rem;
    margin-top: 0.875rem;
    font-size: var(--text-sm);
    color: var(--muted);
}

/* Author profile header. A person leads the page, so the text sits centred
   under the portrait on narrow screens and beside it once there is room. */
.authorhead {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--gap);
    text-align: center;
    margin-bottom: var(--gap-lg);
    padding-bottom: var(--gap-lg);
    border-bottom: 1px solid var(--ink);
}

.authorhead__text {
    max-width: 60ch;
}

.authorhead__name {
    font-size: var(--text-3xl);
    font-weight: 800;
    line-height: var(--leading-tight);
    margin-top: 0.25rem;
}

.authorhead__bio {
    margin-top: 0.75rem;
    line-height: var(--leading-relaxed);
    color: var(--ink-soft);
}

.authorhead__count {
    margin-top: 0.75rem;
    font-size: var(--text-sm);
    color: var(--muted);
}

/* The portrait uses the same dark tone as the wordmark badge, with white
   initials, rather than inventing a second treatment for faces. */
.avatar {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 5rem;
    height: 5rem;
    flex-shrink: 0;
    overflow: hidden;
    border-radius: 50%;
    background-color: var(--band-dark);
    color: #FFFFFF;
    font-size: var(--text-xl);
    font-weight: 700;
    letter-spacing: 0.02em;
}

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

/* 11. Story cards and lists
   ========================================================================== */

.cardgrid {
    display: grid;
    gap: var(--gap);
    grid-template-columns: 1fr;
}

/* The grid continues the lead story without a heading between the two, so it
   only needs separation, not a label. */
.cardgrid--lead {
    margin-top: var(--gap-lg);
}

/* A card is a white panel with a small shadow, the treatment the reference gives
   its story tiles. Everything inside it responds together on hover: the picture
   scales, the shadow deepens and the headline turns to the accent colour. */
.card {
    display: flex;
    flex-direction: column;
    gap: 0.625rem;
    padding: 0.75rem;
    background-color: var(--paper);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    transition: box-shadow var(--speed) ease;
}

.card:hover {
    box-shadow: var(--shadow-md);
}

.card:hover .card__title a {
    color: var(--accent);
}

.card__media {
    display: block;
    overflow: hidden;
    border-radius: var(--radius);
    background-color: var(--paper-tint);
    border: 1px solid var(--rule);
    aspect-ratio: 16 / 9;
}

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

/* Pictures ease up slightly when their card is hovered, which is what the
   reference does with group-hover:scale-105. The wrapper clips the overflow. */
.card__media img,
.hero__media img,
.storylist__thumb img {
    transition: transform var(--speed-slow) ease;
}

.card:hover .card__media img,
.storylist__item:hover .storylist__thumb img,
.hero:hover .hero__media img {
    transform: scale(1.05);
}

.card__tag {
    font-size: var(--text-xs);
    font-weight: 700;
    letter-spacing: var(--tracking-wider);
    text-transform: uppercase;
    color: var(--accent);
}

/* Card headlines are one step down in weight from the lead. With a single
   typeface across the site, weight and size are what carry the hierarchy. */
.card__title {
    font-size: var(--text-lg);
    font-weight: 700;
    letter-spacing: normal;
    line-height: var(--leading-snug);
}

.card__title a {
    color: var(--ink);
}

.card__title a:hover {
    color: var(--accent);
    text-decoration: none;
}

.card__summary {
    font-size: var(--text-sm);
    color: var(--muted);
}

.card__meta {
    font-size: var(--text-xs);
    color: var(--muted);
    margin-top: auto;
    padding-top: 0.125rem;
}

/* Byline and date. Separated by space rather than a punctuation mark, so the
   pair reads cleanly without the usual interpunct clutter. Applied alongside
   .card__meta, .hero__meta and .storylist__meta, which set the type. */
.storymeta {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.125rem 0.75rem;
}

/* No underline by default. Eleven underlined author names down one page is
   visual noise; the affordance is kept on hover instead. */
.storymeta a {
    color: inherit;
    text-decoration: none;
}

.storymeta a:hover {
    color: var(--accent);
    text-decoration: underline;
    text-underline-offset: 3px;
}

.storymeta__date {
    font-variant-numeric: tabular-nums;
}

/* The lead story. Everything else on the page stays quiet around it. */
.hero {
    display: grid;
    gap: var(--gap-lg);
    grid-template-columns: 1fr;
    padding-bottom: var(--gap-lg);
    border-bottom: 1px solid var(--rule);
}

.hero__media {
    position: relative;
    display: block;
    overflow: hidden;
    border-radius: var(--radius);
    border: 1px solid var(--rule);
    background-color: var(--paper-tint);
    aspect-ratio: 16 / 9;
}

/* A scrim across the foot of the lead picture. The reference uses gradients this
   way — as a darkening layer over an image rather than as a decorative wash —
   and it gives the largest picture on the page some depth. */
.hero__media::after {
    content: "";
    position: absolute;
    inset: auto 0 0 0;
    height: 32%;
    background-image: linear-gradient(to top, rgb(2 6 24 / 0.2), transparent);
    pointer-events: none;
}

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

/* The lead headline follows the reference's treatment: extrabold at tight
   leading, stepping up through the breakpoints. Weight 800 is shared with an
   article title and an author name — the three places a headline is the only
   thing on the page. */
.hero__title {
    font-size: var(--text-2xl);
    font-weight: 800;
    line-height: var(--leading-tight);
    margin-top: 0.5rem;
}

.hero__title a {
    color: var(--ink);
}

.hero__title a:hover {
    color: var(--accent);
    text-decoration: none;
}

.hero__summary {
    margin-top: 0.75rem;
    font-size: var(--text-lg);
    line-height: var(--leading-relaxed);
    color: var(--ink-soft);
    max-width: 60ch;
}

.hero__meta {
    margin-top: 0.875rem;
    font-size: var(--text-sm);
    color: var(--muted);
}

/* A lead story with no artwork. Two classes deep on purpose, so this beats the
   two-column rule in the desktop media query no matter which comes later. */
.hero.hero--text-only {
    grid-template-columns: 1fr;
}

/* Held to a readable measure rather than running the full container width. The
   headline can breathe wider than the standfirst, which keeps its own 60ch cap. */
.hero--text-only .hero__text {
    max-width: 54rem;
}

/* Compact chronological list with thumbnails. */
.storylist {
    display: grid;
    gap: 0;
}

.storylist__item {
    display: grid;
    grid-template-columns: 6.5rem 1fr;
    gap: var(--gap);
    padding-block: 1.125rem;
    border-bottom: 1px solid var(--rule);
}

.storylist__item:first-child {
    padding-top: 0;
}

.storylist__item:last-child {
    border-bottom: 0;
}

.storylist__thumb {
    display: block;
    overflow: hidden;
    border-radius: var(--radius-sm);
    border: 1px solid var(--rule);
    background-color: var(--paper-tint);
    aspect-ratio: 4 / 3;
}

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

/* min-width:0 lets a long headline wrap instead of stretching the grid column. */
.storylist__text {
    min-width: 0;
}

/* Same treatment as .card__title. */
.storylist__title {
    font-size: var(--text-base);
    font-weight: 700;
    letter-spacing: normal;
    line-height: var(--leading-snug);
    margin-top: 0.125rem;
}

.storylist__title a {
    color: var(--ink);
}

.storylist__title a:hover {
    color: var(--accent);
    text-decoration: none;
}

.storylist__item:hover .storylist__title a {
    color: var(--accent);
}

.storylist__meta {
    margin-top: 0.375rem;
    font-size: var(--text-xs);
    color: var(--muted);
}

/* Without a thumbnail the row gives the whole width to the headline. */
.storylist__item.storylist__item--no-thumb {
    grid-template-columns: 1fr;
}

/* Promoted slot. Rendered on the dark band, which is what marks it out as a
   different kind of content from the editorial around it. */
.sponsored__label {
    font-size: var(--text-xs);
    font-weight: 700;
    letter-spacing: var(--tracking-wider);
    text-transform: uppercase;
    color: var(--band-dark-muted);
}

.section--sponsored {
    background-image: linear-gradient(
        to bottom,
        var(--band-dark) 0%,
        #16203A 50%,
        var(--band-dark) 100%
    );
}

/* The generated artwork is near-white, which reads as a bright plate on a dark
   band. That is the same as a photograph would read, so it is left alone. */
.sponsored .card__media {
    background-color: var(--paper);
}

.sponsored__item {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.sponsored__label {
    font-size: var(--text-xs);
    font-weight: 700;
    letter-spacing: var(--tracking-wider);
    text-transform: uppercase;
    color: var(--muted);
}

/* The band and the card placeholder share a background, so inside the band the
   media boxes switch to white to stay visible. */
.sponsored .card__media {
    background-color: var(--paper);
}

/* Search hit markers. Tinted rather than a browser default yellow, which would
   be the loudest thing on the page — but at 30% rather than the 12% used for
   panel backgrounds, because at 12% the marker was invisible on white, which
   defeats the point of a highlight. */
mark {
    background-color: #FAC1C8;
    background-color: color-mix(in srgb, var(--accent) 30%, #fff);
    color: var(--ink);
    padding: 0.05em 0.15em;
    border-radius: 2px;
}

/* The latest list beside a most-read aside. Stacks on narrow screens, where a
   second column would leave both too narrow to read. */
.homegrid {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--gap-lg);
}

/* Ranked list. The numbers carry information — the order — which is the one
   case where numbering is not decoration. */
.mostread__title {
    margin-bottom: var(--gap);
    padding-bottom: 0.625rem;
    border-bottom: 1px solid var(--ink);
    font-size: var(--text-lg);
    font-weight: 700;
}

.mostread__list {
    display: grid;
    gap: 0.875rem;
}

.mostread__item {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
}

.mostread__rank {
    flex-shrink: 0;
    min-width: 1.25rem;
    font-size: var(--text-xl);
    font-weight: 800;
    line-height: 1;
    font-variant-numeric: tabular-nums;
    color: var(--accent);
}

.mostread__headline {
    font-size: var(--text-base);
    font-weight: 700;
    line-height: var(--leading-snug);
}

.mostread__headline a {
    color: var(--ink);
}

.mostread__item:hover .mostread__headline a {
    color: var(--accent);
}

.mostread__meta {
    margin-top: 0.125rem;
    font-size: var(--text-xs);
    color: var(--muted);
}

/* Related stories sit below the article, at container width rather than the
   article's reading measure, because three cards need the room. */
.related {
    margin-top: var(--section-y);
    padding-top: var(--gap-lg);
    border-top: 1px solid var(--rule);
}

/* Empty states are an invitation, not a dead end. */
.empty {    padding: var(--gap-lg);
    border: 1px dashed var(--rule-strong);
    border-radius: var(--radius);
    text-align: center;
    color: var(--muted);
}

.empty__title {
    font-size: var(--text-lg);
    margin-bottom: 0.375rem;
}

/* 12. Pagination
   ========================================================================== */

.pagination {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 0.375rem;
    margin-top: var(--gap-lg);
    padding-top: var(--gap-lg);
    border-top: 1px solid var(--rule);
}

.pagination a,
.pagination span {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 2.5rem;
    min-height: 2.5rem;
    padding: 0 0.625rem;
    border: 1px solid var(--rule);
    border-radius: var(--radius-sm);
    font-size: var(--text-sm);
    font-weight: 500;
    color: var(--ink-soft);
}

.pagination a:hover {
    border-color: var(--accent);
    color: var(--accent);
    text-decoration: none;
}

.pagination .is-current {
    background-color: var(--accent);
    border-color: var(--accent);
    color: #fff;
    font-weight: 600;
}

.pagination .is-disabled {
    color: var(--rule-strong);
}

/* "Previous" and "Next" are words, not digits, so they need more room than the
   square number boxes. The ellipsis is a gap, not a control. */
.pagination__step {
    padding-inline: 0.875rem;
}

.pagination__gap {
    border-color: transparent !important;
    background: none !important;
    color: var(--muted);
}

/* 13. Forms
   ========================================================================== */

.form {
    display: grid;
    gap: var(--gap);
    max-width: var(--container-narrow);
}

.field {
    display: grid;
    gap: 0.375rem;
}

.field label {
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--ink-soft);
}

/* The same treatment for a field whose label is not attached to one input —
   a group of checkboxes, for instance. */
.field__label {
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--ink-soft);
}

/* How many times a tag's name appears in the body. */
.tagcount {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.25rem;
    padding: 0 0.25rem;
    border-radius: 999px;
    background-color: var(--accent-tint);
    color: var(--accent-ink);
    font-size: 0.6875rem;
    font-weight: 700;
}

.field input,
.field textarea,
.field select {
    width: 100%;
    padding: 0.625rem 0.75rem;
    border: 1px solid var(--rule-strong);
    border-radius: var(--radius);
    background-color: var(--paper);
    font: inherit;
    font-size: var(--text-base);
    color: var(--ink);
}

.field textarea {
    min-height: 10rem;
    resize: vertical;
}

/* Most textareas want room to write in; a summary or an SEO description does
   not. The blanket min-height above overrides the rows attribute, so a field
   meant to be three lines tall rendered as six. This hands the height back to
   the markup — the box is as tall as its rows say and scrolls beyond that, and
   it can still be dragged taller by hand. */
.field textarea.textarea--compact {
    min-height: auto;
}

.field input:focus,
.field textarea:focus,
.field select:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-tint);
}

.field__error {
    font-size: var(--text-sm);
    color: var(--danger);
}

.field__hint {
    font-size: var(--text-xs);
    color: var(--muted);
}

/* 14. Article body
   ========================================================================== */

/* The article column is centred rather than left-aligned: a long read in a wide
   viewport should sit in the middle of the page rather than hugging the edge. */
.article {
    max-width: 40rem;
    margin-inline: auto;
}

.article__header {
    margin-bottom: var(--gap-lg);
}

.article__title {
    font-size: var(--text-4xl);
    font-weight: 800;
    line-height: var(--leading-tight);
    margin-top: 0.5rem;
}

.article__summary {
    margin-top: 1rem;
    font-size: var(--text-lg);
    line-height: var(--leading-relaxed);
    color: var(--ink-soft);
}

/* The direct address on the contact page. Set apart from the copy above it,
   because it is an alternative to the form below rather than part of the prose.
   The address itself is written in the "[at]" form so harvesters cannot read
   it — see obfuscated_email() in app/helpers.php. */
.contactemail {
    margin-top: var(--gap);
    padding: 0.9rem 1.1rem;
    background-color: var(--paper-tint);
    border-left: 3px solid var(--accent);
    font-size: var(--text-sm);
    color: var(--ink-soft);
}

.contactemail strong {
    color: var(--ink);
}

.contactemail__hint {
    display: block;
    margin-top: 0.3rem;
    font-size: var(--text-xs);
    color: var(--muted);
}

/* The label a sponsored story carries on its own page. The homepage band says
   the same thing, but a reader arriving from a search result or a share never
   sees that band. */
.article__badge {
    display: inline-block;
    margin-bottom: 0.625rem;
    padding: 0.15rem 0.5rem;
    border-radius: 999px;
    background-color: var(--accent);
    color: #FFFFFF;
    font-size: var(--text-xs);
    font-weight: 700;
    letter-spacing: var(--tracking-wider);
    text-transform: uppercase;
}

.article__meta {
    margin-top: 1.25rem;
    padding-top: 0.875rem;
    border-top: 1px solid var(--rule);
    font-size: var(--text-sm);
    color: var(--muted);
    display: flex;
    flex-wrap: wrap;
    gap: 0.375rem 0.75rem;
}

.article__media {
    margin-bottom: var(--gap-lg);
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    overflow: hidden;
}

.article__media img {
    display: block;
    width: 100%;
    height: auto;
}

.article__body {
    font-size: var(--text-base);
    line-height: var(--leading-copy);
}

.article__body > * + * {
    margin-top: 1.25rem;
}

.article__body h2 {
    font-size: var(--text-xl);
    margin-top: 2.25rem;
}

.article__body h3 {
    font-size: var(--text-lg);
    margin-top: 1.875rem;
}

.article__body ul,
.article__body ol {
    padding-left: 1.375rem;
}

.article__body ul { list-style: disc; }
.article__body ol { list-style: decimal; }
.article__body li + li { margin-top: 0.5rem; }

.article__body blockquote {
    padding: 0.25rem 0 0.25rem 1.25rem;
    border-left: 3px solid var(--accent);
    font-family: var(--font-serif);
    font-style: italic;
    font-size: var(--text-lg);
    line-height: var(--leading-normal);
    color: var(--ink-soft);
}

/* The one place a serif appears outside a pull quote: the first letter of an
   article's opening paragraph, floated — the reference's editorial accent. It
   is set in our own ink rather than copying the reference's colour, and only
   applies to the first paragraph, not every one. */
.article__body > p:first-of-type::first-letter {
    float: left;
    margin: 0.04em 0.1em 0 0;
    font-family: var(--font-serif);
    font-size: 3.1em;
    font-weight: 600;
    line-height: 0.8;
    color: var(--ink);
}

.article__body img {
    border-radius: var(--radius);
}

.article__body a {
    text-decoration: underline;
    text-underline-offset: 3px;
}

.article__tags {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: var(--gap-lg);
    padding-top: var(--gap);
    border-top: 1px solid var(--rule);
}

/* FAQ accordion. Built on <details>, so it opens and closes without any
   JavaScript at all. */
.faq {
    margin-top: var(--gap-lg);
    border-top: 1px solid var(--rule);
}

.faq__item {
    border-bottom: 1px solid var(--rule);
}

.faq__question {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--gap);
    padding: 1rem 0;
    cursor: pointer;
    font-size: var(--text-lg);
    font-weight: 700;
    line-height: var(--leading-snug);
    list-style: none;
}

.faq__question::-webkit-details-marker {
    display: none;
}

.faq__question:hover {
    color: var(--accent);
}

/* A chevron drawn with two borders, so no icon font or image is needed. */
.faq__question::after {
    content: "";
    flex-shrink: 0;
    width: 0.5rem;
    height: 0.5rem;
    margin-top: 0.4rem;
    border-right: 2px solid var(--muted);
    border-bottom: 2px solid var(--muted);
    transform: rotate(45deg);
    transition: transform var(--speed) ease;
}

.faq__item[open] .faq__question::after {
    transform: rotate(-135deg);
}

.faq__answer {
    padding-bottom: 1.25rem;
    color: var(--ink-soft);
    line-height: var(--leading-relaxed);
}

.faq__answer > * + * {
    margin-top: 1rem;
}

/* The editorial team. */
.teamgrid {
    display: grid;
    gap: var(--gap-lg);
    grid-template-columns: 1fr;
}

.teamcard {
    display: flex;
    align-items: flex-start;
    gap: var(--gap);
}

.teamcard__avatar {
    display: block;
    flex-shrink: 0;
}

.teamcard__name {
    font-size: var(--text-lg);
    font-weight: 700;
    line-height: var(--leading-snug);
}

.teamcard__name a {
    color: var(--ink);
}

.teamcard:hover .teamcard__name a {
    color: var(--accent);
}

.teamcard__bio {
    margin-top: 0.5rem;
    font-size: var(--text-sm);
    line-height: var(--leading-relaxed);
    color: var(--ink-soft);
}

.tag {
    display: inline-block;
    padding: 0.25rem 0.625rem;
    border: 1px solid var(--rule-strong);
    border-radius: 999px;
    font-size: var(--text-xs);
    font-weight: 500;
    color: var(--ink-soft);
}

.tag:hover {
    border-color: var(--accent);
    color: var(--accent);
    text-decoration: none;
}

/* 15. Footer
   ========================================================================== */

.sitefooter {
    margin-top: var(--section-y);
    background-color: var(--footer);
    color: var(--footer-ink);
    /* A hairline of shadow along the top edge so the dark band sits above the
       page rather than being cut into it. */
    box-shadow: 0 -1px 3px 0 rgb(0 0 0 / 0.12);
}

.sitefooter__inner {
    width: 100%;
    max-width: var(--container);
    margin-inline: auto;
    padding: var(--gap-lg) var(--gap);
}

.sitefooter__links {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
    gap: 0.25rem 1.5rem;
    padding-bottom: var(--gap);
    border-bottom: 1px solid rgba(255, 255, 255, 0.14);
}

.sitefooter__links a {
    display: block;
    padding: 0.5rem 0;
    color: var(--footer-ink);
    font-size: var(--text-sm);
    font-weight: 600;
}

.sitefooter__links a:hover {
    color: #fff;
}

.sitefooter__legal {
    padding-top: var(--gap);
    font-size: var(--text-xs);
    color: rgb(255 255 255 / 0.62);
}

/* 16. Error pages and diagnostics
   ========================================================================== */

.errorpage {
    display: grid;
    place-items: center;
    min-height: 100vh;
    padding: var(--gap-lg) var(--gap);
    background-color: var(--paper-tint);
}

.errorpage__box {
    width: 100%;
    max-width: 34rem;
    padding: var(--gap-lg);
    background-color: var(--paper);
    border: 1px solid var(--rule);
    border-top: 3px solid var(--accent);
    border-radius: var(--radius);
}

.errorpage__box--wide {
    max-width: 52rem;
}

.errorpage__title {
    margin-top: 0.5rem;
    font-size: var(--text-xl);
}

.errorpage__actions {
    margin-top: var(--gap-lg);
}

.trace {
    margin-top: var(--gap);
    font-size: var(--text-sm);
}

.trace summary {
    cursor: pointer;
    font-weight: 600;
    color: var(--accent);
}

.trace pre {
    margin-top: 0.75rem;
    padding: 1rem;
    overflow-x: auto;
    background-color: var(--paper-tint);
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    font-size: var(--text-xs);
    line-height: 1.5;
}

.checklist {
    display: grid;
    gap: 0;
    margin-top: var(--gap-lg);
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    overflow: hidden;
}

.checklist__item {
    display: grid;
    grid-template-columns: 1.5rem 1fr auto;
    align-items: center;
    gap: 0.75rem;
    padding: 0.75rem 1rem;
    border-bottom: 1px solid var(--rule);
    font-size: var(--text-sm);
}

.checklist__item:last-child {
    border-bottom: 0;
}

.checklist__mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.5rem;
    height: 1.5rem;
    border-radius: 50%;
    font-size: 0.75rem;
    font-weight: 700;
    color: #fff;
}

.checklist__item--ok .checklist__mark {
    background-color: var(--ok);
}

.checklist__item--fail {
    background-color: var(--danger-tint);
}

.checklist__item--fail .checklist__mark {
    background-color: var(--danger);
}

.checklist__label {
    font-weight: 600;
    min-width: 0;
    overflow-wrap: anywhere;
}

.checklist__detail {
    font-size: var(--text-xs);
    color: var(--muted);
    text-align: right;
    overflow-wrap: anywhere;
}

/* 17. Responsive
   ========================================================================== */

@media (min-width: 40rem) {
    .cardgrid {
        grid-template-columns: repeat(2, 1fr);
    }

    .storylist__item {
        grid-template-columns: 9rem 1fr;
    }

    .authorhead {
        flex-direction: row;
        align-items: flex-start;
        text-align: left;
    }
}

@media (min-width: 60rem) {
    :root {
        --section-y: 4.5rem;
    }

    /* The admin nav is a horizontal strip in the top bar at every width; only
       the padding around the content changes here. */
    .adminmain {
        padding: var(--gap-lg) 2rem;
    }

    .admingrid--split {
        grid-template-columns: 2fr 1fr;
    }

    .homegrid {
        grid-template-columns: 2fr 1fr;
        align-items: start;
    }

    /* Follows the reader down a long list without scrolling away. */
    .homegrid__aside {
        position: sticky;
        top: var(--gap-lg);
    }

    .formgrid--split {
        display: grid;
        grid-template-columns: 2fr 1fr;
        align-items: start;
        gap: var(--gap-lg);
    }

    .container,
    .guides__inner,
    .masthead__inner,
    .mainnav__inner,
    .sitefooter__inner {
        padding-inline: 2rem;
    }

    .masthead__tagline {
        display: block;
    }

    /* The lead headline and the card titles step up through the breakpoints the
       same way the reference does: 24px → 30px for the lead, 18px → 20px for a
       card. */
    .hero__title {
        font-size: var(--text-3xl);
    }

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

    .cardgrid {
        grid-template-columns: repeat(3, 1fr);
    }

    .cardgrid--four {
        grid-template-columns: repeat(4, 1fr);
    }

    /* Lead story: image beside the text once there is room for it. */
    .hero {
        grid-template-columns: 1.35fr 1fr;
        align-items: start;
        gap: 2.5rem;
    }

    .hero__media {
        grid-column: 2;
        grid-row: 1;
    }

    .hero__text {
        grid-column: 1;
        grid-row: 1;
    }
}

@media (min-width: 80rem) {
    /* The lead reaches its full size only on a wide screen, matching the
       reference's xl step. */
    .hero__title {
        font-size: var(--text-4xl);
    }
}

/* 18. Admin
   ========================================================================== */

.admin {
    min-height: 100vh;
    background-color: var(--paper-tint);
}

.adminbar {
    background-color: var(--band-dark);
    color: #FFFFFF;
}

/* Two rows inside the bar: identity and account on the first, navigation on the
   second. The navigation is a horizontal strip rather than a side rail, so the
   content below gets the full width. */
.adminbar__row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem var(--gap);
    padding: 0.75rem var(--gap);
}

.adminbar__brand {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    color: #FFFFFF;
    font-weight: 700;
}

.adminbar__brand:hover {
    color: #FFFFFF;
    text-decoration: none;
}

.adminbar__mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.75rem;
    height: 1.75rem;
    border-radius: var(--radius-sm);
    background-color: var(--accent);
    font-size: var(--text-xs);
    font-weight: 700;
}

.adminbar__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--gap);
    font-size: var(--text-sm);
}

.adminbar__actions a {
    color: rgb(255 255 255 / 0.78);
}

.adminbar__actions a:hover {
    color: #FFFFFF;
}

.adminbar__user {
    color: rgb(255 255 255 / 0.55);
}

.adminbar__button {
    padding: 0.25rem 0.625rem;
    border: 1px solid rgb(255 255 255 / 0.25);
    border-radius: var(--radius-sm);
    background: transparent;
    color: #FFFFFF;
    font: inherit;
    font-size: var(--text-sm);
    cursor: pointer;
}

.adminbar__button:hover {
    background-color: rgb(255 255 255 / 0.1);
}

.adminnav {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem;
    padding: 0 var(--gap) 0.75rem;
}

.adminnav__link {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.375rem 0.75rem;
    border-radius: var(--radius-sm);
    color: rgb(255 255 255 / 0.72);
    font-size: var(--text-sm);
    font-weight: 600;
}

.adminnav__link:hover {
    background-color: rgb(255 255 255 / 0.1);
    color: #FFFFFF;
    text-decoration: none;
}

.adminnav__link.is-active {
    background-color: var(--accent);
    color: #FFFFFF;
}

.adminnav__badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.25rem;
    height: 1.25rem;
    padding: 0 0.3rem;
    border-radius: 999px;
    background-color: #FFFFFF;
    color: var(--accent);
    font-size: 0.6875rem;
}

.adminmain {
    width: 100%;
    max-width: 1400px;
    margin-inline: auto;
    padding: var(--gap-lg) var(--gap);
}

.paneltitle {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--gap);
    margin-bottom: var(--gap);
}

.paneltitle h1 {
    font-size: var(--text-2xl);
    font-weight: 800;
}

/* A heading row inside a panel rather than at the top of a page: the control
   beside the title lines up with it instead of with the first line of text, and
   the panel's own heading spacing is left to the panel. */
.paneltitle--panel {
    align-items: center;
    margin-bottom: var(--gap);
}

.paneltitle--panel .panel__title {
    margin-bottom: 0;
}

.panel {
    padding: var(--gap-lg);
    background-color: var(--paper);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
}

.panel + .panel {
    margin-top: var(--gap-lg);
}

.panel__title {
    margin-bottom: var(--gap);
    font-size: var(--text-lg);
    font-weight: 700;
}

.stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
    gap: var(--gap);
}

.stat {
    padding: var(--gap);
    background-color: var(--paper);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
}

.stat__value {
    font-size: var(--text-3xl);
    font-weight: 800;
    line-height: 1;
}

.stat__label {
    margin-top: 0.375rem;
    font-size: var(--text-xs);
    font-weight: 700;
    letter-spacing: var(--tracking-wider);
    text-transform: uppercase;
    color: var(--muted);
}

.table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--text-sm);
}

.table th,
.table td {
    padding: 0.625rem 0.5rem;
    border-bottom: 1px solid var(--rule);
    text-align: left;
    vertical-align: top;
}

.table th {
    border-bottom-color: var(--rule-strong);
    font-size: var(--text-xs);
    font-weight: 700;
    letter-spacing: var(--tracking-wider);
    text-transform: uppercase;
    color: var(--muted);
}

.table tbody tr:hover {
    background-color: var(--paper-tint);
}

/* A table too wide for a phone scrolls rather than being cut off. The last
   column of the backups table holds the controls, and a clipped column is an
   unreachable one — the rest of the admin clips at this width, which is a
   wider question than this page. */
.tablewrap {
    overflow-x: auto;
}

/* A table whose second column is a short number: at full width the number ends
   up stranded in the middle of the panel with nothing next to it. */
.table--slim {
    width: auto;
    min-width: 18rem;
}

.status {
    display: inline-block;
    padding: 0.1rem 0.45rem;
    border-radius: 999px;
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: var(--tracking-wider);
    text-transform: uppercase;
}

.status--published {
    background-color: var(--ok-tint);
    color: var(--ok);
}

.status--draft {
    background-color: var(--paper-tint);
    color: var(--muted);
}

.status--scheduled {
    background-color: var(--accent-tint);
    color: var(--accent-ink);
}

.admingrid {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--gap-lg);
}

.plainlist {
    display: grid;
    gap: 0.75rem;
    font-size: var(--text-sm);
}

.actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}

/* A row's read-only actions: downloads and a preflight, which are links because
   that is what they are. Keeping them as links rather than buttons leaves the
   row with two controls that actually change something, and those stand out
   because they are the only ones wearing a border. */
.rowlinks {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    font-size: var(--text-sm);
    white-space: nowrap;
}

.button--small {
    padding: 0.3rem 0.6rem;
    font-size: var(--text-xs);
}

.button--danger {
    border-color: var(--rule-strong);
    background-color: transparent;
    color: var(--danger);
}

.button--danger:hover {
    border-color: var(--danger);
    background-color: var(--danger-tint);
    color: var(--danger);
}

/* Checkboxes are wide by default in .field, which is wrong for a list of tags. */
.field input[type="checkbox"] {
    width: auto;
}

/* A file field is the one control in a form that is drawn by the browser, so it
   cannot be styled like the rest. This at least makes the button inside it wear
   the same shape and weight as every other button on the page. */
.field input[type="file"] {
    padding: 0.5rem 0.75rem;
    cursor: pointer;
}

.field input[type="file"]::file-selector-button {
    margin-right: 0.75rem;
    padding: 0.3rem 0.6rem;
    border: 1px solid var(--accent);
    border-radius: var(--radius);
    background-color: transparent;
    color: var(--accent);
    font: inherit;
    font-size: var(--text-sm);
    font-weight: 600;
    cursor: pointer;
}

.field input[type="file"]::file-selector-button:hover {
    background-color: var(--accent-tint);
}

.field__checkbox {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: var(--text-sm);
}

.checkboxes {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
    gap: 0.375rem;
}

.checkboxes label {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: var(--text-sm);
}

/* An inline record: the summary line is the collapsed state, the form inside it
   is the expanded one. Used for categories, tags and authors, which are all
   short enough to edit in place. */
.taxrow {
    border-bottom: 1px solid var(--rule);
}

.taxrow__summary {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.25rem 1rem;
    padding: 0.625rem 0.25rem;
    cursor: pointer;
    list-style: none;
}

.taxrow__summary::-webkit-details-marker {
    display: none;
}

.taxrow__summary:hover {
    background-color: var(--paper-tint);
}

.taxrow__name {
    font-weight: 600;
}

.taxrow__meta {
    font-size: var(--text-xs);
    color: var(--muted);
}

.taxrow[open] {
    background-color: var(--paper-tint);
}

.taxrow form {
    padding-inline: 0.25rem;
}

.definitionlist {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 0.25rem 1rem;
    margin-bottom: var(--gap-lg);
    font-size: var(--text-sm);
}

.definitionlist dt {
    font-weight: 600;
    color: var(--muted);
}

.messagebody {
    padding-top: var(--gap);
    border-top: 1px solid var(--rule);
    line-height: var(--leading-relaxed);
}

/* The body editor. Quill brings its own chrome; these rules align it with the
   form fields beside it and give the writing surface a readable measure. */
.editor__fallback {
    min-height: 20rem;
}

/* Once the editor is up, the textarea is only there to carry the value. */
.editor.is-enhanced .editor__fallback {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

.editor .ql-toolbar.ql-snow,
.editor .ql-container.ql-snow {
    border-color: var(--rule-strong);
}

.editor .ql-toolbar.ql-snow {
    border-radius: var(--radius) var(--radius) 0 0;
    background-color: var(--paper-tint);
}

.editor .ql-container.ql-snow {
    border-radius: 0 0 var(--radius) var(--radius);
    font-family: var(--font-body);
}

.editor .ql-editor {
    min-height: 20rem;
    padding: 1rem;
    font-size: var(--text-base);
    line-height: var(--leading-relaxed);
}

.editor .ql-editor h2 {
    font-size: var(--text-2xl);
}

.editor .ql-editor h3 {
    font-size: var(--text-xl);
}

.editor .ql-editor blockquote {
    border-left: 3px solid var(--accent);
    padding-left: 1rem;
    color: var(--ink-soft);
}

.editor .ql-editor img {
    max-width: 100%;
    height: auto;
}

/* Quill's own snow theme centres the text inside its toolbar buttons; the font
   stack it ships is not ours. */
.editor .ql-snow .ql-picker,
.editor .ql-snow .ql-stroke {
    stroke: var(--ink-soft);
}

.editor .ql-snow .ql-picker-label {
    color: var(--ink-soft);
}

.colourfield {
    display: flex;
    align-items: center;
    gap: 0.625rem;
}

/* .field input is full width, which is wrong for a swatch. */
.colourfield input[type="color"] {
    flex-shrink: 0;
    width: 3rem;
    height: 2.5rem;
    padding: 0.125rem;
    border: 1px solid var(--rule-strong);
    border-radius: var(--radius);
    background-color: var(--paper);
    cursor: pointer;
}

/* The lead stories, when more than one is marked.
   Slides are stacked in one grid cell rather than laid out in a row: the track
   is then always as tall as its tallest slide, so rotating never makes the page
   jump. The first slide is marked active on the server, so with JavaScript off
   a reader still gets a complete lead story — just no rotation. */
.leads__track {
    display: grid;
}

.leads__slide {
    grid-area: 1 / 1;
    opacity: 0;
    visibility: hidden;
    transform: translateX(-3%);
    transition: opacity 300ms ease, transform 300ms ease, visibility 0s linear 300ms;
}

.leads__slide.is-active {
    opacity: 1;
    visibility: visible;
    transform: none;
    transition-delay: 0s;
}

/* The controls provide the rule underneath, so the slide does not add a second
   one directly above it. */
.leads__slide .hero {
    border-bottom: 0;
    padding-bottom: 0;
}

.leads__controls {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem var(--gap);
    margin-top: var(--gap);
    padding-top: var(--gap);
    border-top: 1px solid var(--band-dark-rule);
}

.leads__dots {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.leads__dot {
    width: 0.625rem;
    height: 0.625rem;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background-color: rgb(255 255 255 / 0.3);
    cursor: pointer;
    transition: background-color var(--speed) ease;
}

.leads__dot:hover {
    background-color: rgb(255 255 255 / 0.6);
}

.leads__dot.is-active {
    background-color: var(--accent);
}

/* The destructive control at the foot of the settings page. Set apart with a
   border and a tint rather than a shout — unmistakably a different kind of
   thing from the settings above it, without being alarming to look at. */
.panel--danger {
    margin-top: var(--gap-lg);
    border: 1px solid var(--danger);
    border-top-width: 3px;
}

.panel--danger .panel__title {
    color: var(--danger);
}

.panel--danger .button--danger {
    border-color: var(--danger);
    background-color: var(--danger);
    color: #FFFFFF;
}

.panel--danger .button--danger:hover {
    border-color: #8F1D14;
    background-color: #8F1D14;
    color: #FFFFFF;
}

.panel--danger .button--danger:disabled {
    border-color: var(--rule-strong);
    background-color: var(--paper-tint);
    color: var(--muted);
    cursor: not-allowed;
}

.signin {
    display: grid;
    place-items: center;
    min-height: 100vh;
    padding: var(--gap-lg) var(--gap);
    background-color: var(--paper-tint);
}

.signin__box {
    width: 100%;
    max-width: 26rem;
    padding: var(--gap-lg);
    background-color: var(--paper);
    border-top: 3px solid var(--accent);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-md);
}

.signin__title {
    margin-block: 0.375rem var(--gap);
    font-size: var(--text-2xl);
    font-weight: 800;
}

@media (prefers-reduced-motion: reduce) {    html {
        scroll-behavior: auto;
    }

    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }
}
