/* Ngo Hoang Nguyen theme — blog-single (R4, CORE-BLOG-1 Mulan fidelity).
 *
 * Scope: the single-post composition only. Consumes the semantic tokens from
 * tokens.css; adds a small set of SCOPED blog tokens on .nhn-post so the global
 * --nhn-prose-width (pages, CV, maintenance) is never widened. Measured against
 * Mulan blog-single (docs/R4-MULAN-BLOG-SINGLE-MEASUREMENT-LEDGER.md): 285px
 * rail, 72rem shell, 66.7/33.3 split, 30px gutter, 40px article top.
 *
 * Light/Dark are handled entirely by the semantic tokens (no duplicated rules):
 * --nhn-rail-surface flips to Mulan's panel colors (#f7f9fc / #191919) and
 * --nhn-grid-gap is exactly Mulan's 30px gutter.
 */

/* -- Scoped blog layout tokens -------------------------------------------- */
.nhn-post,
.nhn-masthead {
    --nhn-blog-sidebar: 23rem;                 /* Mulan 380px → 368px (−3.2%) */
    --nhn-blog-gap: var(--nhn-grid-gap);        /* 1.875rem = Mulan 30px gutter */
    --nhn-blog-article-top: 2.5rem;             /* Mulan titlebar→article = 40px */
    --nhn-blog-article-measure: calc(var(--nhn-content-width) - var(--nhn-blog-sidebar) - var(--nhn-blog-gap));
}

/* -- Breadcrumb masthead (restores the Mulan #titlebar region) ------------- */
.nhn-masthead .container {
    padding-block: var(--nhn-space-6) 0;        /* trim the stacked .container section padding */
}

.nhn-masthead__panel {
    background-color: var(--nhn-rail-surface);  /* Mulan .special-block-bg, scheme-correct */
    border: var(--nhn-border-width) solid var(--nhn-border-subtle);
    border-radius: var(--nhn-radius-md);
    padding: var(--nhn-space-5) var(--nhn-space-6);
}

.nhn-masthead__eyebrow {
    margin: 0 0 var(--nhn-space-2);
    font-size: var(--nhn-text-xs);
    font-weight: var(--nhn-weight-semibold);
    letter-spacing: var(--nhn-tracking-wide);
    text-transform: uppercase;
    color: var(--nhn-accent-ink);
}

.nhn-breadcrumbs__list {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--nhn-space-2);
    margin: 0;
    padding: 0;
    list-style: none;
    font-size: var(--nhn-text-sm);
    color: var(--nhn-text-muted);
}

.nhn-breadcrumbs__item {
    display: inline-flex;
    align-items: center;
    gap: var(--nhn-space-2);
    min-inline-size: 0;
}

.nhn-breadcrumbs__item + .nhn-breadcrumbs__item::before {
    content: "/";
    color: var(--nhn-text-muted);
    opacity: 0.6;
}

.nhn-breadcrumbs__link {
    display: inline-flex;
    align-items: center;
    gap: var(--nhn-space-1);
    color: var(--nhn-link);
    text-decoration: none;
    overflow-wrap: anywhere;
}

.nhn-breadcrumbs__link:hover,
.nhn-breadcrumbs__link:focus-visible {
    color: var(--nhn-link-hover);
    text-decoration: underline;
}

.nhn-breadcrumbs__icon { flex: none; }

.nhn-breadcrumbs__current {
    color: var(--nhn-text-strong);
    font-weight: var(--nhn-weight-medium);
    overflow-wrap: anywhere;
}

/* -- Release the single-post prose cap on the shared <main> -----------------
   theme.css caps `main` at --nhn-prose-width (44rem) via the maintenance-view
   rule `body:not(:has(.site-header)) main` (the rail is `.rail`, not
   `.site-header`, so that rule applies to normal pages too). The blog masthead +
   two-column shell need the full --nhn-content-width (72rem); the inner
   `.container` keeps that 72rem cap + margin-inline:auto centering. Scope the
   release to blog surfaces only so CV/page prose width is untouched. Higher
   specificity than the capping rule so it wins regardless of source order. */
.canvas > main:has(.nhn-masthead),
.canvas > main:has(.nhn-post),
.canvas > main:has(.archive) {
    max-inline-size: none;
}

