/*
 * Article listings and the article page.
 *
 * The front page opens with a hero block - one lead story beside a stack of
 * secondary stories - and continues into a grid of cards. Tag and search
 * listings reuse the same card and skip the hero.
 *
 * Colours, fonts and metrics come from css/gazapost.css; nothing here declares
 * a colour of its own.
 */

/* ---- Page shells ------------------------------------------------------ */

.news-index {
    padding: 2rem 0 4rem;
}

/*
 * The article page is a sheet of white laid on the newsprint background, held
 * to a comfortable reading measure rather than the full container width.
 */
.article-detail {
    max-width: calc(var(--gp-measure) + 2 * var(--gp-gutter));
    margin: 2.5rem auto 4rem;
    padding: 2.5rem var(--gp-gutter) 3.5rem;
    background-color: var(--gp-card);
    border: 1px solid var(--gp-rule);
    box-sizing: border-box;
}

/* ---- Section headings ------------------------------------------------- */

/*
 * Used above a tag or search listing, and to divide the hero from the grid that
 * follows it. The rule runs the full width with the label sitting on top of it.
 */
.section-heading {
    display: flex;
    align-items: baseline;
    gap: 1rem;
    margin: 0 0 1.5rem;
    padding-bottom: 0.6rem;
    border-bottom: 2px solid var(--gp-ink);
    font-family: var(--font-sans);
    font-size: 0.8rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.1em;
}

.section-heading-query {
    font-weight: 400;
    text-transform: none;
    letter-spacing: 0;
    color: var(--gp-muted);
}

.hero + .section-heading {
    margin-top: 3rem;
}

/* ---- Card ------------------------------------------------------------- */

/*
 * One card serves the hero lead, the two secondary stories and the grid below;
 * the blocks that use it only change its proportions, never its anatomy.
 *
 * Each is a query container so its headline can be sized against the card it
 * sits in rather than against the viewport - the same card is around 818px wide
 * as the hero lead, 430px beside it and 300px in the grid, and `vw` cannot tell
 * those three apart.
 */
.card {
    display: flex;
    flex-direction: column;
    background-color: var(--gp-card);
    border: 1px solid var(--gp-rule);
    container-type: inline-size;
}

.card-image {
    display: block;
    /* Anchors the image's aspect ratio so the grid does not reflow as each
       rendition arrives. */
    aspect-ratio: 16 / 9;
    overflow: hidden;
    background-color: var(--gp-rule);
}

.card-image img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.4s ease;
}

.card-image:hover img {
    transform: scale(1.03);
}

.card-body {
    display: flex;
    flex-direction: column;
    /* Pushes the byline to the bottom edge so cards in a row align on it. */
    flex: 1;
    padding: 1.25rem 1.25rem 1.5rem;
}

.card-kickers {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-bottom: 0.5rem;
}

/*
 * Two lines is the budget every headline is held to. Without it a long title is
 * free to set the height of the block it sits in - in the hero that height is
 * shared with the column opposite, so a third line there is paid for by both
 * columns and comes off the images. The `clamp()` floor is the size the cards
 * have always used, so only cards wider than about 430px scale up from it.
 */
.card-title {
    font-family: var(--font-serif);
    font-size: clamp(1.35rem, 5cqi, 1.6rem);
    font-weight: 600;
    line-height: 1.2;
    margin: 0 0 0.5rem;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    overflow: hidden;
    text-wrap: balance;
}

.card-title a {
    color: var(--gp-ink);
    text-decoration: none;
}

.card-title a:hover {
    text-decoration: underline;
    text-underline-offset: 0.12em;
}

.card-intro {
    margin: 0 0 1rem;
    font-size: 0.95rem;
    line-height: 1.5;
    color: var(--gp-muted);
}

.card-meta {
    margin-top: auto;
    font-size: 0.78rem;
    color: var(--gp-muted);
}

.card-meta .byline {
    font-weight: 600;
    color: var(--gp-ink);
}

/* ---- Hero ------------------------------------------------------------- */

/*
 * The lead beside the stack of secondary stories, both columns exactly as tall
 * as each other. Nothing here states a height: the grid row is sized to
 * whichever column is naturally taller, both columns stretch to meet it, and
 * inside each card the image absorbs whatever slack that leaves. So the block
 * re-balances itself when the type, the padding or the container width change,
 * with no measurement anywhere to keep in step with them.
 *
 * `minmax(0, …)` on both tracks stops a long unbroken headline from pushing a
 * column past its share of the row, which the default `auto` minimum allows.
 */
.hero {
    display: grid;
    grid-template-columns: minmax(0, 1.9fr) minmax(0, 1fr);
    gap: 1.5rem;
}

/* With nothing to sit beside it, the lead takes the whole row. */
.hero.is-lead-only {
    grid-template-columns: minmax(0, 1fr);
}

/*
 * Two rows always, whether or not there are two stories to fill them: a lone
 * secondary card then sits in the top row at exactly the height it would have
 * had beside a sibling, and the hero keeps the height it has on a full day.
 *
 * Plain `1fr` rather than `minmax(0, 1fr)` is deliberate - the `auto` minimum
 * that `1fr` carries is what lets the cards' own heights size the row, and so
 * the hero, in the first place. A `0` minimum would collapse the stack.
 */
.hero-secondary {
    display: grid;
    grid-template-rows: repeat(2, 1fr);
    gap: 1.5rem;
}

/*
 * `.hero-lead` stretches to the row as a grid item, but a plain block child
 * would not inherit that height; making it a grid container in turn hands the
 * full height down to the card.
 */
.hero-lead {
    display: grid;
}

