:root {
    --fg: #1a1a1a;
    --fg-muted: #5a5a5a;
    --bg: #fafafa;
    --bg-card: #ffffff;
    --accent: #1f4f8b;
    --border: #e2e2e2;
    --notice-bg: #fff8e1;
    --notice-border: #f0c200;
    --chip-bg: #eef3fa;
    --chip-fg: #1f4f8b;
    --chip-subtle-bg: #f1f1f1;
    --chip-subtle-fg: #555;
    --max-w: 880px;
    --home-max-w: 1100px;
    /* Homepage editorial treatment (Foreign Affairs benchmark):
       crimson accent for section kickers, hairline rules, and a serif
       display face for headlines. */
    --home-accent: #9e1b1f;
    --home-rule: #d8d4cc;
    --home-band-bg: #f5f2ec;
    --home-serif: "Noto Serif KR", "Nanum Myeongjo", "Source Serif 4",
                  Georgia, "Times New Roman", serif;
}

* { box-sizing: border-box; }

/* Citation markers jump to #ref-N anchors in the reference list. */
html { scroll-behavior: smooth; }

html, body {
    margin: 0;
    padding: 0;
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Apple SD Gothic Neo",
                 "Noto Sans CJK KR", "Helvetica Neue", Arial, sans-serif;
    color: var(--fg);
    background: var(--bg);
    line-height: 1.65;
    font-size: 19px;
}

/* ------------------------------------------------------------------
   Typography
   -----------------------------------------------------------------
   Body face is per-language (the <html lang="..."> attribute is set
   per request by web/i18n.py). Every page / card title uses Nanum
   Gothic regardless of language, with native-script fallbacks so
   non-Korean glyphs (e.g. CJK kanji/hanzi) still render through
   per-character font fallback.

   `.site-title-font` is exposed as a helper class so templates can
   opt specific elements into the heading face without being an
   <h1>-<h6>.
   ------------------------------------------------------------------ */

/* Per-language body face --------------------------------------------- */
html[lang="ko"] body {
    font-family: "Gowun Dodum", -apple-system, BlinkMacSystemFont,
                 "Apple SD Gothic Neo", "Noto Sans CJK KR", "Segoe UI",
                 Arial, sans-serif;
}
html[lang="en"] body {
    font-family: "Nunito Sans", -apple-system, BlinkMacSystemFont,
                 "Segoe UI", "Helvetica Neue", Arial, sans-serif;
}
html[lang="zh"] body {
    font-family: "LXGW WenKai", "LXGW WenKai Screen", "Noto Sans SC",
                 "PingFang SC", "Microsoft YaHei",
                 -apple-system, BlinkMacSystemFont, sans-serif;
}
html[lang="ja"] body {
    font-family: "Zen Kaku Gothic New", "Hiragino Kaku Gothic ProN",
                 "Noto Sans JP", "Yu Gothic", "Meiryo",
                 -apple-system, BlinkMacSystemFont, sans-serif;
}

/* Universal title face (page / card / heading titles) ---------------
   Specificity is bumped with `html` so this wins over the per-language
   `html[lang="..."] body` rules above, while still letting individual
   widgets override `font-family` with a more specific selector when
   needed. */
html h1,
html h2,
html h3,
html h4,
html h5,
html h6,
html .row-title,
html .cat-title,
html .site-title-font {
    font-family: "Nanum Gothic", -apple-system, BlinkMacSystemFont,
                 "Apple SD Gothic Neo", "Noto Sans CJK KR",
                 "PingFang SC", "Hiragino Kaku Gothic ProN",
                 "Segoe UI", "Helvetica Neue", Arial, sans-serif;
}

/* Titles never break inside a word: `keep-all` keeps CJK words intact
   (CJK text otherwise breaks between any two characters) and
   `overflow-wrap: normal` disables the mid-word emergency breaks some
   title widgets used to enable. The `html` prefix outranks the
   per-widget class rules below. */
html .row-title,
html .cat-title,
html .cat-item-title,
html .current-watch__title,
html .current-watch__list-title,
html .current-watch__sub-title,
html .viz-modal__title,
html .report-header h1 {
    word-break: keep-all;
    overflow-wrap: normal;
}

/* zh / ja have no inter-word spaces, so `keep-all` would forbid every
   break point and force one-line titles that overflow on mobile.
   Restore the default CJK behavior (break between any two characters)
   for those languages only; ko keeps `keep-all` since Korean uses
   spaces between words. */
html[lang="zh"] .row-title,
html[lang="ja"] .row-title,
html[lang="zh"] .cat-title,
html[lang="ja"] .cat-title,
html[lang="zh"] .cat-item-title,
html[lang="ja"] .cat-item-title,
html[lang="zh"] .current-watch__title,
html[lang="ja"] .current-watch__title,
html[lang="zh"] .current-watch__list-title,
html[lang="ja"] .current-watch__list-title,
html[lang="zh"] .current-watch__sub-title,
html[lang="ja"] .current-watch__sub-title,
html[lang="zh"] .viz-modal__title,
html[lang="ja"] .viz-modal__title,
html[lang="zh"] .report-header h1,
html[lang="ja"] .report-header h1 {
    word-break: normal;
    overflow-wrap: break-word;
}

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

.site-header {
    background: var(--bg-card);
    border-bottom: 1px solid var(--border);
}
/* Homepage masthead: heavier double rule under the brand bar (FA-style
   editorial chrome) on a pure-white canvas. The full-bleed viz band
   uses a 100vw negative-margin escape, so clip horizontal overflow to
   keep the scrollbar gutter from introducing a sideways scroll. */
body.home { overflow-x: hidden; }
body.home .site-header {
    background: #fff;
    border-bottom: 4px double var(--fg);
}
/* Header bar: two-column grid at every viewport size. The brand logo
   spans both rows on the left; the collapsed language trigger sits
   top-right with the account / logout controls right-aligned beneath
   it, their bottom edge lined up with the bottom edge of the logo. */
.site-header .bar {
    max-width: var(--home-max-w);
    margin: 0 auto;
    padding: 14px 20px;
    display: grid;
    /* Brand column hugs the logo; the right column absorbs the rest
       and may shrink below its content width (minmax(0, 1fr)) so the
       inline keyword menu scrolls instead of overlapping the logo. */
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-rows: auto 1fr;
    align-items: start;
    gap: 8px 16px;
}
.brand {
    grid-row: 1 / span 2;
    grid-column: 1;
    display: inline-flex;
    align-items: center;
    color: var(--fg);
    line-height: 0;
}
.brand-logo {
    height: 104px;
    width: auto;
    display: block;
}
.lang-switch {
    position: relative;
    grid-row: 1;
    grid-column: 2;
    justify-self: end;
    align-self: start;
    /* Nudge the trigger down so it doesn't hug the top edge of the
       header bar. */
    margin-top: 10px;
}
/* Collapsed language trigger: shows the current language and expands
   the full list as a dropdown. */
.lang-switch .lang-switch-toggle {
    display: inline-flex;
    appearance: none;
    align-items: center;
    gap: 4px;
    padding: 2px 10px;
    background: #fff;
    color: var(--fg-muted);
    border: 1px solid var(--border);
    font: inherit;
    font-size: 12px;
    cursor: pointer;
}
.lang-switch-caret { font-size: 10px; line-height: 1; }
.lang-switch-list {
    display: none;
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    z-index: 40;
    flex-direction: column;
    align-items: stretch;
    gap: 4px;
    min-width: 120px;
    padding: 8px;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 10px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
}
.lang-switch.is-open .lang-switch-list { display: flex; }
.lang-switch-list .lang {
    text-align: center;
    padding: 6px 10px;
    font-size: 13px;
    line-height: 1.3;
}
.lang {
    padding: 4px 8px;
    border: 1px solid var(--border);
    border-radius: 999px;
    font-size: 16px;
    color: var(--fg-muted);
}
.lang.current {
    background: var(--accent);
    color: #fff;
    border-color: var(--accent);
}

/* Bottom-right header cell: keyword menu (top-5 monthly report
   keywords + "Our Vision") inline to the LEFT of the account /
   login-signup controls -- one shared row, no extra header band.
   On narrow viewports the keyword list scrolls horizontally instead
   of wrapping so the row stays one line tall. */
.header-menus {
    grid-row: 2;
    grid-column: 2;
    justify-self: end;
    align-self: end;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 14px;
    min-width: 0;
    max-width: 100%;
}
.keyword-nav {
    display: flex;
    align-items: center;
    flex: 0 1 auto;
    min-width: 0;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
}
.keyword-nav::-webkit-scrollbar { display: none; }
/* Track holds the link set plus (in marquee mode) a clone of it; the
   wide gap doubles as the visual seam between the two loop copies. */
.keyword-nav-track {
    display: flex;
    align-items: center;
    gap: 28px;
}
.keyword-nav-set {
    display: flex;
    align-items: center;
    gap: 2px;
    flex: none;
}
.keyword-nav-set-clone { display: none; }
/* Overflow marquee (class + CSS vars set by JS in base.html): the row
   is too narrow for every link, so scroll the set leftwards forever.
   Hover / keyboard focus pauses it so links stay clickable. */
.keyword-nav.is-marquee {
    overflow: hidden;
    mask-image: linear-gradient(to right,
        transparent, #000 14px, #000 calc(100% - 14px), transparent);
    -webkit-mask-image: linear-gradient(to right,
        transparent, #000 14px, #000 calc(100% - 14px), transparent);
}
.keyword-nav.is-marquee .keyword-nav-set-clone { display: flex; }
.keyword-nav.is-marquee .keyword-nav-track {
    width: max-content;
    animation: keyword-nav-marquee var(--marquee-duration, 20s)
        linear infinite;
}
.keyword-nav.is-marquee .keyword-nav-track:hover,
.keyword-nav.is-marquee .keyword-nav-track:focus-within {
    animation-play-state: paused;
}
@keyframes keyword-nav-marquee {
    from { transform: translateX(0); }
    to { transform: translateX(calc(-1 * var(--marquee-shift, 100%))); }
}
.keyword-nav-link {
    display: inline-block;
    padding: 4px 8px;
    font-size: 15px;
    font-weight: 700;
    font-family: 'Nanum Gothic', sans-serif;
    color: var(--fg-muted);
    white-space: nowrap;
    border-bottom: 2px solid transparent;
}
.keyword-nav-link:hover {
    color: var(--accent);
    text-decoration: none;
}
.keyword-nav-link.is-active {
    color: var(--accent);
    border-bottom-color: var(--accent);
}
/* "Our Vision" shares the crimson of the EAI Current Watch kicker. */
.keyword-nav-vision {
    color: var(--home-accent);
    letter-spacing: 0.02em;
}
.keyword-nav-vision:hover,
.keyword-nav-vision.is-active {
    color: var(--home-accent);
    border-bottom-color: var(--home-accent);
}
/* Phones: the keyword menu moves to its own full-width header row
   below the brand / account bar. Dissolve the shared flex cell
   (display: contents) so its children become header-grid items:
   the account controls stay bottom-right and the keyword list spans
   both grid columns on a new third row. */
@media (max-width: 640px) {
    .header-menus {
        display: contents;
    }
    .header-menus .user-nav {
        grid-row: 2;
        grid-column: 2;
        justify-self: end;
        align-self: end;
    }
    .keyword-nav {
        grid-row: 3;
        grid-column: 1 / -1;
        padding-top: 8px;
        border-top: 1px solid var(--border);
        /* A right-edge fade hints at the horizontally scrollable
           overflow instead of clipping it abruptly. */
        mask-image: linear-gradient(to right, #000 88%, transparent);
        -webkit-mask-image: linear-gradient(to right, #000 88%, transparent);
    }
    /* Compact pills so 로그인/회원가입 stay on one line next to the
       logo on ~360px screens instead of wrapping mid-word. */
    .user-nav .lang,
    .user-nav .user-nav-link {
        white-space: nowrap;
        font-size: 13px;
        padding: 3px 9px;
    }
}

.site-main {
    max-width: var(--max-w);
    margin: 0 auto;
    padding: 28px 20px 60px;
}
/* The homepage uses a wider canvas so the 2-col category grid breathes. */
body.home .site-main {
    max-width: var(--home-max-w);
}

.site-footer {
    margin-top: 40px;
    background: #f3f5f8;
    color: var(--fg-muted);
    text-align: center;
    font-size: 14px;
    line-height: 1.7;
    padding: 36px 20px 64px;
}
.site-footer-inner {
    max-width: var(--home-max-w);
    margin: 0 auto;
}
.site-footer-org {
    margin: 0 0 10px;
    font-size: 18px;
    font-weight: 700;
    color: var(--fg);
    letter-spacing: 0.01em;
}
.site-footer-line {
    margin: 0;
    color: var(--fg-muted);
    font-size: 14px;
}
.site-footer-divider {
    border: 0;
    border-top: 1px solid #d9dee6;
    margin: 18px auto;
    max-width: 760px;
}
.site-footer-copy {
    margin: 0;
    color: var(--fg-muted);
    font-size: 12px;
}
.site-footer-credit {
    margin: 8px 0 0;
    color: var(--fg-muted);
    font-size: 12px;
}
.site-footer-credit a {
    color: inherit;
    text-decoration: underline;
}
.site-footer-credit a:hover { color: var(--accent); }
.site-footer-legal {
    margin: 12px 0 0;
    font-size: 13px;
}
.site-footer-legal a {
    color: inherit;
    text-decoration: underline;
}
.site-footer-legal a:hover { color: var(--accent); }
.site-footer-social {
    margin: 16px 0 0;
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 14px;
}
.site-footer-social-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    color: var(--fg-muted);
    border: 1px solid #d9dee6;
    transition: color .15s ease, border-color .15s ease, background-color .15s ease;
}
.site-footer-social-link:hover {
    color: #fff;
    background: var(--accent);
    border-color: var(--accent);
}
.site-footer-social-link svg {
    width: 18px;
    height: 18px;
    display: block;
}

/* Legal pages (terms of service / privacy policy) */
.legal-page {
    max-width: 760px;
    margin: 0 auto;
    padding: 0 4px;
    color: var(--fg);
    line-height: 1.75;
}
.legal-page h1 {
    margin: 0 0 24px;
    font-size: 28px;
}
.legal-section { margin: 0 0 28px; }
.legal-section h2 {
    margin: 0 0 10px;
    font-size: 19px;
    line-height: 1.4;
}
.legal-clauses {
    margin: 0;
    padding-left: 1.6em;
    list-style: decimal;
}
.legal-clause { margin: 0 0 8px; }
.legal-clause-text { color: var(--fg-muted); }
.legal-items {
    margin: 6px 0 4px;
    padding-left: 1.4em;
    list-style: lower-alpha;
}
.legal-items li {
    margin: 0 0 4px;
    color: var(--fg-muted);
}
.legal-officer a { color: var(--accent); }
.legal-back {
    margin-top: 32px;
    padding-top: 16px;
    border-top: 1px solid var(--border);
}
.legal-back a { color: var(--fg-muted); }
.legal-back a:hover { color: var(--accent); }

/* "Our Vision" page: director photo floated beside the statement on
   wide viewports, stacked above it on narrow ones. */
.vision-page {
    max-width: 860px;
    margin: 0 auto;
    padding: 0 4px;
    color: var(--fg);
    line-height: 1.85;
}
.vision-title {
    margin: 0 0 28px;
    font-size: 32px;
    font-family: 'Nanum Gothic', sans-serif;
    letter-spacing: 0.01em;
}
.vision-layout {
    display: flex;
    gap: 32px;
    align-items: flex-start;
}
.vision-photo {
    flex: 0 0 260px;
    margin: 6px 0 0;
    position: sticky;
    top: 20px;
}
.vision-photo img {
    display: block;
    width: 100%;
    height: auto;
    border-radius: 10px;
    border: 1px solid var(--border);
}
.vision-photo figcaption {
    margin-top: 10px;
    font-size: 14px;
    color: var(--fg-muted);
    text-align: center;
    line-height: 1.5;
}
.vision-body { flex: 1 1 auto; min-width: 0; }
.vision-body p {
    margin: 0 0 18px;
    font-size: 17px;
}
.vision-signature {
    margin-top: 28px;
    font-weight: 700;
    text-align: right;
}
@media (max-width: 720px) {
    .vision-layout { flex-direction: column; }
    .vision-photo {
        position: static;
        flex: 0 0 auto;
        width: min(260px, 70%);
        margin: 0 auto 8px;
    }
}

/* Contact page */
.contact-intro {
    margin: 0 0 24px;
    color: var(--fg-muted);
}
.contact-details {
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: 8px 18px;
    margin: 0;
}
.contact-details dt {
    font-weight: 600;
    color: var(--fg);
}
.contact-details dd {
    margin: 0;
    color: var(--fg-muted);
}
.contact-details a { color: var(--accent); }
.contact-map {
    position: relative;
    width: 100%;
    aspect-ratio: 16 / 9;
    border: 1px solid var(--border);
    border-radius: 8px;
    overflow: hidden;
    background: #eef1f5;
}
.contact-map iframe {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
}
.contact-map-link {
    margin: 10px 0 0;
    font-size: 14px;
}
.contact-map-link a { color: var(--accent); }

/* List */
.report-list h1 { margin-top: 0; }
.report-list .empty { color: var(--fg-muted); font-style: italic; }

/* Search bar (public list) */
.list-search {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    margin: 0 0 16px;
}
.list-search-label {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    border: 0;
}
.list-search-input {
    flex: 1 1 240px;
    min-width: 0;
    padding: 8px 12px;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--bg-card);
    font: inherit;
    font-size: 16px;
    color: inherit;
}
.list-search-input:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 2px rgba(0, 102, 204, 0.15);
}
.list-search-submit {
    padding: 8px 16px;
    border: 1px solid var(--accent);
    border-radius: 6px;
    background: var(--accent);
    color: #fff;
    font: inherit;
    font-size: 16px;
    cursor: pointer;
    white-space: nowrap;
}
.list-search-submit:hover { filter: brightness(0.95); }

/* Shared loading state for search submit buttons (list + home forms). */
.list-search-submit[disabled],
.home-search-submit[disabled] {
    cursor: progress;
    opacity: 0.85;
}
.list-search-submit[aria-busy="true"],
.home-search-submit[aria-busy="true"] {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}
.btn-spinner {
    display: inline-block;
    width: 14px;
    height: 14px;
    border: 2px solid rgba(255, 255, 255, 0.45);
    border-top-color: #fff;
    border-radius: 50%;
    animation: btn-spin 0.6s linear infinite;
    flex: none;
}
.btn-spinner-label { white-space: nowrap; }
@keyframes btn-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
    .btn-spinner { animation-duration: 1.6s; }
}