/* R4-H5: the archive feed must FILL the offset canvas beside the rail, not
   shrink-wrap and drift to centre. `main` inherits `margin-inline:auto` from the
   maintenance-width cap rule (`body:not(:has(.site-header)) main`); in the column
   flex `.canvas` an auto cross-axis margin DISABLES `align-items:stretch`, so a
   sparse archive (1–3 posts) collapses to its content width and floats in the
   middle of a huge blank canvas — the exact "bị bóp nhỏ khung vào giữa" defect.
   Zeroing the inline margin lets `main` span the full canvas; the inner
   `.container` re-applies the 72rem measure cap + centering for readability.
   Scoped to `.archive` so the certified blog-single shell is untouched. */
.canvas > main:has(.archive) {
    margin-inline: 0;
}

/* With a full-width archive main, keep the empty state a tidy centred panel
   instead of a canvas-wide band. */
.archive .empty-state {
    max-inline-size: 42rem;
    margin-inline: auto;
}

/* -- Two-column shell ----------------------------------------------------- */
.nhn-masthead + .container {
    /* --nhn-blog-article-top is scoped to .nhn-post / .nhn-masthead; this sibling
       container is their parent, so custom-property inheritance does not reach it
       and the value previously resolved to 0 (content stuck to the titlebar).
       Declare it here so the measured Mulan titlebar→article rhythm (40px) applies. */
    --nhn-blog-article-top: 2.5rem;
    padding-block-start: var(--nhn-blog-article-top);
}

.nhn-post--has-sidebar {
    display: grid;
    grid-template-columns: minmax(0, 1fr) var(--nhn-blog-sidebar);
    gap: var(--nhn-blog-gap);
    align-items: start;
}

.nhn-post__main { min-inline-size: 0; }

.nhn-post--full .nhn-post__main {
    max-inline-size: var(--nhn-blog-article-measure);
    margin-inline: auto;
}

/* Release the global single-column prose cap inside the two-column shell so the
 * article fills its grid track (overrides .entry--post / .entry-title / figure). */
.nhn-post .entry--post,
.nhn-post .entry--post .entry-title,
.nhn-post .entry--post .featured-image {
    max-inline-size: none;
    margin-inline: 0;
}

/* -- Featured media (stable 3:2 box, no layout shift) --------------------- */
.nhn-post__figure {
    margin: 0 0 var(--nhn-space-5);
    aspect-ratio: 3 / 2;
    overflow: hidden;
    border-radius: var(--nhn-radius-md);
    background-color: var(--nhn-surface-muted);
}

.nhn-post__figure .featured-image {
    inline-size: 100%;
    block-size: 100%;
    object-fit: cover;
    display: block;
}

/* -- Post meta: categories chips alongside author/date -------------------- */
.post-meta__item--cats { flex-wrap: wrap; }

.post-meta__cat {
    color: var(--nhn-link);
    text-decoration: none;
}

.post-meta__cat:hover,
.post-meta__cat:focus-visible {
    color: var(--nhn-link-hover);
    text-decoration: underline;
}

/* -- Previous / next navigation ------------------------------------------ */
.nhn-postnav {
    margin-block: var(--nhn-space-7);
    padding-block-start: var(--nhn-space-5);
    border-block-start: var(--nhn-border-width) solid var(--nhn-divider);
}

.nhn-postnav__list {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--nhn-blog-gap);
    margin: 0;
    padding: 0;
    list-style: none;
}

.nhn-postnav__item--next { text-align: end; }

.nhn-postnav__link {
    display: inline-flex;
    flex-direction: column;
    gap: var(--nhn-space-1);
    text-decoration: none;
    color: var(--nhn-text-strong);
}

.nhn-postnav__item--next .nhn-postnav__link { align-items: flex-end; }

.nhn-postnav__label {
    font-size: var(--nhn-text-xs);
    font-weight: var(--nhn-weight-semibold);
    letter-spacing: var(--nhn-tracking-wide);
    text-transform: uppercase;
    color: var(--nhn-text-muted);
}

.nhn-postnav__title {
    font-size: var(--nhn-text-lg);
    font-weight: var(--nhn-weight-medium);
    color: var(--nhn-link);
    overflow-wrap: anywhere;
}