/*
 * Where the slack between the two columns goes. The body is pinned to its
 * content height - overriding the `flex: 1` the grid cards below want - and the
 * image grows into what is left, cropping through `object-fit`. `aspect-ratio`
 * still gives each image its preferred size, so it decides the shape the block
 * settles into; it just no longer fixes it.
 */
.hero .card-image {
    flex: 1 1 auto;
    min-height: 0;
}

.hero .card-body {
    flex: 0 0 auto;
}

.hero-lead .card {
    border: none;
    background-color: transparent;
}

.hero-lead .card-image {
    aspect-ratio: 3 / 2;
}

/*
 * The lead's text sits on a white card pulled up over the foot of its image,
 * inset from the left edge - the overlap is what separates the lead from the
 * cards beside it at a glance.
 */
.hero-lead .card-body {
    position: relative;
    margin: -3.5rem 2.5rem 0 3rem;
    padding: 1.75rem 2rem 1.5rem;
    background-color: var(--gp-card);
}

/* The lead is wide enough to carry a third line without unbalancing the row. */
.hero-lead .card-title {
    font-size: clamp(1.75rem, 5cqi, 2.5rem);
    font-weight: 700;
    -webkit-line-clamp: 3;
    line-clamp: 3;
}

.hero-lead .card-intro {
    font-size: 1.05rem;
}

/*
 * The hero row is as tall as its tallest column, so everything the secondary
 * cards carry is paid for twice - once per stacked card - while the lead pays
 * for it once. Their intros are what tips that balance: with them the stack
 * wants roughly 950px against the lead's 700 and the lead's image has to
 * stretch to nearly square to keep up. Without them the two columns land within
 * about 70px of each other and the lead settles at a natural 4:3.
 *
 * Only in the two-column hero - once it collapses below, the secondary cards
 * are wide enough to carry an intro again.
 */
@media (width > 900px) {
    .hero-secondary .card-intro {
        display: none;
    }
}

/* ---- Grid of remaining articles --------------------------------------- */

.article-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr));
    gap: 1.5rem;
}

.no-articles {
    margin: 0;
    padding: 3rem 0;
    color: var(--gp-muted);
    font-style: italic;
}

/* ---- Pagination -------------------------------------------------------- */

.pagination {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1.5rem;
    margin-top: 3rem;
}

.pagination-link {
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--gp-accent-dark);
    text-decoration: none;
}

.pagination-link:hover {
    text-decoration: underline;
}

.pagination-link.is-disabled {
    color: #b3b0a8;
    pointer-events: none;
}

.pagination-status {
    font-size: 0.85rem;
    color: var(--gp-muted);
}

/* ---- Article page ------------------------------------------------------ */

.article-kickers {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-bottom: 0.75rem;
}

.article-title {
    font-family: var(--font-serif);
    font-size: clamp(2rem, 5vw, 2.9rem);
    font-weight: 700;
    line-height: 1.15;
    margin: 0 0 0.85rem;
}

.article-intro {
    font-size: 1.2rem;
    line-height: 1.5;
    color: var(--gp-muted);
    margin: 0 0 1.25rem;
}

.article-meta {
    padding-bottom: 1.5rem;
    border-bottom: 1px solid var(--gp-rule);
    font-size: 0.85rem;
    color: var(--gp-muted);
}

.article-meta .byline {
    font-weight: 600;
    color: var(--gp-ink);
}

/*
 * The hero image is allowed to run out to the sheet's edges, past the reading
 * measure the surrounding text is held to.
 */
.article-hero {
    margin: 1.75rem calc(-1 * var(--gp-gutter)) 0.6rem;
}

.article-hero img {
    display: block;
    width: 100%;
    height: auto;
}

.article-body {
    margin-top: 1.75rem;
    font-size: 1.05rem;
    line-height: 1.7;
}

.article-body h2,
.article-body h3 {
    font-family: var(--font-serif);
    line-height: 1.25;
}

.article-body h2 {
    font-size: 1.5rem;
    font-weight: 700;
    margin: 2rem 0 0.75rem;
}

.article-body h3 {
    font-size: 1.25rem;
    font-weight: 600;
    margin: 1.75rem 0 0.5rem;
}

.article-body p {
    margin: 0 0 1.15rem;
}

.article-body a {
    color: var(--gp-accent-dark);
}

.article-body img {
    max-width: 100%;
    height: auto;
}

.article-body blockquote {
    margin: 1.5rem 0;
    padding-left: 1.25rem;
    border-left: 3px solid var(--gp-accent);
    font-family: var(--font-serif);
    font-size: 1.15rem;
    color: var(--gp-ink);
}

/* ---- Narrower screens -------------------------------------------------- */

/*
 * The hero's two columns stop working long before the phone breakpoint - the
 * secondary cards get too narrow to hold a headline - so it collapses first.
 */
@media (max-width: 900px) {
    .hero,
    .hero.is-lead-only {
        grid-template-columns: minmax(0, 1fr);
    }

    .hero-secondary {
        grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
        grid-template-rows: none;
    }
}

@media (max-width: 600px) {
    /* Below this width there is no room either side for the overlap, so the
       lead's text block returns to sitting squarely under its image. */
    .hero-lead .card-body {
        margin: 0;
        padding: 1.25rem 1.25rem 1.5rem;
        border: 1px solid var(--gp-rule);
        border-top: none;
    }

    .hero-lead .card-image {
        aspect-ratio: 16 / 9;
    }

    .article-detail {
        margin: 1.25rem auto 2.5rem;
        padding: 1.75rem var(--gp-gutter) 2.5rem;
    }
}
