/**
 * ELEVEN28 Journal
 *
 * Structure & mechanics adapted from the Web Designer Depot reference
 * (docs/JOURNAL_REFERENCE_MAPPING.md); visual identity is ELEVEN28
 * (docs/JOURNAL_DESIGN_TOKEN_MAPPING.md). Flat, Warm Paper, Ink Hairline,
 * circular-arrow CTA, single 1.04 image-hover — no shadows, no accent chips.
 */

:root {
    --jr-card-gap: var(--grid-gap, 20px);
}

/* Page gutter — matches the site convention (per-section 2em / 0.75em, no
   global container). One wrapper carries it for every Journal section. */
.jr-page {
    padding: 0 2em 6em;
    max-width: 100em;
    margin: 0 auto;
}
@media screen and (max-width: 767px) { .jr-page { padding: 0 0.75em 4em; } }

/* ---- Hero (ref: .hero-section) ------------------------------------------ */
.jr-hero {
    padding: 9em 0 3em;
    max-width: 60em;
}
.jr-hero .title-xl { margin-top: 0.5em; }
.jr-hero__standfirst {
    margin-top: 1.5em;
    max-width: 34em;
    opacity: 0.75;
}
@media screen and (max-width: 1024px) { .jr-hero { padding: 7em 0 2em; } }

/* ---- Section headers ---------------------------------------------------- */
.jr-section-head {
    padding-bottom: 0.9em;
    margin-bottom: 2.5em;
    border-bottom: 1px solid var(--color-ink-hairline, #03090D60);
}

.jr-featured, .jr-latest, .jr-popular, .jr-readnext { margin-bottom: 5.5em; }
@media screen and (max-width: 767px) { .jr-featured, .jr-latest, .jr-popular, .jr-readnext { margin-bottom: 3.5em; } }

/* ---- Featured editorial row (ref: article-box-large + small-feature) ---- */
.jr-row {
    display: grid;
    grid-template-columns: 1.4fr 1fr;
    gap: calc(var(--jr-card-gap) * 2);
    align-items: start;
}
.jr-row__aside {
    display: flex;
    flex-direction: column;
    gap: calc(var(--jr-card-gap) * 1.6);
}
/* Desktop: lead image fills the column height to match the supporting stack
   (ref: article-box-large image "fills height"), so the row reads balanced. */
@media screen and (min-width: 1025px) {
    .jr-row { align-items: stretch; }
    .jr-card--large { height: 100%; }
    .jr-card--large .jr-card__media { aspect-ratio: auto; flex: 1 1 auto; min-height: 30em; }
}
@media screen and (max-width: 1024px) {
    .jr-row { grid-template-columns: 1fr; gap: 3em; }
    .jr-row__aside { display: grid; grid-template-columns: 1fr 1fr; gap: 2em; }
}
@media screen and (max-width: 767px) {
    .jr-row__aside { grid-template-columns: 1fr; gap: 2.5em; }
}

/* ---- Standard grid (ref: .section-article-featured grid) ---------------- */
.jr-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: calc(var(--jr-card-gap) * 2) var(--jr-card-gap);
}
@media screen and (max-width: 1024px) { .jr-grid { grid-template-columns: repeat(2, 1fr); } }
@media screen and (max-width: 767px)  { .jr-grid { grid-template-columns: 1fr; gap: 3em; } }

/* ---- Article card (ref: .article-box / .js-article-link) ---------------- */
/* Flattened: no gradient border box, no dark surface. Photography full-bleed
   inside its own container, text directly on Warm Paper below. */
.jr-card {
    display: flex;
    flex-direction: column;
    position: relative;
    cursor: pointer;
}
.jr-card__media {
    display: block;
    overflow: hidden;               /* ref .image-feature overflow:hidden */
    border-radius: var(--rounded-md, 0.375em);
    aspect-ratio: 16 / 11;
    background: var(--color-2, #03090D);
}
.jr-card--large .jr-card__media { aspect-ratio: 16 / 10; }
/* The push-in that answers the title underline. Both run on the same curve so
   the card reads as one gesture rather than two effects that happen to fire
   together; the image is given a longer duration because a picture moving at
   the speed of a 2.5px rule looks twitchy, and a slow zoom under a quick
   underline is what makes the pair feel deliberate.

   1.04 was too polite to register at card size. 1.07 is felt without the crop
   visibly eating the composition — .jr-card__media already clips it. */
.jr-card__img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transform-origin: center;
    transition: transform 0.7s cubic-bezier(0.16, 1, 0.3, 1);
}
.jr-card:hover .jr-card__img,
.jr-card:focus-within .jr-card__img { transform: scale(1.07); }  /* ref image zoom */