.nhn-postnav__link:hover .nhn-postnav__title,
.nhn-postnav__link:focus-visible .nhn-postnav__title {
    color: var(--nhn-link-hover);
    text-decoration: underline;
}

/* -- Author introduction (privacy-safe: name/avatar/bio/url only) --------- */
.nhn-author {
    display: flex;
    gap: var(--nhn-space-5);
    align-items: flex-start;
    margin-block: var(--nhn-space-7);
    padding: var(--nhn-space-6);
    background-color: var(--nhn-card-surface);
    border: var(--nhn-border-width) solid var(--nhn-border-subtle);
    border-radius: var(--nhn-radius-md);
}

.nhn-author__avatar {
    flex: none;
    inline-size: 80px;
    block-size: 80px;
    border-radius: 50%;
    object-fit: cover;
    background-color: var(--nhn-surface-muted);
}

.nhn-author__avatar--initial {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: var(--nhn-h3);
    font-weight: var(--nhn-weight-semibold);
    color: var(--nhn-accent-ink);
    background-color: var(--nhn-rail-surface);
}

.nhn-author__body { min-inline-size: 0; }

.nhn-author__name {
    margin: 0 0 var(--nhn-space-2);
    font-size: var(--nhn-h4);
    color: var(--nhn-heading);
}

.nhn-author__link { color: inherit; text-decoration: none; }
.nhn-author__link:hover,
.nhn-author__link:focus-visible { color: var(--nhn-link-hover); text-decoration: underline; }

.nhn-author__bio {
    margin: 0;
    color: var(--nhn-text);
    line-height: var(--nhn-leading-normal);
}

/* -- Related posts grid (Mulan .blog-grid-flex) -------------------------- */
.nhn-related { margin-block: var(--nhn-space-8); }

.nhn-related__title {
    margin: 0 0 var(--nhn-space-5);
    font-size: var(--nhn-h3);
    color: var(--nhn-heading);
}

.nhn-related__grid {
    display: grid;
    /* Fit as many compact cards as the (sidebar-narrowed) article column allows:
       3-up on desktop, 2-up on tablet, 1-up when narrow. auto-fit collapses any
       empty trailing track so a 3-card set always fills its row with no right-side
       whitespace. Mobile is forced to a single column below. */
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 10rem), 1fr));
    gap: var(--nhn-space-5);
    margin: 0;
    padding: 0;
    list-style: none;
}

.nhn-card {
    display: flex;
    flex-direction: column;
    block-size: 100%;
    background-color: var(--nhn-card-surface);
    border: var(--nhn-border-width) solid var(--nhn-border-subtle);
    border-radius: var(--nhn-radius-md);
    overflow: hidden;
    box-shadow: var(--nhn-shadow-sm);
    transition: box-shadow var(--nhn-duration-fast) ease, transform var(--nhn-duration-fast) ease;
}

.nhn-card:hover { box-shadow: var(--nhn-card-shadow); transform: translateY(-2px); }

.nhn-card__media {
    display: block;
    aspect-ratio: 3 / 2;
    overflow: hidden;
    background-color: var(--nhn-surface-muted);
}

.nhn-card__media img {
    inline-size: 100%;
    block-size: 100%;
    object-fit: cover;
    display: block;
    transition: transform var(--nhn-duration-fast) ease;
}

.nhn-card:hover .nhn-card__media img { transform: scale(1.04); }

.nhn-card__media--empty { display: block; inline-size: 100%; block-size: 100%; }

.nhn-card__body {
    display: flex;
    flex-direction: column;
    gap: var(--nhn-space-2);
    padding: var(--nhn-space-4);
}

.nhn-card__title {
    margin: 0;
    font-size: var(--nhn-h4);
    line-height: var(--nhn-leading-snug);
    /* Clamp to 2 lines so uneven titles keep cards aligned. Full title text stays
       in the DOM, so the link's accessible name is unaffected. */
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    overflow: hidden;
}

.nhn-card__title a { color: var(--nhn-heading); text-decoration: none; }
.nhn-card__title a:hover,
.nhn-card__title a:focus-visible { color: var(--nhn-link-hover); }

.nhn-card__meta {
    display: flex;
    flex-wrap: wrap;
    gap: var(--nhn-space-3);
    margin: 0;
    font-size: var(--nhn-text-xs);
    color: var(--nhn-text-muted);
}