/* Full-page loading modal: shown while a keyword-nav search navigates
   to the results list page. */
.page-loading-overlay {
    position: fixed;
    inset: 0;
    z-index: 100;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(255, 255, 255, 0.7);
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
}
.page-loading-overlay[hidden] { display: none; }
.page-loading-box {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 14px 22px;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 12px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
    font-size: 14px;
    font-weight: 700;
    color: var(--fg-muted);
}
.page-loading-spinner {
    width: 18px;
    height: 18px;
    border: 2px solid var(--border);
    border-top-color: var(--accent);
    border-radius: 50%;
    animation: btn-spin 0.6s linear infinite;
    flex: none;
}
@media (prefers-reduced-motion: reduce) {
    .page-loading-spinner { animation-duration: 1.6s; }
}
/* Dim the search inputs while the results page is loading. */
form.is-searching .list-search-input,
form.is-searching .list-search-textarea,
form.is-searching .home-search-input,
form.is-searching .home-search-textarea,
form.is-searching .home-search-mode {
    opacity: 0.7;
    pointer-events: none;
}
.list-search-clear {
    padding: 8px 12px;
    color: var(--fg-muted);
    font-size: 15px;
    white-space: nowrap;
}
.list-search-clear:hover { color: var(--accent); text-decoration: underline; }
.list-search-summary {
    margin: 0 0 16px;
    color: var(--fg-muted);
    font-size: 15px;
}