.jr-card__body {
    display: flex;
    flex-direction: column;
    gap: 1em;
    padding-top: 1.5em;
    flex: 1 1 auto;              /* fill card height so CTAs align across the row */
}
.jr-card--large .jr-card__body { gap: 1.25em; }

.jr-card__title { margin: 0; }
/* Journal titles carry the global .title-xs / .title-m classes, which set
   line-height: .9 (theme.css). That tie is won by the type class, so bumping
   .jr-card__title alone did nothing — line one's hover underline landed on the
   caps of line two. Beat the type class with a compound selector and give the
   underline clear air below it. */
.jr-card__title.title-xs, .jr-card__title.title-m, .jr-card__title.title-s,
.jr-popular__title.title-xs, .jr-popular__title.title-m, .jr-popular__title.title-s {
    line-height: 1.3;
}
.jr-card__title a { color: inherit; }
/* One underline per line of the title, fading in on hover. background-image is
   forced to none to neutralise the OLD gradient-underline rule (commit 000ccc1)
   that some browsers still have cached: it drew a SECOND, card-hover underline
   via background-size, stacking two lines under each line of text. line-height
   1.3 (above) keeps line one's underline clear of line two. */
.jr-card__link {
    color: inherit;
    background-image: none;
    text-decoration: underline;
    text-decoration-color: transparent;
    text-decoration-thickness: 2.5px;
    text-underline-offset: 0.08em;
    transition: text-decoration-color var(--transition, 0.3s cubic-bezier(0.16, 1, 0.3, 1));
}
/* Underline reveals when ANYWHERE on the listing is hovered/focused (the whole
   card is one click target), not only the title text. */
.jr-card:hover .jr-card__link,
.jr-card:focus-within .jr-card__link,
.jr-popular__item:hover .jr-card__link,
.jr-popular__item:focus-within .jr-card__link,
.jr-card__link:hover,
.jr-card__link:focus-visible {
    text-decoration-color: currentColor;
}

.jr-card__excerpt { margin: 0; opacity: 0.75; max-width: 34em; }