.nhn-card__cat a { color: var(--nhn-link); text-decoration: none; }
.nhn-card__cat a:hover,
.nhn-card__cat a:focus-visible { color: var(--nhn-link-hover); text-decoration: underline; }

.nhn-card__excerpt {
    margin: 0;
    font-size: var(--nhn-text-sm);
    color: var(--nhn-text);
    line-height: var(--nhn-leading-snug);
    /* Clamp to 2 lines for even card heights (text already char-limited in Blade). */
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    overflow: hidden;
}

/* -- Sidebar + Core widget output (.tn-widget*) styled to Mulan .widget --- */
.nhn-post__sidebar {
    min-inline-size: 0;
    display: flex;
    flex-direction: column;
    gap: var(--nhn-space-6);
}

.nhn-post__sidebar .tn-widget {
    background-color: var(--nhn-card-surface);
    border: var(--nhn-border-width) solid var(--nhn-border-subtle);
    border-radius: var(--nhn-radius-md);
    padding: var(--nhn-space-5);
}

.nhn-post__sidebar .tn-widget__title {
    margin: 0 0 var(--nhn-space-4);
    font-size: var(--nhn-text-lg);
    font-weight: var(--nhn-weight-semibold);
    color: var(--nhn-heading);
    padding-block-end: var(--nhn-space-3);
    border-block-end: var(--nhn-border-width) solid var(--nhn-divider);
}

.nhn-post__sidebar .tn-widget__list {
    margin: 0;
    padding: 0;
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: var(--nhn-space-3);
}

.nhn-post__sidebar .tn-widget__item {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--nhn-space-2);
    font-size: var(--nhn-text-sm);
    line-height: var(--nhn-leading-snug);
}

.nhn-post__sidebar .tn-widget__item a {
    color: var(--nhn-link);
    text-decoration: none;
    overflow-wrap: anywhere;
}

.nhn-post__sidebar .tn-widget__item a:hover,
.nhn-post__sidebar .tn-widget__item a:focus-visible {
    color: var(--nhn-link-hover);
    text-decoration: underline;
}

.nhn-post__sidebar .tn-widget__date,
.nhn-post__sidebar .tn-widget__count {
    color: var(--nhn-text-muted);
    font-size: var(--nhn-text-xs);
}

/* -- Theme-owned sidebar search (Gate 11B: verified cms.search contract) --- */
.nhn-post__sidebar .nhn-widget {
    background-color: var(--nhn-card-surface);
    border: var(--nhn-border-width) solid var(--nhn-border-subtle);
    border-radius: var(--nhn-radius-md);
    padding: var(--nhn-space-5);
    margin: 0;
}

.nhn-post__sidebar .nhn-widget__title {
    margin: 0 0 var(--nhn-space-4);
    font-size: var(--nhn-text-lg);
    font-weight: var(--nhn-weight-semibold);
    color: var(--nhn-heading);
    padding-block-end: var(--nhn-space-3);
    border-block-end: var(--nhn-border-width) solid var(--nhn-divider);
}

.nhn-search {
    display: flex;
    align-items: stretch;
    gap: var(--nhn-space-2);
}

.nhn-search__field {
    flex: 1 1 auto;
    min-inline-size: 0;
    padding: var(--nhn-space-3) var(--nhn-space-4);
    font: inherit;
    font-size: var(--nhn-text-sm);
    color: var(--nhn-text);
    background-color: var(--nhn-surface);
    border: var(--nhn-border-width) solid var(--nhn-border-subtle);
    border-radius: var(--nhn-radius-sm);
}

.nhn-search__field::placeholder { color: var(--nhn-text-muted); opacity: 1; }

.nhn-search__field:focus-visible {
    outline: 2px solid var(--nhn-focus-ring);
    outline-offset: 1px;
    border-color: var(--nhn-focus-ring);
}

.nhn-search__submit {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: 2.75rem;
    padding: 0;
    /* R4-H7: fill + glyph are Theme-Option configurable; empty follows the
       Primary colour / on-accent ink (the shipped Mulan default). */
    color: var(--nhn-opt-search-button-icon, var(--nhn-accent-contrast));
    background-color: var(--nhn-opt-search-button-bg, var(--nhn-accent));
    border: var(--nhn-border-width) solid var(--nhn-opt-search-button-bg, var(--nhn-accent));
    border-radius: var(--nhn-radius-sm);
    cursor: pointer;
    transition: background-color var(--nhn-duration-fast) ease, border-color var(--nhn-duration-fast) ease;
}