.rows { list-style: none; padding: 0; margin: 0; display: grid; gap: 14px; }
.row { background: var(--bg-card); border: 1px solid var(--border); border-radius: 8px; }
.row-link {
    display: flex;
    gap: 16px;
    align-items: center;
    padding: 14px 18px;
    color: inherit;
}
.row-link:hover { text-decoration: none; background: #f6f8fb; }
.row-thumb {
    width: 88px;
    height: 88px;
    object-fit: cover;
    border-radius: 6px;
    flex-shrink: 0;
    background: var(--chip-subtle-bg);
    display: block;
}
.row-thumb--fallback {
    object-fit: contain;
    background: #fff;
    border: 1px solid var(--border);
    padding: 6px;
}
.row-content { flex: 1 1 auto; min-width: 0; }
.row-meta {
    display: flex;
    gap: 8px;
    align-items: center;
    flex-wrap: wrap;
    font-size: 16px;
    color: var(--fg-muted);
    margin-bottom: 6px;
}
.row-title { margin: 0; font-size: 20px; line-height: 1.4; font-weight: 600; }
.row-title.fallback { color: var(--fg-muted); font-style: italic; }

/* List row titles mirror the homepage headline format: the serif
   display face by default, with the same Noto Sans bold overrides
   for ko/zh/ja used by the homepage title rules. The `html` prefix
   outranks the global Nanum Gothic heading rule. */
html .report-list .row-title {
    font-family: var(--home-serif);
}
html[lang="ko"] .report-list .row-title {
    font-family: "Noto Sans KR", "Apple SD Gothic Neo", "Noto Sans CJK KR",
                 -apple-system, BlinkMacSystemFont, sans-serif;
    font-weight: 700;
}
html[lang="zh"] .report-list .row-title {
    font-family: "Noto Sans SC", "PingFang SC", "Microsoft YaHei",
                 -apple-system, BlinkMacSystemFont, sans-serif;
    font-weight: 700;
}
html[lang="ja"] .report-list .row-title {
    font-family: "Noto Sans JP", "Hiragino Kaku Gothic ProN", "Yu Gothic",
                 "Meiryo", -apple-system, BlinkMacSystemFont, sans-serif;
    font-weight: 700;
}
.row-authors {
    margin: 4px 0 0;
    font-size: 14px;
    line-height: 1.4;
    color: var(--fg-muted);
    overflow-wrap: anywhere;
    word-break: break-word;
}
.chip {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 999px;
    font-size: 14px;
    background: var(--chip-bg);
    color: var(--chip-fg);
}
.chip.subtle { background: var(--chip-subtle-bg); color: var(--chip-subtle-fg); }

/* Pager (public list) */
.pager {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin: 28px 0 8px;
    flex-wrap: wrap;
}
.pager-btn {
    padding: 8px 14px;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--bg-card);
    color: var(--accent);
    font-size: 17px;
    line-height: 1.2;
    white-space: nowrap;
}
.pager-btn:hover { text-decoration: none; background: #f3f6fb; }
.pager-btn.disabled {
    color: var(--fg-muted);
    background: transparent;
    cursor: default;
    pointer-events: none;
    opacity: 0.55;
}
.pager-summary {
    color: var(--fg-muted);
    font-size: 16px;
    text-align: center;
    flex: 1 1 auto;
}

/* Detail */
.back-nav .back { color: var(--fg-muted); font-size: 17px; }
.back-nav--bottom {
    margin-top: 32px;
    padding-top: 16px;
    border-top: 1px solid var(--border);
}
.ai-translation-notice {
    margin: 32px 0 0;
    color: var(--fg-muted);
    font-size: 14px;
    font-style: italic;
    line-height: 1.55;
}
/* When the AI notice sits directly above the bottom nav, the nav's
   top border alone provides the separator -- collapse the notice's
   own top spacing into a shared gap. */
.ai-translation-notice + .back-nav--bottom { margin-top: 20px; }
.report-header h1 { margin-bottom: 8px; line-height: 1.3; font-size: 25px; }

/* Series/collection subtitle shown directly under the report title
   (e.g. the parent 답사기 title above an individual chapter report). */
.report-subtitle {
    margin: 0 0 12px;
    color: var(--fg-muted);
    font-size: 17px;
    font-weight: 500;
    line-height: 1.4;
    word-break: keep-all;
}

/* Compact byline directly under the title: shows author name +
   affiliation in a single line per author, no image, no bio block.
   Multiple authors stack vertically on narrow screens but stay
   inline on wider viewports separated by a soft middle dot. */
.report-byline {
    list-style: none;
    margin: 0 0 14px;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 4px 14px;
    color: var(--fg);
    font-size: 16px;
    line-height: 1.5;
}
.report-byline__author {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 6px;
}
.report-byline__author + .report-byline__author::before {
    content: ",";
    margin-right: 4px;
    color: var(--fg-muted);
}
/* The byline-wrapper above sets a 16px baseline for the affiliation;
   the name itself bumps up just past the body text size (19px) so the
   author reads as the strongest element beneath the title without
   competing with ``.report-header h1`` at 25px. */
.report-byline__name { font-weight: 600; font-size: 21px; }
.report-byline__sep { color: var(--fg-muted); }
.report-byline__affiliation { color: var(--fg-muted); }

.meta {
    display: grid;
    grid-template-columns: max-content 1fr;
    column-gap: 14px;
    row-gap: 4px;
    margin: 12px 0 24px;
    color: var(--fg-muted);
    font-size: 17px;
}
.meta dt { font-weight: 600; }
.meta dd { margin: 0; }

.notice {
    background: var(--notice-bg);
    border: 1px solid var(--notice-border);
    padding: 10px 14px;
    border-radius: 6px;
    margin: 12px 0 18px;
    font-size: 17px;
}

.editors-note {
    background: var(--bg-card);
    border-left: 3px solid var(--accent);
    padding: 14px 18px;
    margin: 18px 0;
}
.editors-note h2 { margin-top: 0; font-size: 17px; text-transform: uppercase; color: var(--fg-muted); letter-spacing: .04em; }

.body { margin-top: 28px; }
.body h1, .body h2, .body h3, .body h4 { margin-top: 1.6em; font-size: 20px; line-height: 1.4; }
.body p { margin: 0 0 1em; }
.body img { max-width: 100%; height: auto; display: block; margin: 12px 0; }
/* EAIs-imported figures get role-based default widths so the page
   layout is consistent across reports. ``max-width: 100%`` (above)
   still applies so narrow viewports shrink the figure responsively
   even when the role-specific rule below requests a larger width. */
.body img.eais-illustration,
.body figure.eais-illustration > img { width: 760px; }
.body img.eais-visualization,
.body figure.eais-visualization > img { width: 100%; }

.cover-image {
    margin: 0 0 24px;
}
.cover-image img {
    width: 100%;
    max-height: 480px;
    height: auto;
    object-fit: cover;
    display: block;
    border-radius: 6px;
    border: 1px solid var(--border);
}
.cover-image figcaption {
    margin-top: 8px;
    color: var(--fg-muted);
    font-size: 15px;
    text-align: center;
}
.body blockquote {
    border-left: 3px solid var(--border);
    margin: 1em 0;
    padding: 4px 14px;
    color: var(--fg-muted);
}
.body table {
    border-collapse: collapse;
    width: 100%;
    margin: 1em 0;
    font-size: 17px;
}
.body th, .body td { border: 1px solid var(--border); padding: 6px 10px; text-align: left; }
.body th { background: var(--chip-subtle-bg); }
.body pre { background: #f3f3f3; padding: 12px; overflow-x: auto; border-radius: 6px; }
.body code { background: #f3f3f3; padding: 1px 4px; border-radius: 3px; font-size: 0.95em; }
.body iframe { max-width: 100%; }

/* ------------------------------------------------------------------
   Citations ('참고출처' / References)
   ------------------------------------------------------------------
   blocks_renderer._link_citations rewrites inline [N] markers into
   sup.cite-ref anchors and tags each trailing reference paragraph as
   p.cite-item with id="ref-N" so the marker can jump to it. */
sup.cite-ref {
    line-height: 0; /* keep the superscript from inflating line height */
}
sup.cite-ref a {
    font-size: 12px;
    font-weight: 600;
    color: var(--accent);
    text-decoration: none;
    padding: 0 1px;
}
sup.cite-ref a:hover { text-decoration: underline; }

/* The html[lang] prefix lifts specificity above the per-language
   article typography rules (e.g. ``html[lang="ko"] .report-detail
   .body p { margin-bottom: 24px }``) so the reference list stays
   compact in every display language. */
.body p.cite-item,
html[lang] .report-detail .body p.cite-item {
    font-size: 15px;
    line-height: 1.6;
    color: var(--fg-muted);
    /* Vertical margins only: the CJK (ko/ja/zh) article layout centers
       every `.body > *` text block in a 616px column via
       `margin-left/right: auto`, and this higher-specificity rule must
       not reset those -- otherwise the reference list breaks out of the
       column and no longer lines up with the 참고출처 heading. */
    margin-top: 0;
    margin-bottom: 6px;
    text-align: left;
    word-break: break-word;
    overflow-wrap: anywhere; /* long source URLs must not overflow */
    /* Clicked footnote targets must land below the pinned title/TOC bar
       (.report-sticky-bar); mirrors .report-section-anchor's margins. */
    scroll-margin-top: 60px;
}
@media (max-width: 899px) {
    .body p.cite-item,
    html[lang] .report-detail .body p.cite-item {
        scroll-margin-top: 76px;
    }
}
.body p.cite-item:target {
    background: var(--chip-subtle-bg, #f0f4fa);
    border-radius: 4px;
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

/* ------------------------------------------------------------------
   Article typography for Latin/Cyrillic languages (en / fr / es / ru)
   -----------------------------------------------------------------
   Metrics benchmarked against foreignaffairs.com article pages:
   ~630px text column, normal letter-spacing, left alignment, ~20px
   paragraph spacing, 1.45 line-height at every width. FA's body size
   is fluid: 18px below 768px, then calc(16px + 0.5vw) capped at 22px
   (measured 20.25px @ 850, 21px @ 1000, 22px @ 1200+).
   Body face benchmarked against foreignpolicy.com (tiempos with a
   georgia/serif fallback stack).
   ------------------------------------------------------------------ */
/* FA uses two centered columns: a wide "topper" (title header) and a
   narrower ~630px text column (measured 1063px vs 630px). The header
   keeps the full page column; every text section below it collapses
   to the 630px reading column. */
html[lang="en"] .report-detail .editors-note,
html[lang="fr"] .report-detail .editors-note,
html[lang="es"] .report-detail .editors-note,
html[lang="ru"] .report-detail .editors-note,
html[lang="en"] .report-detail .body,
html[lang="fr"] .report-detail .body,
html[lang="es"] .report-detail .body,
html[lang="ru"] .report-detail .body,
html[lang="en"] .report-detail .tabs,
html[lang="fr"] .report-detail .tabs,
html[lang="es"] .report-detail .tabs,
html[lang="ru"] .report-detail .tabs,
html[lang="en"] .report-detail .attachments,
html[lang="fr"] .report-detail .attachments,
html[lang="es"] .report-detail .attachments,
html[lang="ru"] .report-detail .attachments,
html[lang="en"] .report-detail .ai-translation-notice,
html[lang="fr"] .report-detail .ai-translation-notice,
html[lang="es"] .report-detail .ai-translation-notice,
html[lang="ru"] .report-detail .ai-translation-notice,
html[lang="en"] .report-detail .related-reports-mount,
html[lang="fr"] .report-detail .related-reports-mount,
html[lang="es"] .report-detail .related-reports-mount,
html[lang="ru"] .report-detail .related-reports-mount {
    max-width: 630px;
    margin-left: auto;
    margin-right: auto;
}
/* Title header, benchmarked against the FA article "topper":
   serif display title at min(40px + 2vw, 64px)/1.1 weight 400,
   small-caps byline at min(14px + 1vw, 26px)/1 with 0.075em
   tracking, and an 18px-capped serif meta line — all left-aligned,
   all fluid until the 1200px cap. */
html[lang="en"] .report-detail .report-header h1,
html[lang="fr"] .report-detail .report-header h1,
html[lang="es"] .report-detail .report-header h1,
html[lang="ru"] .report-detail .report-header h1 {
    font-family: "Tiempos Text", Tiempos, Georgia, "Times New Roman", serif;
    /* FA caps its display title at 64px, but FA headlines run ~5 words;
       EAI titles are several times longer, so the same scale overwhelms
       the page. Keep the fluid FA-style behaviour at a gentler scale. */
    font-size: min(calc(26px + 1vw), 40px);
    line-height: 1.2;
    font-weight: 400;
    letter-spacing: normal;
    text-align: left;
    margin: 0 0 15px;
}
html[lang="en"] .report-detail .report-byline,
html[lang="fr"] .report-detail .report-byline,
html[lang="es"] .report-detail .report-byline,
html[lang="ru"] .report-detail .report-byline {
    font-family: "Tiempos Text", Tiempos, Georgia, "Times New Roman", serif;
    margin: 0 0 15px;
}
html[lang="en"] .report-detail .report-byline__name,
html[lang="fr"] .report-detail .report-byline__name,
html[lang="es"] .report-detail .report-byline__name,
html[lang="ru"] .report-detail .report-byline__name {
    font-weight: 400;
    font-size: min(calc(14px + 1vw), 26px);
    line-height: 1;
    letter-spacing: 0.075em;
    font-variant: all-small-caps;
}
html[lang="en"] .report-detail .meta,
html[lang="fr"] .report-detail .meta,
html[lang="es"] .report-detail .meta,
html[lang="ru"] .report-detail .meta {
    font-family: "Tiempos Text", Tiempos, Georgia, "Times New Roman", serif;
    font-size: min(calc(13.5px + 0.375vw), 18px);
    color: var(--fg);
}

html[lang="en"] .report-detail .body,
html[lang="fr"] .report-detail .body,
html[lang="es"] .report-detail .body,
html[lang="ru"] .report-detail .body {
    font-family: "Tiempos Text", Tiempos, Georgia, "Times New Roman", serif;
    font-size: 18px;
    line-height: 1.45;
    letter-spacing: normal;
    text-align: left;
}
@media (min-width: 768px) {
    html[lang="en"] .report-detail .body,
    html[lang="fr"] .report-detail .body,
    html[lang="es"] .report-detail .body,
    html[lang="ru"] .report-detail .body {
        font-size: min(calc(16px + 0.5vw), 22px);
    }
}
html[lang="en"] .report-detail .body p,
html[lang="fr"] .report-detail .body p,
html[lang="es"] .report-detail .body p,
html[lang="ru"] .report-detail .body p {
    margin: 0 0 20px;
}
/* In-body section headings follow the serif article face (FA uses a
   serif subhead inside the article column as well). Specificity must
   beat the universal `html h1..h6` Nanum Gothic rule above. */
html[lang="en"] .report-detail .body h1, html[lang="en"] .report-detail .body h2,
html[lang="en"] .report-detail .body h3, html[lang="en"] .report-detail .body h4,
html[lang="fr"] .report-detail .body h1, html[lang="fr"] .report-detail .body h2,
html[lang="fr"] .report-detail .body h3, html[lang="fr"] .report-detail .body h4,
html[lang="es"] .report-detail .body h1, html[lang="es"] .report-detail .body h2,
html[lang="es"] .report-detail .body h3, html[lang="es"] .report-detail .body h4,
html[lang="ru"] .report-detail .body h1, html[lang="ru"] .report-detail .body h2,
html[lang="ru"] .report-detail .body h3, html[lang="ru"] .report-detail .body h4 {
    font-family: "Tiempos Text", Tiempos, Georgia, "Times New Roman", serif;
}

/* ------------------------------------------------------------------
   CJK article typography — benchmarked on chosun.com article pages
   (measured live, 2026-06): running text sits in a 616px column,
   18px body face with a 1.74 line-height and -0.5px tracking,
   justified with break-all line breaking, and 24px paragraph
   spacing. In-body subheads are 20px / 1.5 bold.

   Applied to ko / ja / zh report-detail pages only. Figures, tables
   and code blocks keep the wide 880px canvas, the same way the
   benchmark lets visuals bleed beyond the text column.
   ------------------------------------------------------------------ */
html[lang="ko"] .report-detail,
html[lang="ja"] .report-detail,
html[lang="zh"] .report-detail {
    --article-text-w: 616px;
}

/* Text-flow blocks share the narrow, centered text column. */
html[lang="ko"] .report-detail .report-header,
html[lang="ja"] .report-detail .report-header,
html[lang="zh"] .report-detail .report-header,
html[lang="ko"] .report-detail .editors-note,
html[lang="ja"] .report-detail .editors-note,
html[lang="zh"] .report-detail .editors-note,
html[lang="ko"] .report-detail .ai-translation-notice,
html[lang="ja"] .report-detail .ai-translation-notice,
html[lang="zh"] .report-detail .ai-translation-notice,
html[lang="ko"] .report-detail .body > p,
html[lang="ja"] .report-detail .body > p,
html[lang="zh"] .report-detail .body > p,
html[lang="ko"] .report-detail .body > h1,
html[lang="ja"] .report-detail .body > h1,
html[lang="zh"] .report-detail .body > h1,
html[lang="ko"] .report-detail .body > h2,
html[lang="ja"] .report-detail .body > h2,
html[lang="zh"] .report-detail .body > h2,
html[lang="ko"] .report-detail .body > h3,
html[lang="ja"] .report-detail .body > h3,
html[lang="zh"] .report-detail .body > h3,
html[lang="ko"] .report-detail .body > h4,
html[lang="ja"] .report-detail .body > h4,
html[lang="zh"] .report-detail .body > h4,
html[lang="ko"] .report-detail .body > ul,
html[lang="ja"] .report-detail .body > ul,
html[lang="zh"] .report-detail .body > ul,
html[lang="ko"] .report-detail .body > ol,
html[lang="ja"] .report-detail .body > ol,
html[lang="zh"] .report-detail .body > ol,
html[lang="ko"] .report-detail .body > blockquote,
html[lang="ja"] .report-detail .body > blockquote,
html[lang="zh"] .report-detail .body > blockquote {
    max-width: var(--article-text-w);
    margin-left: auto;
    margin-right: auto;
}

/* Article title, matching the chosun.com headline measurement:
   38px Noto Sans (KR / SC / JP) bold. Fluid below the 38px cap so
   long EAI titles don't overwhelm narrow viewports. Specificity
   beats the universal `html h1` Nanum Gothic rule. */
html[lang="ko"] .report-detail .report-header h1,
html[lang="ja"] .report-detail .report-header h1,
html[lang="zh"] .report-detail .report-header h1 {
    font-weight: 700;
    font-size: min(calc(26px + 1vw), 38px);
    line-height: 1.3;
    letter-spacing: -0.5px;
}
html[lang="ko"] .report-detail .report-header h1 {
    font-family: "Noto Sans KR", "Apple SD Gothic Neo", "Noto Sans CJK KR",
                 -apple-system, BlinkMacSystemFont, sans-serif;
}
html[lang="zh"] .report-detail .report-header h1 {
    font-family: "Noto Sans SC", "PingFang SC", "Microsoft YaHei",
                 -apple-system, BlinkMacSystemFont, sans-serif;
}
html[lang="ja"] .report-detail .report-header h1 {
    font-family: "Noto Sans JP", "Hiragino Kaku Gothic ProN", "Yu Gothic",
                 "Meiryo", -apple-system, BlinkMacSystemFont, sans-serif;
}

/* Body face: 18px / 1.74 / -0.5px, justified, break-all. */
html[lang="ko"] .report-detail .body,
html[lang="ja"] .report-detail .body,
html[lang="zh"] .report-detail .body {
    font-size: 18px;
    line-height: 1.74;
    letter-spacing: -0.5px;
    text-align: justify;
    word-break: break-all;
}
html[lang="ko"] .report-detail .body p,
html[lang="ja"] .report-detail .body p,
html[lang="zh"] .report-detail .body p {
    margin-bottom: 24px;
}

/* In-body subheads: 20px / 1.5 bold, same -0.5px tracking. */
html[lang="ko"] .report-detail .body h1,
html[lang="ja"] .report-detail .body h1,
html[lang="zh"] .report-detail .body h1,
html[lang="ko"] .report-detail .body h2,
html[lang="ja"] .report-detail .body h2,
html[lang="zh"] .report-detail .body h2,
html[lang="ko"] .report-detail .body h3,
html[lang="ja"] .report-detail .body h3,
html[lang="zh"] .report-detail .body h3,
html[lang="ko"] .report-detail .body h4,
html[lang="ja"] .report-detail .body h4,
html[lang="zh"] .report-detail .body h4 {
    font-size: 20px;
    line-height: 1.5;
    letter-spacing: -0.5px;
    font-weight: 700;
}

.tabs { margin-top: 28px; display: grid; gap: 8px; }
.tab { background: var(--bg-card); border: 1px solid var(--border); border-radius: 6px; padding: 8px 14px; }
.tab summary { cursor: pointer; font-weight: 600; }
.tab-body { padding-top: 8px; }

.attachments h2 { font-size: 20px; line-height: 1.4; }
.attachments ul { padding-left: 20px; }
.attachments li { margin: 4px 0; }

/* ------------------------------------------------------------------
   Related reports (vector-search "more like this") at body bottom
   ------------------------------------------------------------------ */
.related-reports {
    margin-top: 40px;
    padding-top: 20px;
    border-top: 1px solid var(--border);
}
.related-reports h2 { font-size: 20px; line-height: 1.4; margin-bottom: 12px; }
.related-reports ul { list-style: none; margin: 0; padding: 0; }
.related-report {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
    padding: 10px 0;
    border-bottom: 1px solid var(--border);
}
.related-report:last-child { border-bottom: none; }
.related-report__link { line-height: 1.5; }
.related-report__meta {
    flex-shrink: 0;
    display: flex;
    align-items: baseline;
    gap: 10px;
    white-space: nowrap;
}
.related-report__score {
    font-size: 13px;
    font-variant-numeric: tabular-nums;
    color: var(--accent, #2f6fb0);
    font-weight: 600;
}
.related-report__date {
    color: var(--fg-muted);
    font-size: 14px;
    white-space: nowrap;
}
.related-more { margin-top: 4px; }
.related-more > ul { margin-top: 0; }
.related-more__toggle {
    cursor: pointer;
    list-style: none;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 8px 0;
    color: var(--accent);
    font-size: 15px;
    font-weight: 600;
}
.related-more__toggle::-webkit-details-marker { display: none; }
.related-more__toggle::before {
    content: "▾";
    font-size: 12px;
    transition: transform 0.15s ease;
}
.related-more[open] > .related-more__toggle::before { transform: rotate(180deg); }
.related-more__toggle:hover { text-decoration: underline; }

.not-found { text-align: center; padding: 80px 20px; }
.not-found h1 { font-size: 77px; margin: 0; }

/* ------------------------------------------------------------------
   Floating quick-nav
   ------------------------------------------------------------------
   Shown on long pages (detail view, category list) once the user has
   scrolled past a threshold and *before* hitting the very bottom of
   the page. Desktop: vertical column anchored to the bottom-right
   corner. Mobile: horizontal bar pinned to the bottom of the
   viewport. Buttons use a dark-navy fill at 50% alpha (so background
   content shows through) with crisp white labels; alpha lifts toward
   opaque on hover / focus.
   ------------------------------------------------------------------ */
.floating-nav {
    position: fixed;
    z-index: 90;
    display: flex;
    gap: 8px;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.22s ease, transform 0.22s ease;
}
.floating-nav.is-visible {
    opacity: 1;
    pointer-events: auto;
}

.floating-nav-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 8px 14px;
    border: 1px solid rgba(10, 31, 61, 0.55);
    border-radius: 999px;
    background: rgba(15, 42, 74, 0.5);
    color: #ffffff;
    font-size: 14px;
    line-height: 1.2;
    box-shadow: 0 2px 8px rgba(10, 31, 61, 0.22);
    white-space: nowrap;
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
    transition: background-color 0.18s ease, border-color 0.18s ease;
}
.floating-nav-btn:hover,
.floating-nav-btn:focus-visible {
    background: rgba(31, 79, 139, 0.92);
    border-color: rgba(31, 79, 139, 0.95);
    color: #ffffff;
    text-decoration: none;
    outline: none;
}
.floating-nav-icon {
    font-size: 16px;
    line-height: 1;
    display: inline-block;
    color: #ffffff;
}

/* Desktop: vertical column anchored to the bottom-right corner of the
   viewport. Hidden state slides off-screen to the right. */
@media (min-width: 900px) {
    .floating-nav {
        right: 18px;
        bottom: 18px;
        flex-direction: column;
        transform: translateX(20px);
    }
    .floating-nav.is-visible {
        transform: translateX(0);
    }
    .floating-nav-btn {
        min-width: 104px;
        justify-content: flex-start;
    }
}

/* Mobile / narrow viewport: horizontal bar pinned to the bottom edge.
   Hidden state slides down off-screen. */
@media (max-width: 899px) {
    .floating-nav {
        left: 0;
        right: 0;
        bottom: 0;
        padding: 10px 12px calc(env(safe-area-inset-bottom, 0px) + 10px);
        flex-direction: row;
        justify-content: space-around;
        gap: 8px;
        transform: translateY(24px);
    }
    .floating-nav.is-visible {
        transform: translateY(0);
    }
    .floating-nav-btn {
        flex: 1 1 0;
        min-width: 0;
        padding: 10px 8px;
        font-size: 14px;
    }
}

/* ------------------------------------------------------------------
   Report sticky title bar + stage section nav
   ------------------------------------------------------------------
   Rendered only for generated investigation reports whose body carries
   "N단계: ..." stage headings (server-side detection). Hidden until the
   article <h1> scrolls out of view, then pinned to the top edge.
   Desktop (>=900px): one row -- shrunken title + current-section button;
   clicking the button drops the full table of contents below the row.
   (A horizontal stage menu was tried first but clips once four or more
   stages are selected.)
   Mobile: same widgets stacked on two lines.
   z-index sits above .floating-nav (90) and below the auth modal (1000).
   ------------------------------------------------------------------ */
.report-sticky-bar {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 95;
    /* Pale accent-blue wash so the pinned bar reads as chrome, not as
       part of the (white/near-white) article body behind it. */
    background: rgba(238, 243, 250, 0.97);
    border-bottom: 1px solid #d4dfee;
    box-shadow: 0 2px 10px rgba(10, 31, 61, 0.08);
    backdrop-filter: blur(3px);
    -webkit-backdrop-filter: blur(3px);
    opacity: 0;
    pointer-events: none;
    transform: translateY(-12px);
    transition: opacity 0.2s ease, transform 0.2s ease;
}
.report-sticky-bar.is-visible {
    opacity: 1;
    pointer-events: auto;
    transform: translateY(0);
}
.report-sticky-inner {
    max-width: var(--max-w);
    margin: 0 auto;
    padding: 0 20px;
    /* Two columns: a flexible title column on the left and a fixed-width
       nav column on the right. The current-section button (row 1) and the
       dropdown TOC (row 2) share the right column, so every TOC item lines
       up under the current-section label at a consistent left edge. */
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(240px, 320px);
    align-items: center;
    column-gap: 18px;
    min-height: 44px;
}
.report-sticky-title {
    grid-column: 1;
    grid-row: 1;
    min-width: 0;
    max-width: 100%;
    font-size: 14px;
    font-weight: 700;
    line-height: 1.3;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.report-sticky-current {
    grid-column: 2;
    grid-row: 1;
    justify-self: start;
    min-width: 0;
    max-width: 100%;
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 4px 0;
    border: 0;
    background: none;
    font: inherit;
    font-size: 13px;
    color: var(--accent);
    text-align: left;
    cursor: pointer;
}
.report-sticky-current:hover .report-sticky-current-label,
.report-sticky-current:focus-visible .report-sticky-current-label {
    text-decoration: underline;
}
.report-sticky-current-label {
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.report-sticky-caret {
    flex: 0 0 auto;
    font-size: 11px;
    transition: transform 0.15s ease;
}
.report-sticky-bar.toc-open .report-sticky-caret { transform: rotate(180deg); }
/* The dropdown TOC sits in the right column, under the current-section
   button (grid row 2), so it opens flush to the right edge of the bar. */
.report-sticky-toc {
    grid-column: 2;
    grid-row: 2;
    align-self: start;
    display: block;
    margin: 0;
    padding: 4px 0 10px;
    list-style: none;
    border-top: 1px solid #d4dfee;
    max-height: 60vh;
    overflow-y: auto;
}
.report-sticky-toc[hidden] { display: none; }
.report-sticky-toc li { margin: 0; }
.report-sticky-toc a {
    display: block;
    padding: 9px 4px;
    font-size: 14px;
    color: var(--fg);
    text-decoration: none;
    border-bottom: 1px solid #e3eaf4;
}
.report-sticky-toc li:last-child a { border-bottom: 0; }
.report-sticky-toc a:hover,
.report-sticky-toc a:focus-visible {
    color: var(--accent);
    text-decoration: none;
}
.report-sticky-toc a.is-current {
    color: var(--chip-fg);
    font-weight: 700;
}

/* Clicked nav targets land just below the pinned bar -- and inside the
   scrollspy reading line (max(bar height + 24px, 100px)), so the clicked
   section immediately becomes the highlighted/current one. */
.report-section-anchor { scroll-margin-top: 60px; }

@media (max-width: 899px) {
    /* Narrow viewport: stack title / current / TOC in one full-width
       column instead of the two-column desktop grid. */
    .report-sticky-inner {
        display: block;
        padding: 0 14px;
        min-height: 0;
    }
    .report-sticky-title {
        max-width: none;
        padding: 7px 0 2px;
        font-size: 13px;
    }
    .report-sticky-current {
        max-width: none;
        width: 100%;
        padding: 2px 0 7px;
    }
    .report-section-anchor { scroll-margin-top: 76px; }
}

/* Admin */
.admin-nav {
    margin-left: 8px;
    display: flex;
    align-items: center;
    gap: 6px;
}
.admin-nav-form { margin: 0; display: inline; }
.admin-nav-link {
    border: 1px solid var(--border);
    background: var(--bg-card);
    color: var(--fg-muted);
    cursor: pointer;
    font: inherit;
    line-height: 1;
}
.admin-nav-link:hover { color: var(--accent); }
.admin-page { max-width: 980px; }
.admin-header { margin-bottom: 16px; }
.admin-header h1 { margin: 0 0 4px; font-size: 26px; }
.admin-subtitle { color: var(--fg-muted); font-size: 16px; margin: 0; }
.admin-filter { display: flex; gap: 8px; margin: 14px 0 18px; flex-wrap: wrap; }
.admin-input {
    padding: 6px 10px;
    border: 1px solid var(--border);
    border-radius: 6px;
    font-size: 17px;
    background: var(--bg-card);
    color: var(--fg);
}
.admin-input:focus { outline: 2px solid var(--accent); outline-offset: -1px; }
.admin-btn {
    padding: 6px 14px;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--bg-card);
    cursor: pointer;
    font-size: 17px;
    color: var(--fg);
    text-decoration: none;
    display: inline-block;
}
.admin-btn:hover { text-decoration: none; background: #f3f6fb; }
.admin-btn-primary {
    background: var(--accent); color: #fff; border-color: var(--accent);
}
.admin-btn-primary:hover { background: #173a66; }

.admin-btn.is-loading,
.admin-btn[disabled].is-loading {
    cursor: progress;
    opacity: 0.85;
    background: var(--accent);
    color: #fff;
    border-color: var(--accent);
}
.admin-btn.is-loading::before {
    content: "";
    display: inline-block;
    width: 0.9em;
    height: 0.9em;
    margin-right: 0.55em;
    vertical-align: -0.12em;
    border: 2px solid currentColor;
    border-top-color: transparent;
    border-radius: 50%;
    animation: admin-btn-spin 0.7s linear infinite;
}
@keyframes admin-btn-spin {
    to { transform: rotate(360deg); }
}
.admin-link { color: var(--accent); font-size: 16px; }
.admin-muted { color: var(--fg-muted); font-size: 16px; }
.admin-empty { color: var(--fg-muted); font-style: italic; }

.admin-table {
    width: 100%;
    border-collapse: collapse;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 6px;
    overflow: hidden;
}
.admin-table th, .admin-table td {
    text-align: left;
    padding: 8px 12px;
    border-bottom: 1px solid var(--border);
    font-size: 17px;
    vertical-align: middle;
}
.admin-table th { background: var(--chip-subtle-bg); font-weight: 600; }
.admin-table tr:last-child td { border-bottom: none; }

.admin-pill {
    display: inline-block;
    padding: 1px 8px;
    border-radius: 999px;
    font-size: 13px;
    background: var(--chip-subtle-bg);
    color: var(--chip-subtle-fg);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.admin-pill-pending { background: #fff3cd; color: #856404; }
/* Nav-keyword curation table (drag & drop reorder). */
.nav-kw-table tr[draggable="true"] { cursor: default; }
.nav-kw-drag {
    cursor: grab;
    color: var(--fg-muted);
    text-align: center;
    user-select: none;
}
.nav-kw-row.is-dragging { opacity: 0.45; }
.nav-kw-row.is-hidden-admin td { opacity: 0.55; }
.admin-pill-auto { background: #e0e7ff; color: #2638b8; }
.admin-pill-reviewed { background: #d4edda; color: #155724; }
.admin-pill-resolved { background: #d4edda; color: #155724; }
.admin-pill-ambiguous { background: #f8d7da; color: #721c24; }
.admin-pill-missing { background: #f1f1f1; color: #555; }

.admin-pager {
    display: flex; gap: 14px; margin-top: 16px; align-items: center;
}

/* Single explicit column (minmax(0, 1fr)) forces every .admin-fieldset
   card to stretch to the full main-column width; without it the implicit
   ``grid-auto-columns: auto`` sizes the column to fit each card's
   content, so cards with short inputs (meta / editor's note / image
   caption / empty tabs) render narrower than the body_html card with
   its tall textarea. */
.admin-form { display: grid; gap: 18px; grid-template-columns: minmax(0, 1fr); }
.admin-fieldset {
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 14px 18px;
    background: var(--bg-card);
    min-width: 0;
}
.admin-fieldset legend { font-weight: 600; padding: 0 6px; color: var(--fg-muted); font-size: 16px; }
.admin-field {
    display: grid;
    grid-template-columns: 160px 1fr;
    align-items: start;
    gap: 12px;
    margin: 8px 0;
}
.admin-field > span { padding-top: 6px; font-size: 17px; color: var(--fg-muted); }
.admin-field input[type="text"], .admin-field select, .admin-field textarea {
    width: 100%;
    padding: 6px 10px;
    border: 1px solid var(--border);
    border-radius: 6px;
    font: inherit;
    background: var(--bg-card);
    color: var(--fg);
}
.admin-field textarea { resize: vertical; min-height: 60px; font-family: inherit; }
/* Hint copy that lives inside an .admin-field grid (160px label + 1fr
   input). Force it into the second column so it aligns flush under
   the input and doesn't drift into the label gutter. ``code`` inside
   the hint inherits the muted color but bumps to a monospace font so
   sample outputs (e.g. ホン・ギルドン) stand out. */
.admin-field .admin-hint {
    grid-column: 2;
    margin-top: 4px;
    color: var(--fg-muted);
    font-size: 13px;
    line-height: 1.5;
}
.admin-field .admin-hint code {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 12.5px;
    padding: 0 4px;
    background: rgba(0, 0, 0, 0.04);
    border-radius: 3px;
}
.admin-actions { display: flex; gap: 14px; align-items: center; }

.admin-slot {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 14px 18px;
    margin: 14px 0;
}
.admin-slot-head { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }
.admin-slot-head h2 { margin: 0; font-size: 19px; }
.admin-candidates { margin: 12px 0; }
.admin-candidate-list { list-style: none; padding: 0; margin: 8px 0; display: grid; gap: 6px; }
.admin-candidate-list label { display: block; padding: 6px 8px; border: 1px solid var(--border); border-radius: 6px; cursor: pointer; }
.admin-candidate-list label:hover { background: #f6f8fb; }
.admin-inline-form { display: flex; gap: 8px; margin-top: 8px; flex-wrap: wrap; }

/* Featured visualization picker (admin report edit, source language).
   Radio cards: thumbnail + index label, selected card gets an accent
   border so the active diagram is obvious at a glance. */
.admin-featured-viz .admin-field--inline {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 8px 0 4px;
}
.admin-viz-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 12px;
    margin: 12px 0 4px;
}
.admin-viz-option {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 10px;
    border: 2px solid var(--border);
    border-radius: 8px;
    cursor: pointer;
    background: var(--bg-card);
}
.admin-viz-option:hover { border-color: var(--fg-muted); }
.admin-viz-option input[type="radio"] {
    position: absolute;
    top: 10px;
    left: 10px;
}
.admin-viz-option img {
    width: 100%;
    height: 140px;
    object-fit: contain;
    background: #fff;
    border-radius: 4px;
}
.admin-viz-option-label { font-size: 14px; color: var(--fg-muted); text-align: center; }
.admin-viz-option:has(input:checked) {
    border-color: var(--accent, #2563eb);
    box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.15);
}

.flash { padding: 8px 14px; border-radius: 6px; margin: 8px 0; font-size: 17px; }
.flash-ok { background: #d4edda; color: #155724; }
.flash-error { background: #f8d7da; color: #721c24; }
.flash-message { background: var(--chip-subtle-bg); color: var(--fg); }

/* Homepage: search bar (slim editorial strip between the viz band and
   the section grid). */
.home-search {
    margin: 0 0 30px;
}
.home-search-form {
    display: flex;
    align-items: stretch;
    gap: 10px;
    flex-wrap: wrap;
    background: transparent;
    border-top: 1px solid var(--home-rule);
    border-bottom: 1px solid var(--home-rule);
    padding: 14px 0;
}
.home-search-input {
    flex: 1 1 280px;
    min-width: 0;
    padding: 11px 14px;
    border: 1px solid var(--fg);
    border-radius: 0;
    background: #fff;
    font: inherit;
    font-size: 17px;
    color: inherit;
}
.home-search-input:focus {
    outline: none;
    border-color: var(--home-accent);
    box-shadow: 0 0 0 1px var(--home-accent);
}
.home-search-submit {
    padding: 0 26px;
    border: 1px solid var(--fg);
    border-radius: 0;
    background: var(--fg);
    color: #fff;
    font: inherit;
    font-size: 15px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    cursor: pointer;
    white-space: nowrap;
    transition: background-color 0.12s ease, border-color 0.12s ease;
}
.home-search-submit:hover {
    background: var(--home-accent);
    border-color: var(--home-accent);
}

/* Homepage search: mode dropdown + natural-language textarea */
.home-search-mode {
    flex: 0 0 auto;
    align-self: center;
    padding: 11px 12px;
    border: 1px solid var(--fg);
    border-radius: 0;
    background: #fff;
    font: inherit;
    font-size: 15px;
    color: inherit;
    cursor: pointer;
}
.home-search-mode:focus {
    outline: none;
    border-color: var(--home-accent);
    box-shadow: 0 0 0 1px var(--home-accent);
}
.home-search-textarea {
    flex: 1 1 100%;
    min-width: 0;
    padding: 11px 14px;
    border: 1px solid var(--fg);
    border-radius: 0;
    background: #fff;
    font: inherit;
    font-size: 17px;
    line-height: 1.5;
    color: inherit;
    resize: vertical;
}
.home-search-textarea:focus {
    outline: none;
    border-color: var(--home-accent);
    box-shadow: 0 0 0 1px var(--home-accent);
}
/* Generic toggle used by the homepage search mode switch. */
.is-hidden { display: none !important; }

@media (max-width: 480px) {
    .home-search-form { padding: 10px 0; gap: 8px; }
    .home-search-input { font-size: 16px; padding: 10px 12px; }
    .home-search-submit { padding: 10px 16px; font-size: 16px; }
    .home-search-mode { width: 100%; flex: 1 1 100%; }
    .home-search-textarea { font-size: 16px; padding: 10px 12px; }
}

/* Vector search results page: full-width natural-language textarea form */
.list-search--vector { align-items: stretch; }
.list-search-textarea {
    flex: 1 1 100%;
    min-width: 0;
    padding: 8px 12px;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--bg-card);
    font: inherit;
    font-size: 16px;
    line-height: 1.5;
    color: inherit;
    resize: vertical;
}
.list-search-textarea:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 2px rgba(0, 102, 204, 0.15);
}
.list-search-summary--notice {
    padding: 10px 14px;
    border: 1px solid var(--notice-border);
    border-radius: 8px;
    background: var(--notice-bg);
    color: #6b5800;
}

/* Similarity badge on vector search result rows */
.chip-similarity {
    background: var(--accent);
    color: #fff;
    font-weight: 600;
}

/* Homepage: view-mode tabs (category | project) — editorial text tabs
   on a hairline rule, active tab underlined in the accent crimson. */
.home-view-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 26px;
    margin: 0 0 26px;
    border-top: 2px solid var(--fg);
    border-bottom: 1px solid var(--home-rule);
    padding: 10px 0;
}
.home-view-tab {
    padding: 2px 0;
    border-bottom: 3px solid transparent;
    color: var(--fg-muted);
    font-size: 16px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    line-height: 1.4;
    text-decoration: none;
    transition: border-color 0.12s ease, color 0.12s ease;
}
.home-view-tab:hover {
    text-decoration: none;
    color: var(--home-accent);
}
.home-view-tab.is-active {
    color: var(--fg);
    border-bottom-color: var(--home-accent);
}
.home-view-tab.is-active:hover { color: var(--fg); }

/* Bottom band title ("EAI REPORTS") sitting where the view tabs used
   to be: same hairline framing as .home-view-tabs, rendered as a
   section heading rather than a row of links. */
.home-reports-heading {
    margin: 0 0 26px;
    border-top: 2px solid var(--fg);
    border-bottom: 1px solid var(--home-rule);
    padding: 12px 0;
    font-size: 18px;
    font-weight: 800;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    line-height: 1.3;
    color: var(--home-accent);
}

/* ------------------------------------------------------------------
   Homepage editorial chrome (Foreign Affairs benchmark)
   ------------------------------------------------------------------
   Section "kickers": small uppercase crimson labels sitting on a
   hairline rule, shared by every homepage band. */
.home-kicker {
    margin: 0 0 18px;
    padding-top: 10px;
    border-top: 2px solid var(--fg);
    font-size: 15px;
    font-weight: 800;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--home-accent);
}
.home-kicker--band {
    border-top-color: var(--home-accent);
}

/* Nav-keyword results page: centered "more" button under the bands. */
.keyword-watch-more {
    display: flex;
    justify-content: center;
    margin: 32px 0 12px;
}

/* "EAI CURRENT WATCH" heading matches the "EAI REPORTS" band size. */
#current-watch-heading.home-kicker {
    font-size: 18px;
}

/* Homepage canvas: paper-white, typography-led. */
body.home { background: #fff; }
body.home .site-main { padding-top: 20px; }

/* Headline serif face for the homepage editorial bands. The `html`
   prefix outranks the global Nanum Gothic heading rule. */
html body.home .current-watch__title,
html body.home .current-watch__list-title,
html body.home .current-watch__sub-title,
html body.home .cat-item-title {
    font-family: var(--home-serif);
}

/* World Issue Today titles use Nanum Gothic across every language
   (the `html[lang]` selectors below outrank the per-lang Noto Sans
   rules used by the article headlines). */
html body.home .world-issue__item-title,
html[lang="ko"] body.home .world-issue__item-title,
html[lang="zh"] body.home .world-issue__item-title,
html[lang="ja"] body.home .world-issue__item-title {
    font-family: "Nanum Gothic", -apple-system, BlinkMacSystemFont,
                 "Apple SD Gothic Neo", "Noto Sans CJK KR",
                 "PingFang SC", "Hiragino Kaku Gothic ProN",
                 "Segoe UI", "Helvetica Neue", Arial, sans-serif;
}

/* ko / zh / ja: homepage section kickers use Nanum Gothic instead of
   the serif display face. The [lang] attribute selector outranks the
   serif rule above. */
html[lang="ko"] body.home .home-kicker,
html[lang="zh"] body.home .home-kicker,
html[lang="ja"] body.home .home-kicker {
    font-family: "Nanum Gothic", -apple-system, BlinkMacSystemFont,
                 "Apple SD Gothic Neo", "Noto Sans CJK KR",
                 "PingFang SC", "Hiragino Kaku Gothic ProN",
                 "Segoe UI", "Helvetica Neue", Arial, sans-serif;
}

/* ko / zh / ja: homepage titles (Current Watch headlines + bottom
   category band) use the same Noto Sans bold face as the
   report-detail article titles. */
html[lang="ko"] body.home .current-watch__title,
html[lang="ko"] body.home .current-watch__list-title,
html[lang="ko"] body.home .current-watch__sub-title,
html[lang="ko"] body.home .cat-title,
html[lang="ko"] body.home .cat-item-title,
html[lang="zh"] body.home .current-watch__title,
html[lang="zh"] body.home .current-watch__list-title,
html[lang="zh"] body.home .current-watch__sub-title,
html[lang="zh"] body.home .cat-title,
html[lang="zh"] body.home .cat-item-title,
html[lang="ja"] body.home .current-watch__title,
html[lang="ja"] body.home .current-watch__list-title,
html[lang="ja"] body.home .current-watch__sub-title,
html[lang="ja"] body.home .cat-title,
html[lang="ja"] body.home .cat-item-title {
    font-weight: 700;
}
html[lang="ko"] body.home .current-watch__title,
html[lang="ko"] body.home .current-watch__list-title,
html[lang="ko"] body.home .current-watch__sub-title,
html[lang="ko"] body.home .cat-title,
html[lang="ko"] body.home .cat-item-title {
    font-family: "Noto Sans KR", "Apple SD Gothic Neo", "Noto Sans CJK KR",
                 -apple-system, BlinkMacSystemFont, sans-serif;
}
html[lang="zh"] body.home .current-watch__title,
html[lang="zh"] body.home .current-watch__list-title,
html[lang="zh"] body.home .current-watch__sub-title,
html[lang="zh"] body.home .cat-title,
html[lang="zh"] body.home .cat-item-title {
    font-family: "Noto Sans SC", "PingFang SC", "Microsoft YaHei",
                 -apple-system, BlinkMacSystemFont, sans-serif;
}
html[lang="ja"] body.home .current-watch__title,
html[lang="ja"] body.home .current-watch__list-title,
html[lang="ja"] body.home .current-watch__sub-title,
html[lang="ja"] body.home .cat-title,
html[lang="ja"] body.home .cat-item-title {
    font-family: "Noto Sans JP", "Hiragino Kaku Gothic ProN", "Yu Gothic",
                 "Meiryo", -apple-system, BlinkMacSystemFont, sans-serif;
}

/* Japanese refinement: the wide Latin-oriented letter-spacing of the
   kicker labels exaggerates CJK glyphs, so tighten label tracking. */
html[lang="ja"] body.home .home-kicker,
html[lang="ja"] body.home .cat-title {
    letter-spacing: 0.05em;
}
html[lang="ja"] body.home .current-watch__authors,
html[lang="ja"] body.home .current-watch__list-authors,
html[lang="ja"] body.home .viz-card__authors,
html[lang="ja"] body.home .cat-item-authors {
    font-weight: 500;
    letter-spacing: 0.02em;
}

/* Homepage: top "EAI Current Watch" hero band */
.current-watch {
    margin: 0 0 36px;
    min-height: 120px;
}

/* Lead story (left, 2fr) + headline list (right rail, 1fr) separated
   by a vertical hairline, mirroring the FA front-page top band. */
.current-watch__layout {
    display: grid;
    grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
    gap: 0 32px;
    align-items: start;
}

/* Left column wrapper: the lead hero stacked above the 2-card subtop
   row, separated from the right rail by a vertical hairline. */
.current-watch__main {
    display: flex;
    flex-direction: column;
    gap: 24px;
    min-width: 0;
    padding-right: 32px;
    border-right: 1px solid var(--home-rule);
}

.current-watch__hero {
    display: flex;
    flex-direction: column;
    gap: 16px;
    align-items: stretch;
    color: inherit;
    text-decoration: none;
}
.current-watch__hero:hover {
    text-decoration: none;
}
.current-watch__hero:hover .current-watch__title {
    color: var(--home-accent);
}
/* Admin-only dim for published-but-not-yet-translated current_watch
   rows. Signals that the row is live in its source language but the
   translation for the active UI language is still being generated. */
.current-watch__hero.is-pending-translation {
    opacity: 0.85;
}

.current-watch__thumb-wrap {
    width: 100%;
    aspect-ratio: 16 / 9;
    overflow: hidden;
    background: var(--chip-subtle-bg);
}
.current-watch__thumb {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
.current-watch__thumb.cat-item-thumb--fallback {
    object-fit: contain;
    background: #fff;
    padding: 18px;
}

.current-watch__body {
    display: flex;
    flex-direction: column;
    gap: 10px;
    min-width: 0;
}
.current-watch__title {
    margin: 0;
    font-size: 34px;
    font-weight: 700;
    line-height: 1.28;
    color: var(--fg);
}
.current-watch__title.fallback {
    color: var(--fg-muted);
    font-style: italic;
}
.current-watch__authors {
    margin: 0;
    font-size: 15px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    line-height: 1.4;
    color: var(--fg);
}
.current-watch__date {
    font-size: 14px;
    color: var(--fg-muted);
    font-variant-numeric: tabular-nums;
}
.current-watch__summary {
    margin: 0;
    font-size: 17px;
    line-height: 1.6;
    color: var(--fg-muted);
}

/* Subtop row: two smaller cards beneath the hero, each mirroring the
   hero's thumbnail + title + authors + date pattern at a reduced
   scale. */
.current-watch__subtop {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 24px;
    padding-top: 22px;
    border-top: 1px solid var(--home-rule);
}
.current-watch__sub {
    display: flex;
    flex-direction: column;
    gap: 12px;
    min-width: 0;
    color: inherit;
    text-decoration: none;
}
.current-watch__sub:hover {
    text-decoration: none;
}
.current-watch__sub:hover .current-watch__sub-title {
    color: var(--home-accent);
}
.current-watch__sub.is-pending-translation {
    opacity: 0.85;
}
.current-watch__sub-body {
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-width: 0;
}
.current-watch__sub-title {
    color: var(--fg);
    font-size: 18px;
    font-weight: 700;
    line-height: 1.28;
}
.current-watch__sub-title.fallback {
    color: var(--fg-muted);
    font-style: italic;
}
.current-watch__sub-authors {
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--fg-muted);
    line-height: 1.35;
    overflow-wrap: anywhere;
    word-break: break-word;
}
.current-watch__sub-date {
    font-size: 13px;
    color: var(--fg-muted);
    font-variant-numeric: tabular-nums;
}

/* Pending-translation tag: admin-only, signals that the row is
   published but its translation for the active UI language hasn't
   landed yet. Warm-amber palette so it reads as a transient "in
   progress" state. Anonymous visitors never see this state because
   the server filters such rows out of their result set. */
.current-watch__pending-tag {
    align-self: flex-start;
    display: inline-block;
    padding: 2px 8px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.05em;
    background: #fff3d6;
    color: #8a5a00;
}
.current-watch__pending-tag--small {
    font-size: 10px;
    padding: 1px 6px;
}

/* Right rail: text-only headline list with hairline separators
   (FA-style secondary stories). */
.current-watch__list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
}
.current-watch__list-item {
    margin: 0;
    border-bottom: 1px solid var(--home-rule);
}
.current-watch__list-item:last-child { border-bottom: none; }
.current-watch__list-item.is-pending-translation {
    opacity: 0.85;
}
.current-watch__list-link {
    display: block;
    padding: 14px 0;
    color: inherit;
}
.current-watch__list-link:hover {
    text-decoration: none;
}
.current-watch__list-link:hover .current-watch__list-title {
    color: var(--home-accent);
}
.current-watch__list-text {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.current-watch__list-title {
    color: var(--fg);
    font-size: 19px;
    font-weight: 600;
    line-height: 1.35;
}
.current-watch__list-title.fallback {
    color: var(--fg-muted);
    font-style: italic;
}
.current-watch__list-authors {
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--fg-muted);
    line-height: 1.35;
    overflow-wrap: anywhere;
    word-break: break-word;
}
.current-watch__list-date {
    font-size: 13px;
    color: var(--fg-muted);
    font-variant-numeric: tabular-nums;
}

/* World Issue Today: a tabbed view of the latest global-situation scan
   inside the right rail. The heading reuses the .home-kicker treatment
   (top rule + uppercase accent) so it reads like the other homepage
   section titles; the issue list sits in a bordered, lightly tinted box
   matching the other boxed areas. */
.current-watch__world-item {
    padding: 18px 0 4px;
}
.world-issue {
    display: block;
}
.world-issue__title.home-kicker {
    margin: 0 0 12px;
}
.world-issue__date {
    margin-left: 8px;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0;
    text-transform: none;
    color: var(--fg-muted);
    font-variant-numeric: tabular-nums;
}
/* Category toggle (기업 리스크 / 국제 정세): two wide pills whose active
   background matches the issue panel background of their group, so the
   selected button and the box below read as one surface. */
.world-issue__cats {
    display: flex;
    gap: 8px;
    margin-bottom: 10px;
}
/* One-line tagline between the category toggle and the issue panel. */
.world-issue__tagline {
    margin: 0 0 10px;
    font-size: 12px;
    line-height: 1.5;
    color: var(--fg-muted);
    text-align: center;
}
.world-issue__cat {
    appearance: none;
    flex: 1 1 0;
    min-width: 0;
    border: 1px solid var(--home-rule);
    background: #fff;
    color: var(--fg-muted);
    font: inherit;
    font-size: 13px;
    font-weight: 700;
    line-height: 1.2;
    padding: 7px 12px;
    border-radius: 999px;
    cursor: pointer;
    text-align: center;
    white-space: nowrap;
    transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.world-issue__cat:hover {
    color: var(--fg);
    border-color: var(--fg-muted);
}
.world-issue__cat--corporate.is-active {
    background: #e9d5d8;
    border-color: #d3aeb4;
    color: var(--home-accent);
}
.world-issue__cat--political.is-active {
    background: var(--chip-subtle-bg);
    border-color: var(--home-rule);
    color: var(--fg);
}
/* 기업 리스크 group: rose-tinted panel matching its active button; the
   국제 정세 group keeps the default neutral panel tint. */
.world-issue__group--corporate .world-issue__panel {
    background: #e9d5d8;
    border-color: #d3aeb4;
}
.world-issue__group--corporate .world-issue__item {
    border-bottom-color: #d3aeb4;
}
.world-issue__group[hidden] { display: none; }
.world-issue__tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-bottom: 10px;
}
.world-issue__tab {
    appearance: none;
    border: 1px solid var(--home-rule);
    background: #fff;
    color: var(--fg-muted);
    font: inherit;
    font-size: 12px;
    font-weight: 700;
    line-height: 1.2;
    padding: 5px 10px;
    border-radius: 999px;
    cursor: pointer;
    white-space: nowrap;
    transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.world-issue__tab:hover {
    color: var(--fg);
    border-color: var(--fg-muted);
}
.world-issue__tab.is-active {
    background: var(--home-accent);
    border-color: var(--home-accent);
    color: #fff;
}
.world-issue__panel {
    list-style: none;
    margin: 0;
    padding: 14px 16px;
    border: 1px solid var(--home-rule);
    background: var(--chip-subtle-bg);
    counter-reset: world-issue;
}
.world-issue__panel[hidden] { display: none; }
.world-issue__item {
    padding: 7px 0;
    border-bottom: 1px solid var(--home-rule);
}
.world-issue__item:first-child { padding-top: 0; }
.world-issue__item:last-child { padding-bottom: 0; border-bottom: none; }
.world-issue__item-body {
    position: relative;
    min-width: 0;
}
/* Hanging-indent bullet: the dot is an inline ::before on the title so
   ``vertical-align: middle`` centers it on the text glyphs (not the
   line box), and padding-left + negative text-indent keep wrapped lines
   aligned under the first character. */
.world-issue__item-title {
    display: block;
    color: var(--fg);
    font-size: 15px;
    font-weight: 400;
    line-height: 1.4;
    padding-left: 13px;
    text-indent: -13px;
    word-break: keep-all;
}
/* zh / ja have no inter-word spaces, so keep-all would overflow; let
   those scripts wrap normally. */
html[lang="zh"] body.home .world-issue__item-title,
html[lang="ja"] body.home .world-issue__item-title {
    word-break: normal;
}
.world-issue__item-title::before {
    content: "";
    display: inline-block;
    width: 5px;
    height: 5px;
    margin-right: 8px;
    border-radius: 50%;
    background: var(--home-accent);
    vertical-align: middle;
}
.world-issue__item-title[tabindex] {
    cursor: help;
    outline: none;
}
.world-issue__item-title[tabindex]:hover,
.world-issue__item-title[tabindex]:focus-visible {
    color: var(--home-accent);
}
/* Issues that already have a published report render as a link with a
   report icon in place of the bullet dot. The hanging indent widens to
   the icon width (12px + 5px gap) so wrapped lines still align. */
.world-issue__item-title--report {
    padding-left: 17px;
    text-indent: -17px;
    text-decoration: none;
}
.world-issue__item-title--report::before { content: none; }
.world-issue__report-icon {
    width: 12px;
    height: 12px;
    margin-right: 5px;
    color: var(--home-accent);
    vertical-align: middle;
}
.world-issue__item-title--report:hover,
.world-issue__item-title--report:focus-visible {
    color: var(--home-accent);
    text-decoration: underline;
}

/* Detail text shown only on hover/focus of the title, as a popover so
   the resting list stays title-only. */
.world-issue__tooltip {
    position: absolute;
    left: 0;
    top: calc(100% + 6px);
    z-index: 30;
    width: max-content;
    max-width: min(300px, 100%);
    padding: 10px 12px;
    background: var(--fg);
    color: #fff;
    font-size: 13px;
    font-weight: 400;
    line-height: 1.6;
    border-radius: 6px;
    box-shadow: 0 10px 28px rgba(0, 0, 0, 0.22);
    opacity: 0;
    visibility: hidden;
    transform: translateY(-4px);
    transition: opacity 0.15s ease, transform 0.15s ease, visibility 0.15s;
    pointer-events: none;
}
.world-issue__item-body:hover .world-issue__tooltip,
.world-issue__item-body:focus-within .world-issue__tooltip {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
}
/* Report-linked issues get a "report available" notice instead of the
   summary; the accent background sets it apart from summary tooltips. */
.world-issue__tooltip--report {
    background: var(--home-accent);
}
.world-issue__box {
    padding: 14px 16px;
    border: 1px solid var(--home-rule);
    background: var(--chip-subtle-bg);
}
.world-issue__empty {
    margin: 0;
    font-size: 14px;
    color: var(--fg-muted);
}
.current-watch__empty {
    margin: 8px 0 0;
    color: var(--fg-muted);
    font-size: 15px;
}

/* en / fr / es / ru: these languages produce longer headlines and
   World Issue entries than the CJK/Korean source, so the right rail
   (headline list + World Issue Today) overruns the left hero column
   and leaves a large gap. Shrink the right-rail type for just these
   languages to rebalance the two columns' heights. */
html[lang="en"] body.home .current-watch__list-title,
html[lang="fr"] body.home .current-watch__list-title,
html[lang="es"] body.home .current-watch__list-title,
html[lang="ru"] body.home .current-watch__list-title {
    font-size: 16px;
    line-height: 1.3;
}
html[lang="en"] body.home .current-watch__list-authors,
html[lang="fr"] body.home .current-watch__list-authors,
html[lang="es"] body.home .current-watch__list-authors,
html[lang="ru"] body.home .current-watch__list-authors,
html[lang="en"] body.home .current-watch__list-date,
html[lang="fr"] body.home .current-watch__list-date,
html[lang="es"] body.home .current-watch__list-date,
html[lang="ru"] body.home .current-watch__list-date {
    font-size: 12px;
}
html[lang="en"] body.home .world-issue__item-title,
html[lang="fr"] body.home .world-issue__item-title,
html[lang="es"] body.home .world-issue__item-title,
html[lang="ru"] body.home .world-issue__item-title {
    font-size: 13px;
    line-height: 1.35;
}
html[lang="en"] body.home .world-issue__tab,
html[lang="fr"] body.home .world-issue__tab,
html[lang="es"] body.home .world-issue__tab,
html[lang="ru"] body.home .world-issue__tab {
    font-size: 11px;
}
html[lang="en"] body.home .world-issue__cat,
html[lang="fr"] body.home .world-issue__cat,
html[lang="es"] body.home .world-issue__cat,
html[lang="ru"] body.home .world-issue__cat {
    font-size: 12px;
}
/* Tighten the right-rail vertical rhythm too: font shrink alone still
   leaves the rail roughly one headline taller than the left column for
   these languages, so trim the per-row padding to claw that back. */
html[lang="en"] body.home .current-watch__list-link,
html[lang="fr"] body.home .current-watch__list-link,
html[lang="es"] body.home .current-watch__list-link,
html[lang="ru"] body.home .current-watch__list-link {
    padding: 10px 0;
}
html[lang="en"] body.home .current-watch__list-text,
html[lang="fr"] body.home .current-watch__list-text,
html[lang="es"] body.home .current-watch__list-text,
html[lang="ru"] body.home .current-watch__list-text {
    gap: 2px;
}
html[lang="en"] body.home .current-watch__world-item,
html[lang="fr"] body.home .current-watch__world-item,
html[lang="es"] body.home .current-watch__world-item,
html[lang="ru"] body.home .current-watch__world-item {
    padding: 12px 0 4px;
}
html[lang="en"] body.home .world-issue__panel,
html[lang="fr"] body.home .world-issue__panel,
html[lang="es"] body.home .world-issue__panel,
html[lang="ru"] body.home .world-issue__panel {
    padding: 10px 14px;
}
html[lang="en"] body.home .world-issue__item,
html[lang="fr"] body.home .world-issue__item,
html[lang="es"] body.home .world-issue__item,
html[lang="ru"] body.home .world-issue__item {
    padding: 5px 0;
}

@media (max-width: 880px) {
    .current-watch__layout {
        grid-template-columns: 1fr;
        gap: 8px;
    }
    .current-watch__main {
        padding-right: 0;
        border-right: none;
        padding-bottom: 18px;
        border-bottom: 1px solid var(--home-rule);
    }
    .current-watch__subtop {
        grid-template-columns: 1fr;
        gap: 18px;
    }
    .current-watch__title { font-size: 26px; }
}

/* ------------------------------------------------------------------
   Featured visualization band: full-bleed tinted strip showing two
   admin-selected in-body diagrams at a time; with more, the track
   auto-flows left one card at a time.
   ------------------------------------------------------------------ */
.viz-band {
    /* Full-bleed: escape the centered .site-main column. */
    width: 100vw;
    margin-left: calc(50% - 50vw);
    margin-bottom: 36px;
    background: var(--home-band-bg);
    border-top: 1px solid var(--home-rule);
    border-bottom: 1px solid var(--home-rule);
    padding: 26px 20px 30px;
}
.viz-band .home-kicker {
    max-width: var(--home-max-w);
    margin-left: auto;
    margin-right: auto;
}
.viz-carousel {
    position: relative;
    max-width: var(--home-max-w);
    margin: 0 auto;
}
.viz-carousel__viewport {
    overflow: hidden;
}
.viz-carousel__track {
    display: flex;
    transition: transform 0.6s ease;
    will-change: transform;
}
.viz-carousel__track.no-transition { transition: none; }
.viz-card {
    flex: 0 0 50%;
    min-width: 0;
    box-sizing: border-box;
    padding: 0 14px;
    display: flex;
    flex-direction: column;
    gap: 12px;
    color: inherit;
    text-decoration: none;
}
.viz-card:hover { text-decoration: none; }
.viz-card:hover .viz-card__authors { color: var(--home-accent); }
.viz-carousel--single .viz-card { margin: 0 auto; }
.viz-card__image-wrap {
    background: #fff;
    border: 1px solid var(--home-rule);
    padding: 12px;
}
.viz-card__image-wrap img {
    display: block;
    width: 100%;
    height: 460px;
    object-fit: contain;
}
.viz-card__meta {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    min-width: 0;
    text-align: center;
}
.viz-card__authors {
    font-size: 14px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--fg);
}
.viz-card__date {
    font-size: 14px;
    color: var(--fg-muted);
    font-variant-numeric: tabular-nums;
}

/* Prev/next chevrons + dot pager */
.viz-carousel__nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 40px;
    height: 40px;
    border: 1px solid var(--home-rule);
    border-radius: 999px;
    background: #fff;
    color: var(--fg);
    font-size: 24px;
    line-height: 1;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: color 0.12s ease, border-color 0.12s ease;
}
.viz-carousel__nav:hover {
    color: var(--home-accent);
    border-color: var(--home-accent);
}
.viz-carousel__nav--prev { left: -8px; }
.viz-carousel__nav--next { right: -8px; }
.viz-carousel__dots {
    display: flex;
    justify-content: center;
    gap: 8px;
    margin-top: 18px;
}
.viz-carousel__dot {
    width: 9px;
    height: 9px;
    padding: 0;
    border: 1px solid var(--fg-muted);
    border-radius: 999px;
    background: transparent;
    cursor: pointer;
}
.viz-carousel__dot.is-active {
    background: var(--home-accent);
    border-color: var(--home-accent);
}

@media (max-width: 880px) {
    .viz-card {
        flex-basis: 100%;
        padding: 0;
    }
    .viz-card__image-wrap img { height: 300px; }
    .viz-carousel__nav { display: none; }
}

/* Lightbox modal: the clicked diagram at natural size (capped to the
   viewport) with the report title + link underneath. */
.viz-modal {
    position: fixed;
    inset: 0;
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
}
.viz-modal[hidden] { display: none; }
.viz-modal__backdrop {
    position: absolute;
    inset: 0;
    background: rgba(17, 17, 17, 0.62);
}
.viz-modal__dialog {
    position: relative;
    background: #fff;
    border: 1px solid var(--home-rule);
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.3);
    padding: 24px 24px 20px;
    max-width: calc(100vw - 48px);
    max-height: calc(100vh - 48px);
    display: flex;
    flex-direction: column;
    gap: 14px;
    overflow: auto;
}
.viz-modal__close {
    position: absolute;
    top: 8px;
    right: 10px;
    width: 34px;
    height: 34px;
    border: none;
    background: transparent;
    font-size: 28px;
    line-height: 1;
    cursor: pointer;
    color: var(--fg-muted);
}
.viz-modal__close:hover { color: var(--fg); }
.viz-modal__image {
    display: block;
    /* Natural size, capped so the dialog always fits the viewport. */
    width: auto;
    height: auto;
    max-width: 100%;
    max-height: calc(100vh - 220px);
    margin: 0 auto;
}
.viz-modal__meta {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    text-align: center;
}
.viz-modal__title {
    font-size: 19px;
    font-weight: 700;
    line-height: 1.35;
    color: var(--fg);
    text-decoration: none;
}
.viz-modal__title:hover { color: var(--home-accent); }
.viz-modal__link {
    font-size: 14px;
    font-weight: 700;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--home-accent);
    text-decoration: none;
}
.viz-modal__link:hover { text-decoration: underline; }
body.viz-modal-open { overflow: hidden; }

/* Homepage: category section bands (2 columns, stacks on small screens).
   Boxless editorial sections: each card is a section with an uppercase
   crimson label on a heavy top rule and hairline-separated entries. */
.category-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 28px 44px;
}
@media (max-width: 720px) {
    .category-grid { grid-template-columns: 1fr; }
}

.cat-card {
    display: flex;
    flex-direction: column;
    color: inherit;
    min-width: 0;
}

.cat-card-head {
    display: flex;
    align-items: center;
    gap: 12px;
    border-top: 2px solid var(--fg);
    padding-top: 10px;
    margin-bottom: 6px;
}
.cat-title {
    margin: 0;
    font-size: 16px;
    font-weight: 800;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--home-accent);
    line-height: 1.3;
}

.cat-list {
    list-style: none;
    padding: 0;
    margin: 0 0 12px;
    display: grid;
    gap: 0;
    flex: 1 1 auto;
}
.cat-item {
    border-bottom: 1px solid var(--home-rule);
    font-size: 17px;
    min-width: 0;
}
.cat-item:last-child { border-bottom: none; }
.cat-item-link {
    display: flex;
    align-items: flex-start;
    gap: 14px;
    padding: 12px 0;
    color: inherit;
}
.cat-item-link:hover {
    text-decoration: none;
}
.cat-item-link:hover .cat-item-title { color: var(--home-accent); }
.cat-item-thumb {
    width: 64px;
    height: 64px;
    object-fit: cover;
    flex-shrink: 0;
    background: var(--chip-subtle-bg);
    display: block;
}
.cat-item-thumb--fallback {
    object-fit: contain;
    background: #fff;
    border: 1px solid var(--border);
    padding: 4px;
}
.cat-item-text {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 3px;
}
.cat-item-title {
    color: var(--fg);
    font-size: 18px;
    font-weight: 600;
    line-height: 1.35;
}
.cat-item-title.fallback { color: var(--fg-muted); font-style: italic; }
.cat-item-authors {
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--fg-muted);
    line-height: 1.35;
    overflow-wrap: anywhere;
    word-break: break-word;
}
.cat-item-date {
    font-size: 13px;
    color: var(--fg-muted);
    font-variant-numeric: tabular-nums;
}

.cat-card-cta {
    align-self: flex-start;
    margin-top: 2px;
    padding: 0;
    font-size: 15px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--home-accent);
    transition: color 0.12s ease;
}
.cat-card-cta:hover {
    text-decoration: underline;
    color: var(--fg);
}
.cat-empty {
    margin: 0;
    color: var(--fg-muted);
    font-style: italic;
    font-size: 17px;
}

/* Admin shell (sidebar + main column) */
body.admin .site-main {
    max-width: var(--home-max-w);
}
.admin-shell {
    display: grid;
    grid-template-columns: 220px 1fr;
    gap: 28px;
    align-items: start;
}
@media (max-width: 880px) {
    .admin-shell { grid-template-columns: 1fr; }
}
.admin-sidebar {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 16px 18px;
    position: sticky;
    top: 18px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}
.admin-brand {
    display: flex;
    flex-direction: column;
    gap: 2px;
    border-bottom: 1px solid var(--border);
    padding-bottom: 10px;
}
.admin-brand strong {
    font-size: 18px;
    color: var(--accent);
    letter-spacing: 0.02em;
}
.admin-username { font-size: 14px; }
.admin-menu { display: flex; flex-direction: column; gap: 4px; }
.admin-menu-link {
    display: block;
    padding: 8px 10px;
    border-radius: 6px;
    color: var(--fg);
    font-size: 16px;
}
.admin-menu-link:hover { background: #f3f6fb; text-decoration: none; }
.admin-menu-link.is-active {
    background: var(--accent);
    color: #fff;
}
.admin-menu-link.is-active:hover { background: #173a66; }
.admin-menu-link--sub {
    margin-left: 8px;
    padding: 6px 10px;
    font-size: 14px;
    color: var(--fg-muted);
}
.admin-menu-link--sub:hover { color: var(--accent); }
.admin-logout { margin: 4px 0 0; }
.admin-logout .admin-btn { width: 100%; }
.admin-back { margin: 0; font-size: 14px; }
.admin-main { min-width: 0; }
.admin-flashes { margin-bottom: 12px; }

/* Admin dashboard cards */
.admin-stats {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 14px;
    margin: 16px 0 26px;
}
@media (max-width: 640px) {
    .admin-stats { grid-template-columns: 1fr; }
}
.admin-stat {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 16px 18px;
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.admin-stat-label {
    font-size: 14px;
    color: var(--fg-muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
}
.admin-stat-value {
    font-size: 28px;
    color: var(--accent);
    font-variant-numeric: tabular-nums;
}
.admin-tools {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 14px;
}
.admin-tool {
    display: block;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 18px 20px;
    color: inherit;
    transition: border-color 0.12s ease, background-color 0.12s ease;
}
.admin-tool:hover {
    text-decoration: none;
    border-color: var(--accent);
    background: #f6f8fb;
}
.admin-tool h2 {
    margin: 0 0 6px;
    font-size: 18px;
    color: var(--accent);
}
.admin-tool p {
    margin: 0;
    color: var(--fg-muted);
    font-size: 16px;
    line-height: 1.5;
}

/* Dashboard "fill missing translations" cards. One <form> per
 * supported display language, each showing the current untranslated
 * count and a primary-action button that POSTs to
 * admin_dashboard.fill_missing_translations. Wrapped in a
 * <details>/<summary> so it can be collapsed; the section sits at
 * the bottom of the dashboard and the sidebar exposes an anchor that
 * scrolls + opens it. Uses the existing .admin-btn .is-loading
 * spinner from above; the JS handler in admin-loading.js swaps the
 * button text on submit. */
.admin-missing-translations {
    margin: 18px 0 26px;
    scroll-margin-top: 24px;
}
.admin-missing-toggle {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 10px;
    overflow: hidden;
}
.admin-missing-summary {
    list-style: none;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 14px 18px;
    user-select: none;
    background: var(--bg-card);
    transition: background-color 0.12s ease;
}
.admin-missing-summary::-webkit-details-marker { display: none; }
.admin-missing-summary:hover { background: #f6f8fb; }
.admin-missing-summary:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: -2px;
}
.admin-missing-summary-icon {
    flex: 0 0 auto;
    width: 0;
    height: 0;
    border-left: 6px solid var(--accent);
    border-top: 5px solid transparent;
    border-bottom: 5px solid transparent;
    transition: transform 0.15s ease;
}
.admin-missing-toggle[open] .admin-missing-summary-icon {
    transform: rotate(90deg);
}
.admin-missing-summary-title {
    font-size: 18px;
    font-weight: 700;
    color: var(--accent);
    flex: 1 1 auto;
}
.admin-missing-summary-hint {
    font-size: 13px;
    color: var(--fg-muted);
}
.admin-missing-toggle[open] .admin-missing-summary {
    border-bottom: 1px solid var(--border);
}
.admin-missing-body {
    padding: 16px 18px 18px;
}
.admin-missing-intro {
    margin: 0 0 14px;
    color: var(--fg-muted);
    font-size: 15px;
    line-height: 1.55;
}
.admin-missing-intro code {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.92em;
    background: var(--chip-subtle-bg);
    color: var(--chip-subtle-fg);
    padding: 0 4px;
    border-radius: 3px;
}
.admin-missing-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 14px;
}
.admin-missing-card {
    display: flex;
    flex-direction: column;
    gap: 10px;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 16px 18px;
}
.admin-missing-meta {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
}
.admin-missing-label {
    font-size: 17px;
    font-weight: 600;
    color: var(--accent);
}
.admin-missing-count {
    font-size: 28px;
    color: var(--accent);
    font-variant-numeric: tabular-nums;
    line-height: 1;
}
.admin-missing-count small {
    font-size: 14px;
    font-weight: 500;
    color: var(--fg-muted);
    margin-left: 2px;
}
.admin-missing-count.is-zero { color: var(--fg-muted); }
.admin-missing-sources {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}
.admin-missing-source {
    display: inline-flex;
    align-items: baseline;
    gap: 6px;
    padding: 3px 8px;
    border-radius: 999px;
    border: 1px solid var(--border);
    background: #f5f7fa;
    font-size: 12.5px;
    line-height: 1.3;
    color: var(--fg-muted);
}
.admin-missing-source-label { font-weight: 500; }
.admin-missing-source-count {
    font-variant-numeric: tabular-nums;
    font-weight: 700;
    color: var(--fg);
}
.admin-missing-source--primary {
    border-color: #c7d4e6;
    background: #eaf0f9;
    color: var(--accent);
}
.admin-missing-source--primary .admin-missing-source-count { color: var(--accent); }
.admin-missing-source--english {
    border-color: #f1c97a;
    background: #fff6e1;
    color: #8a5a00;
    cursor: help;
}
.admin-missing-source--english .admin-missing-source-count { color: #8a5a00; }
.admin-missing-limit {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    font-size: 14px;
    color: var(--fg-muted);
}
.admin-missing-limit input[type="number"] {
    width: 84px;
    padding: 4px 8px;
    border: 1px solid var(--border);
    border-radius: 5px;
    font-size: 15px;
    text-align: right;
    font-variant-numeric: tabular-nums;
}
.admin-missing-limit input[type="number"]:disabled {
    background: #f5f5f5;
    color: var(--fg-muted);
    cursor: not-allowed;
}
.admin-missing-submit {
    width: 100%;
    font-size: 16px;
}
.admin-missing-submit:disabled {
    opacity: 0.55;
    cursor: not-allowed;
}
.admin-missing-help {
    margin: 0;
    font-size: 13.5px;
    line-height: 1.45;
}

/* Admin login form */
body.admin-login-page .site-main {
    max-width: 440px;
}
.admin-login {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 28px 32px;
    margin-top: 32px;
}
.admin-login h1 {
    margin: 0 0 6px;
    font-size: 24px;
    color: var(--accent);
}
.admin-login-form {
    display: flex;
    flex-direction: column;
    gap: 14px;
    margin-top: 18px;
}
.admin-login-field {
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.admin-login-field span {
    font-size: 15px;
    color: var(--fg-muted);
    font-weight: 600;
}
.admin-login-field input {
    padding: 10px 12px;
    border: 1px solid var(--border);
    border-radius: 6px;
    font-size: 17px;
    background: var(--bg);
    color: var(--fg);
}
.admin-login-field input:focus {
    outline: 2px solid var(--accent);
    outline-offset: -1px;
    background: var(--bg-card);
}
.admin-login-submit {
    margin-top: 4px;
    padding: 10px 16px;
    font-size: 17px;
}
.admin-login-back {
    margin: 18px 0 0;
    font-size: 14px;
    text-align: center;
}

/* Homepage admin toolbar: drag-and-drop reorder hint + save status.
   Visible only when the admin is logged in (see home.html). */
.admin-home-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
    margin: 0 0 14px;
    padding: 8px 14px;
    border: 1px dashed var(--border);
    border-radius: 8px;
    background: var(--chip-subtle-bg);
}
.admin-home-order-status {
    font-size: 14px;
    color: var(--fg-muted);
    min-height: 1em;
    font-variant-numeric: tabular-nums;
}
.admin-home-order-status.is-ok { color: #155724; }
.admin-home-order-status.is-error { color: #721c24; }
.admin-home-order-status.is-busy { color: var(--accent); }

/* Homepage drag-and-drop reorder (admin only).
   The grid gets `.is-sortable` from home.html and individual cards
   are flagged draggable; the script swaps DOM order on dragover. */
.category-grid.is-sortable .cat-card {
    cursor: grab;
    transition: box-shadow 0.12s ease, opacity 0.12s ease,
                border-color 0.12s ease, background-color 0.12s ease;
}
.category-grid.is-sortable .cat-card:active { cursor: grabbing; }
.category-grid.is-sortable .cat-card.is-dragging {
    opacity: 0.45;
    border-color: var(--accent);
    background: #f3f6fb;
}
.cat-card-drag-handle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    margin-right: 4px;
    color: var(--fg-muted);
    font-size: 18px;
    line-height: 1;
    border-radius: 6px;
    background: var(--chip-subtle-bg);
    cursor: grab;
    flex-shrink: 0;
}
.category-grid.is-sortable .cat-card:hover .cat-card-drag-handle {
    color: var(--accent);
    background: var(--chip-bg);
}

/* Per-card "hide / show" toggle (admin only). Lives at the end of
   the cat-card-head so the title still takes the available width. */
.cat-card-visibility {
    margin-left: auto;
    padding: 4px 12px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--bg-card);
    color: var(--fg-muted);
    font: inherit;
    font-size: 13px;
    line-height: 1.3;
    cursor: pointer;
    white-space: nowrap;
    transition: border-color 0.12s ease, color 0.12s ease,
                background-color 0.12s ease;
}
.cat-card-visibility:hover {
    border-color: var(--accent);
    color: var(--accent);
    background: #f3f6fb;
}
.cat-card-visibility:disabled {
    opacity: 0.6;
    cursor: progress;
}
.cat-card-visibility[aria-pressed="true"] {
    border-color: #f0c200;
    background: #fff8e1;
    color: #8a6d00;
}
.cat-card-visibility[aria-pressed="true"]:hover {
    background: #ffefbf;
}

/* Dimmed appearance for cards the admin has hidden from the public
   homepage. The card stays interactive so the admin can flip it back
   on, but the muted look signals "not visible to visitors". */
.cat-card.is-hidden-admin {
    opacity: 0.55;
    border-style: dashed;
    background: #fafafa;
}
.cat-card.is-hidden-admin:hover { opacity: 0.85; }

/* Admin toolbar on the public report list (visible only when logged in) */
.admin-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
    margin: 6px 0 18px;
    padding: 10px 14px;
    border: 1px dashed var(--border);
    border-radius: 8px;
    background: var(--chip-subtle-bg);
}
.admin-toolbar-note { color: var(--fg-muted); font-size: 15px; }
.admin-chip { background: #fef3c7; color: #92400e; }
.row--admin { position: relative; }
.row--admin .row-link:hover { background: #fff8e7; }
.row--admin .row-link { padding-right: 96px; }
.row-visibility-btn {
    position: absolute;
    top: 10px;
    right: 12px;
    z-index: 2;
    padding: 4px 10px;
    font-size: 13px;
    font-weight: 600;
    color: var(--fg-muted);
    background: #fff;
    border: 1px solid var(--border);
    border-radius: 6px;
    cursor: pointer;
}
.row-visibility-btn:hover { background: #f6f8fb; color: var(--fg); }
.row-visibility-btn:disabled { opacity: 0.6; cursor: default; }
.row-visibility-btn[aria-pressed="true"] {
    color: #92400e;
    background: #fef3c7;
    border-color: #fcd34d;
}
.row--hidden { opacity: 0.55; }
.row--hidden .row-thumb { filter: grayscale(1); }

/* Reports edit form: stacked label/body for full-width textareas */
.admin-field--stacked {
    grid-template-columns: 1fr;
}
.admin-field--stacked > span { padding-top: 0; }

/* Category combobox (reports edit form): a text input with a curated
   dropdown plus a clickable "+ 새 카테고리 추가" action. Replaces the
   native <datalist> so the add-new affordance can be a real list item. */
.admin-combobox { position: relative; min-width: 0; }
.admin-combobox-control { display: flex; align-items: stretch; }
.admin-combobox-control input[type="text"] {
    flex: 1;
    min-width: 0;
    border-radius: 6px 0 0 6px;
}
.admin-combobox-toggle {
    flex: 0 0 auto;
    margin-left: -1px;
    padding: 0 12px;
    border: 1px solid var(--border);
    border-radius: 0 6px 6px 0;
    background: var(--bg-card);
    color: var(--fg-muted);
    cursor: pointer;
    font-size: 12px;
    line-height: 1;
}
.admin-combobox-toggle:hover { color: var(--accent); border-color: var(--accent); }
.admin-combobox-list {
    position: absolute;
    z-index: 30;
    top: calc(100% + 2px);
    left: 0;
    right: 0;
    margin: 0;
    padding: 4px 0;
    list-style: none;
    max-height: 260px;
    overflow-y: auto;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 6px;
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.12);
}
.admin-combobox-option,
.admin-combobox-add,
.admin-combobox-empty {
    padding: 7px 12px;
    font-size: 15px;
    color: var(--fg);
    cursor: pointer;
}
.admin-combobox-option:hover,
.admin-combobox-option.is-active,
.admin-combobox-add:hover,
.admin-combobox-add.is-active {
    background: #f0f5fb;
    color: var(--accent);
}
.admin-combobox-empty { color: var(--fg-muted); cursor: default; }
.admin-combobox-add {
    margin-top: 4px;
    border-top: 1px solid var(--border);
    font-weight: 600;
    color: var(--accent);
}

/* Monospace HTML editor */
.admin-code {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 14px;
    line-height: 1.5;
    min-height: 220px;
    white-space: pre-wrap;
    word-break: break-word;
    overflow-wrap: anywhere;
    overflow-x: hidden;
}
textarea.admin-code { resize: vertical; }

/* Re-translate action (non-source language edit) */
.admin-retranslate-form { margin-top: 24px; }
.admin-retranslate-form .admin-field--inline {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 12px 0 4px;
}
.admin-retranslate-form .admin-field--inline > span {
    padding-top: 0;
    color: var(--fg);
    font-size: 16px;
}
.admin-retranslate-hint {
    margin: 4px 0 14px;
    font-size: 14px;
    line-height: 1.55;
}

/* Danger zone (report delete) */
.admin-danger-form { margin-top: 24px; }
.admin-danger-zone {
    border-color: #f3c2c2;
    background: #fff6f6;
}
.admin-btn-danger {
    color: #9c1c1c;
    border-color: #f3c2c2;
    background: #fff;
}
.admin-btn-danger:hover { background: #ffe8e8; }
.admin-btn-danger:disabled {
    color: #b88;
    border-color: #f3d7d7;
    background: #fdf3f3;
    cursor: not-allowed;
}

/* Per-language editor tabs (source + every DISPLAY_LANG) */
.admin-lang-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    margin: 0 0 18px;
    padding: 4px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--chip-subtle-bg);
}
.admin-lang-tab {
    display: inline-flex;
    align-items: baseline;
    gap: 8px;
    padding: 6px 12px;
    border-radius: 6px;
    border: 1px solid transparent;
    color: var(--fg);
    font-size: 16px;
    line-height: 1.3;
    text-decoration: none;
    background: transparent;
}
.admin-lang-tab:hover {
    text-decoration: none;
    background: var(--bg-card);
    border-color: var(--border);
}
.admin-lang-tab em {
    font-size: 12px;
    font-style: normal;
    color: var(--fg-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.admin-lang-tab.is-source { font-weight: 600; }
.admin-lang-tab.is-source em { color: #1d5f96; }
.admin-lang-tab.is-active {
    background: var(--bg-card);
    border-color: var(--accent);
    color: var(--accent);
}
.admin-lang-tab.is-active em { color: var(--accent); }

.admin-header-lang { color: var(--fg-muted); font-weight: 400; font-size: 0.85em; }

/* Disabled meta inputs (visible only when editing a translation) */
.admin-field input:disabled,
.admin-field select:disabled,
.admin-field textarea:disabled {
    background: #f5f5f5;
    color: var(--fg-muted);
    cursor: not-allowed;
}

/* ------------------------------------------------------------------
   Analytics dashboard
   ------------------------------------------------------------------ */
.admin-stats--secondary { margin-top: -8px; }

.analytics-windows {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    align-items: center;
    margin: 0 0 16px;
}
.analytics-window-link {
    padding: 6px 12px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--bg-card);
    color: var(--fg);
    font-size: 14px;
    text-decoration: none;
}
.analytics-window-link:hover {
    text-decoration: none;
    border-color: var(--accent);
    color: var(--accent);
}
.analytics-window-link.is-active {
    background: var(--accent);
    color: #fff;
    border-color: var(--accent);
}
.analytics-window-current {
    margin-left: auto;
    color: var(--fg-muted);
    font-size: 13px;
}

.analytics-range {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 10px;
    margin: 0 0 18px;
    padding: 12px 14px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--bg-card);
}
.analytics-range.is-active {
    border-color: var(--accent);
}
.analytics-range-field {
    display: flex;
    flex-direction: column;
    gap: 4px;
    font-size: 12px;
    color: var(--fg-muted);
}
.analytics-range-field input[type="date"] {
    padding: 6px 10px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg);
    color: var(--fg);
    font-size: 14px;
}
.analytics-range-field input[type="date"]:focus {
    outline: none;
    border-color: var(--accent);
}
.analytics-range-sep {
    padding-bottom: 7px;
    color: var(--fg-muted);
}
.analytics-range-submit {
    align-self: flex-end;
}
.analytics-range-clear {
    align-self: flex-end;
    padding-bottom: 7px;
    font-size: 13px;
    color: var(--fg-muted);
}

.analytics-top-form {
    display: flex;
    align-items: center;
    gap: 6px;
}
.analytics-top-label {
    font-size: 12px;
    color: var(--fg-muted);
}
.analytics-top-input {
    width: 72px;
    padding: 5px 8px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg);
    color: var(--fg);
    font-size: 14px;
}
.analytics-top-input:focus {
    outline: none;
    border-color: var(--accent);
}
.analytics-top-submit {
    padding: 5px 12px;
    font-size: 13px;
}

.analytics-card {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 18px 20px;
    margin: 0 0 18px;
}
.analytics-card-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin: 0 0 12px;
    flex-wrap: wrap;
}
.analytics-card-head h2 {
    margin: 0;
    font-size: 18px;
    color: var(--accent);
}

.analytics-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(360px, 1fr));
    gap: 18px;
    margin: 0 0 18px;
}
.analytics-grid .analytics-card { margin: 0; }

/* Daily traffic chart (pure CSS bars) */
.analytics-chart {
    display: flex;
    align-items: flex-end;
    gap: 4px;
    height: 180px;
    padding: 8px 0 0;
    overflow-x: auto;
}
.analytics-chart-bar {
    position: relative;
    flex: 1 0 18px;
    min-width: 18px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-end;
    height: 100%;
    font-size: 11px;
    color: var(--fg-muted);
}
.analytics-chart-fill {
    width: 70%;
    min-height: 2px;
    background: linear-gradient(180deg, var(--accent), #4a82c2);
    border-radius: 4px 4px 0 0;
    transition: filter 0.12s ease;
}
.analytics-chart-bar:hover .analytics-chart-fill {
    filter: brightness(1.1);
}
.analytics-chart-count {
    margin-bottom: 4px;
    font-variant-numeric: tabular-nums;
    color: var(--fg);
    opacity: 0;
    transition: opacity 0.12s ease;
}
.analytics-chart-bar:hover .analytics-chart-count { opacity: 1; }
.analytics-chart-day {
    margin-top: 6px;
    transform: rotate(-45deg);
    transform-origin: top left;
    white-space: nowrap;
    font-size: 10px;
}

/* Top-reports table */
.analytics-table th, .analytics-table td { font-size: 14px; }
.analytics-table .analytics-rank { width: 36px; color: var(--fg-muted); }
.analytics-table .analytics-num {
    text-align: right;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
.analytics-report-no {
    display: inline-block;
    margin-left: 8px;
    font-size: 12px;
}

/* Horizontal bars (language / country / referrer) */
.analytics-bars {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.analytics-bars-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 2fr) auto;
    align-items: center;
    gap: 12px;
    font-size: 14px;
}
.analytics-bars-label {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.analytics-bars-track {
    height: 10px;
    background: var(--chip-subtle-bg);
    border-radius: 999px;
    overflow: hidden;
    display: block;
}
.analytics-bars-fill {
    display: block;
    height: 100%;
    background: var(--accent);
    border-radius: 999px;
}
.analytics-bars-fill--region { background: #4f9d4f; }
.analytics-bars-fill--ref { background: #b6802e; }
.analytics-bars-value {
    font-variant-numeric: tabular-nums;
    color: var(--fg-muted);
    text-align: right;
    white-space: nowrap;
}

.analytics-resolve-form {
    margin-top: 14px;
    padding-top: 12px;
    border-top: 1px dashed var(--border);
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
}
.analytics-resolve-hint { font-size: 13px; }

@media (max-width: 640px) {
    .analytics-bars-row {
        grid-template-columns: minmax(0, 1fr) auto;
    }
    .analytics-bars-track { grid-column: 1 / -1; }
    .analytics-chart { height: 140px; }
    .analytics-chart-day { transform: none; font-size: 9px; }
}

/* ==============================================================
   Auth (login / signup) — modal + standalone pages
   --------------------------------------------------------------
   Used by web/blueprints/auth.py and the login modal that
   web/templates/auth/_login_modal.html overlays on top of the
   gated report-detail page.
   ============================================================== */

/* Gated report-detail: keep the article fully legible so the
   visitor can read what they're about to sign up for. We only
   apply a soft tint so the modal reads as the focal element and
   block interaction with body links / buttons (so a stray click
   doesn't navigate away from the prompt). The actual content
   gating is server-side: anonymous reads are excluded from the
   view-tracking log. */
.report-detail.is-gated {
    position: relative;
    opacity: 0.92;
    pointer-events: none;
    user-select: text;  /* text remains selectable / readable */
}
.report-detail.is-gated .back-nav {
    pointer-events: auto;  /* let visitors navigate away */
}

/* Body scroll lock while the modal is open. */
body.auth-modal-open {
    overflow: hidden;
}

/* Backdrop covers the entire viewport. We use a very light wash
   (no blur, low alpha) so the article behind stays readable; the
   modal card itself does the heavy lifting via its shadow. */
.auth-modal-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(20, 30, 50, 0.18);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1000;
    padding: 20px;
}

.auth-modal-card {
    background: var(--bg-card);
    border-radius: 12px;
    /* Deeper shadow + a subtle ring so the card pops against the
       now-translucent backdrop without darkening the page behind. */
    box-shadow:
        0 30px 80px -16px rgba(0, 0, 0, 0.35),
        0 0 0 1px rgba(20, 30, 50, 0.08);
    max-width: 440px;
    width: 100%;
    max-height: calc(100vh - 40px);
    overflow-y: auto;
    padding: 24px 24px 18px;
}

.auth-modal-head { margin-bottom: 16px; }
.auth-modal-title {
    margin: 0 0 4px;
    font-size: 22px;
    color: var(--fg);
}
.auth-modal-subtitle {
    margin: 0;
    color: var(--fg-muted);
    font-size: 14px;
    line-height: 1.5;
}

.auth-modal-tabs {
    display: flex;
    gap: 4px;
    margin: 0 0 16px;
    border-bottom: 1px solid var(--border);
}
.auth-modal-tab {
    appearance: none;
    background: transparent;
    border: 0;
    border-bottom: 2px solid transparent;
    padding: 8px 16px;
    font: inherit;
    font-size: 15px;
    color: var(--fg-muted);
    cursor: pointer;
    margin-bottom: -1px;
}
.auth-modal-tab:hover { color: var(--fg); }
.auth-modal-tab.is-active {
    color: var(--accent);
    border-bottom-color: var(--accent);
    font-weight: 600;
}

.auth-modal-flash {
    min-height: 0;
    margin: 0 0 12px;
    padding: 0 10px;
    border-radius: 6px;
    font-size: 14px;
    line-height: 1.5;
}
.auth-modal-flash:empty { display: none; }
.auth-modal-flash--ok {
    background: #e6f4ea;
    color: #1d6a3a;
    padding: 8px 12px;
}
.auth-modal-flash--error {
    background: #fde8e8;
    color: #b3261e;
    padding: 8px 12px;
}

.auth-pane { display: none; }
.auth-pane.is-active { display: block; }

.auth-form { display: flex; flex-direction: column; gap: 12px; }
.auth-form[hidden] { display: none; }

.auth-field {
    display: flex;
    flex-direction: column;
    gap: 6px;
    font-size: 14px;
}
.auth-field > span {
    color: var(--fg-muted);
    font-size: 13px;
}
.auth-field > span small {
    font-size: 11px;
    font-weight: normal;
    margin-left: 4px;
}
.auth-field input {
    padding: 10px 12px;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--bg-card);
    font: inherit;
    font-size: 16px;
    color: inherit;
}
.auth-field input:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 2px rgba(31, 79, 139, 0.15);
}

.auth-submit {
    padding: 10px 16px;
    border: 1px solid var(--accent);
    border-radius: 6px;
    background: var(--accent);
    color: #fff;
    font: inherit;
    font-size: 15px;
    font-weight: 600;
    cursor: pointer;
    margin-top: 6px;
}
.auth-submit:hover:not(:disabled) { filter: brightness(0.95); }
.auth-submit:disabled {
    opacity: 0.6;
    cursor: progress;
}

.auth-resend,
.auth-link-button {
    appearance: none;
    background: none;
    border: 0;
    color: var(--accent);
    font: inherit;
    font-size: 13px;
    cursor: pointer;
    text-align: left;
    padding: 4px 0;
}
.auth-resend:disabled { color: var(--fg-muted); cursor: not-allowed; }
.auth-resend:hover:not(:disabled),
.auth-link-button:hover { text-decoration: underline; }

.auth-verify-intro {
    margin: 0 0 4px;
    color: var(--fg-muted);
    font-size: 14px;
    line-height: 1.5;
}

.auth-modal-foot,
.auth-modal-footer {
    margin: 14px 0 0;
    text-align: center;
    font-size: 13px;
    color: var(--fg-muted);
}
.auth-modal-cancel { color: var(--fg-muted); }
.auth-modal-cancel:hover { color: var(--accent); }

/* Standalone /login and /signup pages (no modal). */
body.auth-page .site-main { max-width: 480px; }
.auth-shell {
    background: var(--bg-card);
    padding: 28px 24px 20px;
    border: 1px solid var(--border);
    border-radius: 12px;
    box-shadow: 0 12px 30px -20px rgba(0, 0, 0, 0.2);
}
.auth-shell-title { margin: 0 0 6px; font-size: 24px; }
.auth-shell-subtitle { margin: 0 0 18px; color: var(--fg-muted); font-size: 14px; }
.auth-shell-form { margin-bottom: 18px; }
.auth-shell-foot { margin: 8px 0 0; font-size: 13px; color: var(--fg-muted); }
.auth-resend-form { margin-top: 6px; }

/* Recovery links row under the login form (find id / forgot password). */
.auth-shell-links {
    margin: 12px 0 4px;
    font-size: 13px;
    text-align: center;
}
.auth-shell-links a { color: var(--accent); }
.auth-shell-links a:hover { text-decoration: underline; }
.auth-shell-links-sep { margin: 0 8px; color: var(--fg-muted); }

/* Account settings hub: read-only details + action buttons. */
.account-meta {
    margin: 0 0 20px;
    border: 1px solid var(--border);
    border-radius: 8px;
    overflow: hidden;
}
.account-meta-row {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    padding: 12px 14px;
    font-size: 14px;
}
.account-meta-row + .account-meta-row { border-top: 1px solid var(--border); }
.account-meta-row dt { margin: 0; color: var(--fg-muted); }
.account-meta-row dd { margin: 0; font-weight: 600; word-break: break-all; }
.account-actions {
    display: flex;
    flex-direction: column;
    gap: 14px;
    align-items: stretch;
}
.auth-submit--block {
    display: block;
    text-align: center;
    text-decoration: none;
}
.account-danger-link {
    align-self: center;
    color: #b02a37;
    font-size: 13px;
}
.account-danger-link:hover { text-decoration: underline; }

/* Withdrawal warning callout + destructive submit button. */
.account-danger-box {
    margin: 0 0 18px;
    padding: 12px 14px;
    border: 1px solid #f1aeb5;
    background: #fdf0f1;
    color: #721c24;
    border-radius: 8px;
    font-size: 14px;
    line-height: 1.5;
}
.auth-submit--danger {
    background: #b02a37;
    border-color: #b02a37;
}

/* ==============================================================
   Admin: users + grants tables
   ============================================================== */
.admin-section {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 18px 20px;
    margin: 18px 0;
}
.admin-section h2 {
    margin: 0 0 10px;
    font-size: 18px;
}
.admin-section--danger {
    border-color: #f3c5c1;
    background: #fff7f6;
}

/* Our Vision admin editor. */
.vision-admin-photo {
    display: flex;
    gap: 20px;
    align-items: flex-start;
    flex-wrap: wrap;
}
.vision-admin-photo img {
    width: 160px;
    height: auto;
    border-radius: 8px;
    border: 1px solid var(--border);
}
.vision-admin-photo-forms {
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.vision-admin-body {
    width: 100%;
    box-sizing: border-box;
    line-height: 1.7;
    font-size: 15px;
}

/* Inline-form layout for short user_edit.html forms.
   Scoped via the additional .admin-filter / .admin-inline-form classes so
   it does not override the main vertical .admin-form { display: grid }
   rule used by reports_edit.html / authors_edit.html, where every
   .admin-fieldset card must stretch to the full container width. */
.admin-filter.admin-form,
.admin-inline-form.admin-form {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 10px;
    align-items: center;
}
.admin-inline-form { display: inline; }
.admin-checkbox {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 13px;
    color: var(--fg-muted);
}
.admin-btn-danger {
    background: #c1392b;
    color: #fff;
    border-color: #c1392b;
}
.admin-btn-danger:hover:not(:disabled) { filter: brightness(0.95); }
.admin-link-danger { color: #c1392b !important; }

/* Inline ``<button>`` rendered inside an .admin-inline-form must read
   as a text link (same color/sizing as adjacent <a class="admin-link">)
   rather than a chrome-styled button. Neutralises the user-agent
   border / background / padding so the row-actions cell stays
   visually consistent across "편집" (anchor) and "삭제" (form button). */
button.admin-link {
    background: none;
    border: 0;
    padding: 0;
    font: inherit;
    font-size: 16px;
    cursor: pointer;
    color: var(--accent);
}
button.admin-link:hover { text-decoration: underline; }
button.admin-link.admin-link-danger { color: #c1392b; }

/* Row-actions cell: gap the edit anchor + delete inline-form so the
   two controls don't visually merge. ``flex-wrap`` lets the cell
   collapse onto a second line in narrow viewports without breaking
   the table layout. */
.admin-row-actions {
    display: inline-flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
}
.admin-row-actions .admin-inline-form { display: inline; margin: 0; }

/* Standalone delete form on authors_edit.html. Sits below the main
   admin-form card and is intentionally pulled visually apart from
   the save/retranslate controls so the destructive action requires a
   deliberate eye-down scroll + confirm dialog. */
.admin-delete-form {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
    margin: 24px 0 0;
    padding: 14px 16px;
    border: 1px solid #f3c5c1;
    border-radius: 8px;
    background: #fff7f6;
}
.admin-delete-form .admin-muted {
    font-size: 13px;
    line-height: 1.5;
}

.admin-pill-reader   { background: #eef3fa; color: #1f4f8b; }
.admin-pill-editor   { background: #fff4d6; color: #8a5a00; }
.admin-pill-admin    { background: #ffe1de; color: #a3261e; }

/* Header / nav helpers for the new auth chrome. Bottom edge of the
   account row lines up with the bottom edge of the brand logo. */
.user-nav {
    display: inline-flex;
    align-items: center;
    justify-content: flex-end;
    gap: 6px;
    flex: 0 0 auto;
}
.user-nav-form { display: inline; }
.user-nav-link {
    appearance: none;
    background: transparent;
    border: 1px solid var(--border);
    border-radius: 999px;
    color: var(--fg-muted);
    padding: 4px 8px;
    font: inherit;
    font-size: 16px;
    cursor: pointer;
}
.user-nav-link:hover { color: var(--accent); border-color: var(--accent); }
/* Logout: compact icon-only chip; the text label stays in the DOM
   for screen readers via the button's aria-label. */
.user-nav-logout {
    display: inline-flex;
    align-items: center;
    padding: 6px;
    border-radius: 50%;
    line-height: 0;
}
.user-nav-logout-icon {
    display: block;
    width: 15px;
    height: 15px;
    flex: 0 0 auto;
}
.user-nav-logout-label { display: none; }
.user-nav-email {
    font-size: 13px;
    color: var(--fg-muted);
    padding: 0 4px;
    max-width: 180px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Pre-announcement: "signup is just email verification" callout.
   Surfaced in the gating modal (between subtitle and tabs), on the
   standalone /signup page (above the form, step 1 only), and as a
   compact variant on the /login page. */
.auth-signup-easy-notice {
    display: flex;
    gap: 12px;
    align-items: flex-start;
    margin: 0 0 18px;
    padding: 12px 14px;
    border: 1px solid #c4e5cf;
    background: #f1faf3;
    border-radius: 10px;
    line-height: 1.5;
}
.auth-signup-easy-notice--compact {
    margin-top: 16px;
}
.auth-signup-easy-icon {
    flex: 0 0 26px;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: #1d8a4a;
    color: #fff;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 14px;
    font-weight: 700;
    margin-top: 2px;
}
.auth-signup-easy-body { flex: 1 1 auto; min-width: 0; }
.auth-signup-easy-title {
    display: block;
    font-size: 14px;
    color: #1d6a3a;
    margin: 0 0 4px;
}
.auth-signup-easy-text {
    margin: 0 0 6px;
    font-size: 13px;
    color: #2a4f37;
}
.auth-signup-easy-steps {
    margin: 0 0 6px;
    font-size: 12px;
    color: #4a7158;
    font-variant-numeric: tabular-nums;
}
.auth-signup-easy-cta {
    display: inline-block;
    padding: 6px 0;
    color: #1d6a3a;
    font-weight: 600;
    font-size: 13px;
}
.auth-signup-easy-cta:hover { color: #155a31; text-decoration: underline; }

@media (max-width: 480px) {
    .auth-signup-easy-notice { padding: 10px 12px; }
    .auth-signup-easy-icon { width: 22px; height: 22px; flex-basis: 22px; }
}

/* ------------------------------------------------------------------
   Mobile report-title adjustments: homepage bands, list rows, and the
   detail page step down a size so long Korean titles don't dominate
   small screens. */
@media (max-width: 640px) {
    .current-watch__title { font-size: 21px; }
    .current-watch__list-title { font-size: 16px; }
    .cat-item-title { font-size: 15px; }
    .row-title { font-size: 17px; }
    html[lang] .report-detail .report-header h1 { font-size: 22px; }
}