.jr-card__cta {
    margin-top: auto;           /* pin READ to the bottom, regardless of excerpt length */
    padding-top: 0.25em;
    color: var(--color-2, #03090D);
}
.jr-card__cta svg { transition: transform var(--transition, 0.3s cubic-bezier(0.16, 1, 0.3, 1)); }
.jr-card:hover .jr-card__cta svg { transform: translateX(0.35em); }

/* The Featured row's lead card is stretched to the height of the three-card
   aside beside it, and `margin-top: auto` above pinned READ to the bottom of
   that stretched box: the button ended up 383px below the excerpt it belongs
   to, orphaned in the middle of the page while the text sat far above it.
   Bottom-pinning is right for a row of equal cards — it is what makes their
   CTAs agree — but here there is no card to agree with, only empty column.
   Keep the lead card's title, excerpt and READ together as one block and let
   the spare height fall as trailing air beneath them. */
.jr-row .jr-card--large .jr-card__cta { margin-top: 0; }

/* ---- Row-level alignment across a grid of cards ------------------------- */
/* Titles wrap to different line counts, so each card sizing its own stack meant
   a two-line title started its excerpt where a three-line title was still
   running: three cards side by side, three different excerpt baselines. The
   `margin-top: auto` above only pinned READ to the bottom of ITS OWN card, so
   the CTAs agreed while everything above them did not.

   Subgrid hands each card the row tracks of .jr-grid itself, so the title,
   excerpt and READ of every card in a row occupy the SAME tracks and line up
   however the titles wrap — a two-line title simply leaves air below it.

   Row tracks: 1 media · 2 meta · 3 title · 4 excerpt · 5 READ.

   Without subgrid support the cards keep the flex behaviour above (bottom-pinned
   READ, everything else flowing), which is the previous, perfectly usable
   rendering — nothing here is load-bearing for legibility. */
@supports (grid-template-rows: subgrid) {
    .jr-grid > .jr-card {
        display: grid;
        grid-template-rows: subgrid;
        grid-row: span 5;
        /* A subgrid inherits the PARENT's gutters, and .jr-grid's row gap is the
           space between rows of cards — vast inside a card. State the card's own
           rhythm, which is what .jr-card__body's flex gap used to provide. */
        row-gap: 1em;
    }
    .jr-grid > .jr-card > .jr-card__media {
        /* Was .jr-card__body's padding-top. Padding on a subgrid offsets its
           tracks from the parent's and breaks the alignment, so the air between
           photograph and text is carried here instead. */
        margin-bottom: 0.5em;
    }
    .jr-grid > .jr-card > .jr-card__body {
        display: grid;
        grid-template-rows: subgrid;
        grid-row: span 4;
        padding-top: 0;
    }
    /* Placed explicitly so a card WITHOUT an excerpt still puts READ in the last
       track rather than sliding it up into the empty one and breaking the row. */
    .jr-grid > .jr-card .jr-card__cta {
        grid-row: -2 / -1;
        margin-top: 0;
    }
}

/* ---- Metadata row (ref: author/date/reading-time) ----------------------- */
.jr-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.6em;
    color: var(--color-2, #03090D);
}
.jr-meta__format { opacity: 1; }
.jr-meta__dot { opacity: 0.4; }
/* Byline sits with the date/reading-time run but reads slightly stronger — it is
   attribution, not chrome. */
.jr-meta__author {
    font-family: var(--font-1);
    font-size: 0.8125em;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    opacity: 0.75;
}
.jr-meta__date, .jr-meta__read {
    font-family: var(--font-1);
    font-size: 0.8125em;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    opacity: 0.55;
}

/* ---- Popular / Most Read (ref: .popular-post numbered list) ------------- */
.jr-popular__list {
    list-style: none;
    margin: 0; padding: 0;
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 0;
}
@media screen and (max-width: 767px) { .jr-popular__list { grid-template-columns: 1fr; } }
.jr-popular__item {
    display: grid;
    grid-template-columns: auto 88px 1fr;
    align-items: center;
    gap: 1.25em;
    padding: 1.5em 1em 1.5em 0;
    border-bottom: 1px solid var(--color-ink-hairline, #03090D60);
    position: relative;
    cursor: pointer;
}
.jr-popular__num { opacity: 0.3; line-height: 1; min-width: 1.6em; }
.jr-popular__media {
    display: block; overflow: hidden;
    width: 88px; height: 88px;
    border-radius: var(--rounded-md, 0.375em);
    background: var(--color-2, #03090D);
}
/* Same gesture as .jr-card__img, held a little tighter: these thumbnails are
   small, so the identical 1.07 would read as a lurch. */
.jr-popular__img { width: 100%; height: 100%; object-fit: cover; transform-origin: center; transition: transform 0.7s cubic-bezier(0.16, 1, 0.3, 1); }
.jr-popular__item:hover .jr-popular__img,
.jr-popular__item:focus-within .jr-popular__img { transform: scale(1.05); }
.jr-popular__body { display: flex; flex-direction: column; gap: 0.5em; }
.jr-popular__title { margin: 0; line-height: 1.2; }
.jr-popular__title a { color: inherit; }

/* ---- Article reader (ref: .hero-article + .single-content) -------------- */
.jr-article { display: block; }
.jr-article__hero {
    display: grid;
    grid-template-columns: 1fr 1.15fr;
    gap: calc(var(--jr-card-gap) * 2.5);
    align-items: center;
    padding: 8em 0 3.5em;
    border-bottom: 1px solid var(--color-ink-hairline, #03090D60);
}
@media screen and (max-width: 1024px) {
    .jr-article__hero { grid-template-columns: 1fr; gap: 2.5em; padding: 7em 0 2.5em; }
}
.jr-crumb { display: flex; gap: 0.6em; align-items: center; margin-bottom: 1.5em; }
.jr-crumb a { color: inherit; }
.jr-crumb span[aria-hidden] { opacity: 0.4; }
.jr-article__standfirst { margin: 1.25em 0 1.75em; max-width: 30em; opacity: 0.8; }
.jr-article__hero-figure { margin: 0; }
.jr-article__hero-img {
    width: 100%; height: auto; display: block;
    border-radius: var(--rounded-lg, 0.5em);
    aspect-ratio: 16 / 10; object-fit: cover;
}

.jr-article__body {
    max-width: 34em;
    margin: 3.5em auto 4.5em;
    --jr-link: #AE4F39;
    --jr-link-hover: #8E3B28;
}
.jr-article__body > p { margin-bottom: 1.5em; }

/* Inline links in prose.
   theme.css resets every anchor to `color: inherit; text-decoration: none`,
   which suits the chrome (nav, cards, buttons) but left body links completely
   indistinguishable from the text around them — 24 of them across the live
   articles read as ordinary words. A reader cannot follow what they cannot see.

   Colour AND underline, both at rest — the two signals a reader already knows.
   The brand accent --color-3 (#C2644F) is only 3.6:1 on the cream, which fails
   AA for prose, so the link ink is that terracotta deepened to 4.7:1. It is
   recognisably the same colour on the page, just dark enough to read as body
   text. Hover deepens it again and doubles the rule.

   Offset is constant and text-decoration paints outside the box, so a link
   never reflows the line it sits in. (--jr-link / --jr-link-hover are declared
   on .jr-article__body above.) */
.jr-article__body a {
    color: var(--jr-link);
    text-decoration: underline;
    text-decoration-color: currentColor;
    text-decoration-thickness: 1px;
    text-underline-offset: 0.18em;
    transition: color var(--transition, 0.3s cubic-bezier(0.16, 1, 0.3, 1)),
                text-decoration-thickness var(--transition, 0.3s cubic-bezier(0.16, 1, 0.3, 1));
}

.jr-article__body a:hover {
    color: var(--jr-link-hover);
    text-decoration-thickness: 2px;
}

.jr-article__body a:focus-visible {
    outline: 2px solid var(--color-3);
    outline-offset: 3px;
    border-radius: 2px;
}
.jr-article__h { margin: 2em 0 0.75em; }
.jr-article__h3 { font-family: var(--font-1); text-transform: uppercase; letter-spacing: 0.025em; font-size: 1.125em; }

/* A blank line the writer typed in the editor. Presentational only — it carries
   the same height as the gap under a paragraph so what they saw is what runs. */
.jr-article__spacer { height: 1.5em; }

/* A section break, and now the only full-width rule in the body — so when one
   appears it means exactly one thing. The old hairline sat at 37% ink, which on
   cream read as a smudge or as nothing; at 55% it registers as a deliberate
   mark without becoming heavy. */
.jr-article__divider {
    border: 0;
    border-top: 1px solid rgba(3, 9, 13, 0.55);
    margin: 3.25em 0;
}

/* ---- Quotes -------------------------------------------------------------
   The one place the article changes voice, so it is set to be seen: display
   type at a size no paragraph reaches, held out from the measure by a rule in
   the margin. The rule runs the full height of the quote, so a long one reads
   as a single held breath rather than a run of loose lines.

   No rule underneath. A quote used to close with a full-width hairline, which
   is exactly the mark a section divider makes — two quotes in a piece and the
   article looked arbitrarily chopped into parts. The margin rule says "someone
   else is speaking" without borrowing the divider's meaning.

   No decorative quotation mark either: writers type their own “ ” and the
   ornament sat above them, so every quote opened twice. */
.jr-article__quote,
.jr-article__pullquote {
    display: block;
    margin: 2.75em 0;
    padding: 0.1em 0 0.1em 1.15em;
    border: 0;
    border-left: 2px solid var(--color-3);
    font-family: var(--font-1);
    font-size: 1.45em;
    font-style: normal;
    font-weight: 400;
    line-height: 1.28;
    letter-spacing: -0.005em;
    color: var(--color-2);
}
.jr-article__quote cite,
.jr-article__pullquote cite {
    display: block;
    margin-top: 0.8em;
    font-family: var(--font-2);
    font-size: 0.5em;
    font-style: normal;
    font-weight: 600;
    letter-spacing: 0.12em;
    line-height: 1.4;
    text-transform: uppercase;
    opacity: 0.6;
}
/* A pull quote is the louder of the two: it breaks the reading measure. The
   negative margin is what pulls it wide, so its rule still lands in the margin
   rather than inside the text column. */
.jr-article__pullquote {
    margin-inline: -2.5em;
    font-size: 1.75em;
}
@media screen and (max-width: 1024px) {
    .jr-article__pullquote { margin-inline: 0; }
}
@media screen and (max-width: 767px) {
    .jr-article__quote { font-size: 1.25em; }
    .jr-article__pullquote { font-size: 1.35em; }
}

/* ---- Remaining body blocks ---------------------------------------------- */
.jr-article__list { margin: 0 0 1.75em; padding-left: 1.35em; font-family: var(--font-2); }
.jr-article__list li { margin-bottom: 0.6em; line-height: 1.5; }
.jr-article__list li::marker { color: var(--color-3); }
/* An image is a change of register, not another paragraph, and it has to be
   spaced like one. The original 2.5em was barely 1.5x the 27px paragraph gap,
   so the line under a picture read as a caption stuck to it.

   The gap below is deliberately larger than the gap above: the picture belongs
   to the passage it illustrates, so it should sit nearer the text it follows
   and hold the next passage off. Set in rem, not em — the figure's own
   font-size is 1em while the prose around it is 1.125em, so an em here is
   smaller than an em there and the spacing quietly under-delivered.

   clamp() keeps it proportionate: tighter on a phone, where 4rem of dead space
   is a scroll rather than a pause, and full width of air on a desktop. Both
   values are 80% of the first pass, which read a touch loose in place. */
.jr-article__figure { margin: clamp(2rem, 4vw, 2.8rem) 0 clamp(2.4rem, 5.2vw, 4rem); }
.jr-article__figure img { width: 100%; height: auto; display: block; border-radius: var(--rounded-lg, 0.5em); }
.jr-article__figure--full { margin-inline: -2.5em; }
@media screen and (max-width: 1024px) { .jr-article__figure--full { margin-inline: 0; } }
/* A caption belongs to its image, so it stays close to it — the figure's own
   bottom margin is what holds the following passage off. */
.jr-article__caption {
    margin: 1em 0 0;
    font-family: var(--font-2);
    font-size: 0.85em;
    line-height: 1.5;
    opacity: 0.65;
}
.jr-article__callout {
    margin: 2.25em 0;
    padding: 1.25em 1.5em;
    border-left: 2px solid var(--color-3);
    background: rgba(211, 207, 197, 0.35);
    font-family: var(--font-2);
    line-height: 1.5;
}
.jr-article__code {
    margin: 2em 0;
    padding: 1.25em 1.5em;
    overflow-x: auto;
    background: var(--color-2);
    color: var(--color-1);
    border-radius: var(--rounded-lg, 0.5em);
    font-size: 0.85em;
    line-height: 1.5;
}
/* ---- Tables -------------------------------------------------------------
   Body copy is set to a 34em measure, which is right for prose and too narrow
   for a table of any width: at four columns the cells were shredding words one
   letter per line. So the table steps OUT of the measure — centred on the
   column, allowed up to 48em, and never wider than the viewport allows.

   Past that it scrolls itself rather than the page. A table is the one block
   whose content genuinely cannot always fold, and a page that scrolls sideways
   as a whole is broken for everyone, not just the reader of the table. The
   wrapper is focusable with a name so the scroll is reachable from the
   keyboard, and it holds the vertical rhythm so the bleed cannot collapse it. */
.jr-article__table-wrap {
    width: min(48em, 100%);
    margin: 2.5em auto;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch;
}
@media screen and (min-width: 900px) {
    /* Centre the wider box on the measure instead of on its own left edge. */
    .jr-article__table-wrap {
        width: min(48em, calc(100vw - 6em));
        margin-left: 50%;
        transform: translateX(-50%);
    }
}
.jr-article__table-wrap:focus-visible { outline: 2px solid var(--color-3); outline-offset: 4px; }

.jr-article__table {
    /* min-width sets the point below which the table scrolls instead of
       crushing: three or more columns stay legible on a phone. */
    width: 100%;
    min-width: 26em;
    border-collapse: collapse;
    font-family: var(--font-2);
    font-size: 0.95em;
    line-height: 1.45;
}
.jr-article__table th, .jr-article__table td {
    padding: 0.75em 0.9em;
    text-align: left;
    vertical-align: top;
    overflow-wrap: break-word;
    border-bottom: 1px solid var(--color-ink-hairline, #03090D60);
}
.jr-article__table th {
    font-family: var(--font-1);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    font-size: 0.85em;
    white-space: nowrap;
    border-bottom-color: rgba(3, 9, 13, 0.55);
}
/* The last row's rule would read as a divider under the table. */
.jr-article__table tbody tr:last-child td { border-bottom: 0; }

/* ---- Reduced motion ----------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    .jr-card__img, .jr-popular__img, .jr-card__cta svg { transition: none; }
    .jr-card:hover .jr-card__img,
    .jr-card:focus-within .jr-card__img,
    .jr-popular__item:hover .jr-popular__img,
    .jr-popular__item:focus-within .jr-popular__img { transform: none; }
    .jr-card:hover .jr-card__cta svg { transform: none; }
}