.nhn-search__submit:hover {
    background-color: var(--nhn-opt-search-button-hover-bg, var(--nhn-link-hover));
    border-color: var(--nhn-opt-search-button-hover-bg, var(--nhn-link-hover));
}

.nhn-search__submit:focus-visible {
    outline: 2px solid var(--nhn-focus-ring);
    outline-offset: 2px;
}

.nhn-search__icon {
    inline-size: 1rem;
    block-size: 1rem;
}

/* -- Responsive: stack below Mulan's measured 768px threshold ------------- */
@media (max-width: 47.99em) {
    .nhn-post--has-sidebar {
        grid-template-columns: 1fr;
    }

    .nhn-post__sidebar {
        margin-block-start: var(--nhn-space-7);
    }

    .nhn-related__grid {
        grid-template-columns: 1fr;
    }

    .nhn-postnav__list {
        grid-template-columns: 1fr;
    }

    .nhn-postnav__item--next { text-align: start; }
    .nhn-postnav__item--next .nhn-postnav__link { align-items: flex-start; }
}

/* -- Reduced motion ------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
    .nhn-card,
    .nhn-card__media img {
        transition: none;
    }

    .nhn-card:hover { transform: none; }
    .nhn-card:hover .nhn-card__media img { transform: none; }
}

/* ======================================================================== *
 * R4-H5 — Editorial archive feed (category / tag / blog archive / search)
 *
 * Replaces the former even 3-up .post-grid card wall. The feed is composed as
 * a Mulan-faithful editorial band: a tall vertical FEATURE, up to two stacked
 * landscape WIDE cards, then an auto-fit COMPACT river for the remainder. The
 * width cap on <main> is released above (`:has(.archive)`) so the feed uses the
 * full content shell beside the rail; the header stays prose-capped + centered.
 *
 * Scope: everything here is under `.archive`, so the homepage post-grid section
 * (.post-cards / .post-card*) and the single-post related grid (.nhn-card) are
 * untouched. Cards carry exactly one stretched title link for accessibility;
 * media and the directional cue are decorative.
 * ======================================================================== */

/* -- Header: compact, centered, with a small Mulan accent tick -------------- */
.archive .archive-kicker {
    inline-size: 2.5rem;
    block-size: 3px;
    margin: 0 auto var(--nhn-space-4);
    border-radius: var(--nhn-radius-pill);
    background-color: var(--nhn-accent);
}

/* -- Feed lists ------------------------------------------------------------- */
.archive-feature,
.archive-river {
    list-style: none;
    margin: 0;
    padding: 0;
}
.archive-feature {
    display: flex;
    flex-direction: column;
    gap: var(--nhn-grid-gap);
    margin-block-start: var(--nhn-space-8);
}
.archive-river {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--nhn-grid-gap);
    margin-block-start: var(--nhn-grid-gap);
}
.archive-feature__cell,
.archive-river__cell { display: flex; }
.archive-feature .feed-card,
.archive-river .feed-card { block-size: 100%; }

/* -- Card shell ------------------------------------------------------------- */
.feed-card {
    position: relative;
    inline-size: 100%;
    display: flex;
    flex-direction: column;
    border-radius: var(--nhn-radius-lg);
    overflow: hidden;
    background-color: var(--nhn-card-surface);
    box-shadow: var(--nhn-shadow-sm);
    isolation: isolate;
    transition: transform var(--nhn-duration-fast) var(--nhn-ease),
        box-shadow var(--nhn-duration-fast) var(--nhn-ease);
}
.feed-card:hover { transform: translateY(-3px); box-shadow: var(--nhn-card-shadow); }

/* One accessible outline around the whole card when its link is focused. */
.feed-card:has(a:focus-visible) {
    outline: 2px solid var(--nhn-focus-ring);
    outline-offset: 2px;
}

/* Media + body primitives (shared by every variant) */
.feed-card__media {
    display: block;
    overflow: hidden;
    background-color: var(--nhn-surface-muted);
}
.feed-card__media img {
    display: block;
    inline-size: 100%;
    block-size: 100%;
    object-fit: cover;
    transition: transform var(--nhn-duration-normal) var(--nhn-ease);
}
.feed-card:hover .feed-card__media img { transform: scale(1.05); }

.feed-card__body {
    display: flex;
    flex-direction: column;
    gap: var(--nhn-space-3);
    padding: var(--nhn-space-5);
}
.feed-card__kicker {
    margin: 0;
    font-size: var(--nhn-text-xs);
    letter-spacing: var(--nhn-tracking-wide);
    text-transform: uppercase;
    color: var(--nhn-text-muted);
}
.feed-card__title {
    margin: 0;
    font-size: var(--nhn-h4);
    line-height: var(--nhn-leading-snug);
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    overflow: hidden;
    overflow-wrap: anywhere;
}
.feed-card__title a { color: var(--nhn-heading); text-decoration: none; }
/* Stretched link: whole card is the hit area, one link in the a11y tree. */
.feed-card__title a::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 1;
}
.feed-card:hover .feed-card__title a { color: var(--nhn-accent-ink); }
.feed-card__excerpt {
    margin: 0;
    color: var(--nhn-text-muted);
    font-size: var(--nhn-text-sm);
    line-height: var(--nhn-leading-snug);
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    overflow: hidden;
    overflow-wrap: anywhere;
}

/* Directional cue — a Mulan-style circular action affordance (decorative). */
.feed-card__cue {
    margin-block-start: auto;
    inline-size: 2.5rem;
    block-size: 2.5rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--nhn-radius-pill);
    border: var(--nhn-border-width) solid var(--nhn-border);
    color: var(--nhn-accent-ink);
    transition: transform var(--nhn-duration-fast) var(--nhn-ease),
        background-color var(--nhn-duration-fast) var(--nhn-ease),
        border-color var(--nhn-duration-fast) var(--nhn-ease),
        color var(--nhn-duration-fast) var(--nhn-ease);
}
.feed-card:hover .feed-card__cue {
    background-color: var(--nhn-accent);
    border-color: var(--nhn-accent);
    color: var(--nhn-accent-contrast);
    transform: translateX(4px);
}

/* -- COMPACT (river) : image-top, body below -------------------------------- */
.feed-card--compact { border: var(--nhn-border-width) solid var(--nhn-border-subtle); }
.feed-card--compact .feed-card__media { aspect-ratio: 16 / 9; }
/* No-media compact keeps an accent cue strip so it never reads as broken. */
.feed-card--compact.feed-card--text { border-block-start: 3px solid var(--nhn-accent); }

/* -- FEATURE / WIDE with media : image fills, text overlaid at the bottom --- */
.feed-card--feature.feed-card--media,
.feed-card--wide.feed-card--media {
    display: grid;
    grid-template-areas: "stack";
    min-block-size: 15rem;
}
.feed-card--feature.feed-card--media > *,
.feed-card--wide.feed-card--media > * { grid-area: stack; }
.feed-card--feature.feed-card--media .feed-card__media,
.feed-card--wide.feed-card--media .feed-card__media { align-self: stretch; }
.feed-card--feature.feed-card--media .feed-card__scrim,
.feed-card--wide.feed-card--media .feed-card__scrim {
    background: linear-gradient(to top,
        rgba(0, 0, 0, 0.82) 0%,
        rgba(0, 0, 0, 0.42) 45%,
        rgba(0, 0, 0, 0) 74%);
    z-index: 0;
}
.feed-card--feature.feed-card--media .feed-card__body,
.feed-card--wide.feed-card--media .feed-card__body {
    align-self: end;
    position: relative;
    z-index: 2;
}
.feed-card--feature.feed-card--media .feed-card__kicker,
.feed-card--wide.feed-card--media .feed-card__kicker,
.feed-card--feature.feed-card--media .feed-card__title a,
.feed-card--wide.feed-card--media .feed-card__title a,
.feed-card--feature.feed-card--media .feed-card__excerpt,
.feed-card--wide.feed-card--media .feed-card__excerpt { color: #fff; }
.feed-card--feature.feed-card--media:hover .feed-card__title a,
.feed-card--wide.feed-card--media:hover .feed-card__title a { color: #fff; }
.feed-card--feature.feed-card--media .feed-card__cue,
.feed-card--wide.feed-card--media .feed-card__cue {
    border-color: rgba(255, 255, 255, 0.6);
    color: #fff;
}
.feed-card--feature.feed-card--media:hover .feed-card__cue,
.feed-card--wide.feed-card--media:hover .feed-card__cue {
    background-color: #fff;
    border-color: #fff;
    color: var(--nhn-accent-contrast);
}

/* -- FEATURE / WIDE without media : intentional editorial "quote" tile -------
 * A missing featured image is the common real-content case, so it must look
 * deliberate rather than like an empty box. The lead tile becomes a pull-quote
 * panel: a tonal diagonal ground (scheme-aware via tokens), an oversized
 * decorative quotation mark filling the upper field, an accent rule, and the
 * summary anchored to the baseline. This is the archive's signature — imageless
 * posts read as editorial statements, so sparse feeds never look broken. */
.feed-card--feature.feed-card--text,
.feed-card--wide.feed-card--text {
    justify-content: flex-end;
    min-block-size: 15rem;
    background-image: linear-gradient(158deg, var(--nhn-rail-surface) 0%, var(--nhn-surface-muted) 100%);
    border: var(--nhn-border-width) solid var(--nhn-border-subtle);
}
/* Accent rule along the top edge (feature only). */
.feed-card--feature.feed-card--text::before {
    content: "";
    position: absolute;
    inset-block-start: 0;
    inset-inline: 0;
    block-size: 4px;
    background-color: var(--nhn-accent);
    z-index: 1;
}
/* Oversized decorative quotation mark — the "no image" signature. Sits behind
   the summary (card ::after paints last, so the body is lifted with z-index). */
.feed-card--text::after {
    content: "\201C";
    position: absolute;
    inset-block-start: var(--nhn-space-3);
    inset-inline-start: var(--nhn-space-5);
    font-family: var(--nhn-font-heading);
    font-weight: var(--nhn-weight-bold);
    line-height: 0.8;
    color: var(--nhn-accent);
    opacity: 0.16;
    pointer-events: none;
    z-index: 0;
}
.feed-card--feature.feed-card--text::after { font-size: 11rem; }
.feed-card--wide.feed-card--text::after { font-size: 7rem; }
.feed-card--feature.feed-card--text .feed-card__body,
.feed-card--wide.feed-card--text .feed-card__body {
    position: relative;
    z-index: 1;
    padding: var(--nhn-space-6);
}

/* Larger type for the lead cards (both media + text variants). */
.feed-card--feature .feed-card__title { font-size: var(--nhn-h3); -webkit-line-clamp: 3; line-clamp: 3; }
.feed-card--feature .feed-card__excerpt { -webkit-line-clamp: 3; line-clamp: 3; font-size: var(--nhn-text-base); }
.feed-card--wide .feed-card__title { font-size: var(--nhn-h4); }

/* -- Tablet (>= 48em): the feature block becomes a composed grid ------------ */
@media (min-width: 48em) {
    .archive-feature {
        display: grid;
        grid-template-columns: repeat(2, 1fr);
        gap: var(--nhn-grid-gap);
    }
    .archive-feature__cell { display: block; }
    /* One post: full-width lead. Two: side-by-side. Three: lead spans the top row. */
    .archive-feature[data-count="1"] { grid-template-columns: 1fr; }
    .archive-feature[data-count="3"] .archive-feature__cell:first-child { grid-column: 1 / -1; }

    .feed-card--feature.feed-card--media,
    .feed-card--wide.feed-card--media { min-block-size: 16rem; }

    /* River fills the width (1fr tracks) so trailing cards never float centred
       with a blank gutter. Core paginates archives at 4/page (lead takes 3), so
       the river is normally a single tail card — which becomes a full-width
       horizontal strip below to ground the composition. auto-fit still lays out
       2–3 river cards cleanly should a larger page size ever supply them. */
    .archive-river {
        grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
    }
    /* The scrim span is only meaningful for the overlay feature/wide variants;
       drop it in compact so a lone card can compose as a clean 2-cell strip. */
    .feed-card--compact .feed-card__scrim { display: none; }
    .archive-river__cell:only-child .feed-card--compact.feed-card--media {
        display: grid;
        grid-template-columns: minmax(0, 38%) 1fr;
        align-items: stretch;
        min-block-size: 12rem;
    }
    .archive-river__cell:only-child .feed-card--compact.feed-card--media .feed-card__media {
        aspect-ratio: auto;
        block-size: 100%;
    }
}

/* -- Desktop (>= 64em): the Mulan asymmetry — tall feature + stacked wides --- */
@media (min-width: 64em) {
    .archive-feature[data-count="1"] { grid-template-columns: 1fr; }
    .archive-feature[data-count="1"] .feed-card--feature.feed-card--media { min-block-size: 22rem; }
    .archive-feature[data-count="1"] .feed-card--feature.feed-card--text { min-block-size: 18rem; }

    .archive-feature[data-count="2"] { grid-auto-rows: minmax(20rem, 1fr); }

    .archive-feature[data-count="3"] {
        grid-template-columns: 3fr 2fr;
        grid-template-rows: repeat(2, minmax(11rem, 1fr));
    }
    .archive-feature[data-count="3"] .archive-feature__cell:first-child {
        grid-column: 1;
        grid-row: 1 / span 2;
    }
    .archive-feature[data-count="3"] .feed-card--feature { min-block-size: 24rem; }

    .feed-card--feature.feed-card--media,
    .feed-card--wide.feed-card--media { min-block-size: 0; }
}

/* -- Small screens: trim the decorative quote so it never crowds the summary
      on a narrow stacked quote tile. -------------------------------------- */
@media (max-width: 47.99em) {
    .feed-card--feature.feed-card--text::after,
    .feed-card--wide.feed-card--text::after { font-size: 6rem; }
}

/* -- Reduced motion --------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    .feed-card,
    .feed-card__media img,
    .feed-card__cue { transition: none; }
    .feed-card:hover { transform: none; }
    .feed-card:hover .feed-card__media img { transform: none; }
    .feed-card:hover .feed-card__cue { transform: none; }
}

/* ========================================================================== *
 * Reader text-size controls (R4-H6)
 * -------------------------------------------------------------------------- *
 * Single-post article toolbar. Hidden until theme.js wires it (progressive
 * enhancement). A compact, Mulan-quiet pill group that sits with the article
 * meta; it governs only .entry-content / .entry-excerpt via --nhn-reader-scale.
 * ========================================================================== */
.nhn-reader {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--nhn-space-2) var(--nhn-space-3);
    margin-block: 0 var(--nhn-space-6);
}

.nhn-reader__label {
    font-size: var(--nhn-text-xs);
    text-transform: uppercase;
    letter-spacing: var(--nhn-tracking-wide);
    font-weight: var(--nhn-weight-semibold);
    color: var(--nhn-text-muted);
}

.nhn-reader__controls {
    display: inline-flex;
    gap: var(--nhn-space-1);
}

.nhn-reader__btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-inline-size: 2.5rem;
    min-block-size: 2.5rem;
    padding: 0 var(--nhn-space-2);
    border: 1px solid var(--nhn-border);
    border-radius: var(--nhn-radius-sm);
    background-color: var(--nhn-surface);
    color: var(--nhn-text-strong);
    font-family: inherit;
    font-weight: var(--nhn-weight-semibold);
    line-height: 1;
    cursor: pointer;
    transition: border-color var(--nhn-duration-fast) var(--nhn-ease),
        color var(--nhn-duration-fast) var(--nhn-ease),
        background-color var(--nhn-duration-fast) var(--nhn-ease);
}

/* Size cue: A− small, A medium, A+ large. */
.nhn-reader__btn[data-reader-dec] { font-size: var(--nhn-text-sm); }
.nhn-reader__btn[data-reader-reset] { font-size: var(--nhn-text-base); }
.nhn-reader__btn[data-reader-inc] { font-size: var(--nhn-text-lg); }

.nhn-reader__btn:hover,
.nhn-reader__btn:focus-visible {
    border-color: var(--nhn-accent);
    color: var(--nhn-accent-ink);
    background-color: var(--nhn-surface-muted);
}

.nhn-reader__btn:focus-visible {
    outline: 2px solid var(--nhn-focus-ring);
    outline-offset: 2px;
}

.nhn-reader__btn[disabled] {
    opacity: 0.45;
    cursor: not-allowed;
}

@media (prefers-reduced-motion: reduce) {
    .nhn-reader__btn { transition: none; }
}
