/* ==========================================================================
   AIDD Soln Design System
   Professional science platform — dark header, clean cards, subtle accents
   ========================================================================== */

/* --- Reset & Base --- */
*,
*::before,
*::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

:root {
    --color-bg: #f7f8fa;
    --color-surface: #ffffff;
    --color-surface-hover: #f0f2f5;
    /* Subtle elevation/depression steps used for gradients, hero cards,
       table headers, and zebra rows. In light mode these are near-white
       tints; in dark mode (see [data-theme="dark"] below) they flip to
       slightly lighter/darker slate shades so cards still read as
       "lifted" or "sunken" against the body background. */
    --color-surface-elevated: #f8fbff;
    --color-surface-sunken: #f8fafc;
    --color-border: #e2e5ea;
    --color-border-light: #eef0f3;

    --color-text: #1a1d23;
    --color-text-secondary: #5f6672;
    --color-text-muted: #475569;
    --color-text-inverse: #ffffff;

    --color-primary: #2563eb;
    --color-primary-dark: #1d4ed8;
    --color-primary-light: #eff6ff;

    --color-accent: #0891b2;
    --color-accent-light: #ecfeff;

    --color-success: #047857;
    --color-warning: #d97706;

    --color-cta: #047857;
    --color-cta-hover: #065f46;
    --color-cta-light: #ecfdf5;

    --color-fieldset-bg: #f8fafc;
    --color-fieldset-border: #e2e8f0;

    --color-nav-bg: #0f172a;
    --color-nav-bg-soft: #1e293b;
    --color-nav-divider: #334155;
    --color-nav-divider-strong: #475569;
    --color-nav-text: #cbd5e1;
    --color-nav-text-soft: #94a3b8;
    --color-nav-text-strong: #f1f5f9;
    --color-nav-text-hover: #ffffff;
    --color-nav-accent: #38bdf8;
    --color-danger: #ef4444;
    --color-danger-soft: #fef2f2;
    --color-danger-border: #fecaca;
    --color-danger-strong: #991b1b;
    --color-indigo: #4f46e5;
    --color-warning-soft: #fefce8;
    --color-warning-strong: #854d0e;
    --color-info-soft: #f0f9ff;
    --color-info-strong: #0369a1;

    --color-hero-bg: linear-gradient(135deg, #0f172a 0%, #1e293b 50%, #0c4a6e 100%);

    --font-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    --font-mono: 'JetBrains Mono', 'Fira Code', 'Consolas', monospace;

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
    --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.07), 0 2px 4px -2px rgba(0, 0, 0, 0.05);
    --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.08), 0 4px 6px -4px rgba(0, 0, 0, 0.04);
    --shadow-card-hover: 0 12px 24px -4px rgba(0, 0, 0, 0.12);

    --radius-sm: 6px;
    --radius-md: 10px;
    --radius-lg: 16px;
    --radius: 10px;

    /* Semantic surface / text tokens not covered by the main palette */
    --color-surface-secondary: #f0f2f5;
    --color-text-tertiary: #b0b7c3;

    /* Phase / clinical stage colours (target snapshot chart) */
    --color-phase-4: #059669;
    --color-phase-3: #2563eb;
    --color-phase-2: #0891b2;
    --color-phase-default: #8b919d;

    --container-max: 1280px;
    /* Width of the workbench sidebar column (see .workbench-frame). Shared so the
       fixed project tray can center over the content area, not the whole viewport. */
    --workbench-sidebar-width: 224px;
    --transition: 0.2s ease;

    /* ── light-core4 additions (dormant) ─────────────────────────────
       Tokens from the approved light-core4 spec that have no existing
       counterpart. Nothing references them yet: they are declared here so
       the later page-by-page adoption adds usage only, never definitions.
       Tokens whose value the spec *changes* (--color-primary, --radius,
       --color-text-secondary, …) are deliberately absent — redefining
       those here would repaint the whole app in one step. They move in
       the page pilots and land globally in the final sweep.

       Names follow this file's --color-* / --space-* / --font-size-*
       convention; the spec's short DSL names (--primary, --s1, --tx) are
       intentionally NOT introduced, to avoid a permanent second vocabulary. */

    /* Borders and focus — the spec's third border step and a focus colour
       distinct from the accent. --color-focus-ring is a ring/outline colour;
       it is not a button background. */
    --color-border-strong: #9fadb7;
    --color-primary-border: #9dcec6;
    --color-focus-ring: #0b8ea3;

    /* Third surface step, below --color-surface-sunken. */
    --color-surface-3: #e9eef1;

    /* Tinted success background (pairs with --color-success). */
    --color-success-soft: #e7f4ea;

    /* Spacing scale (4 → 64px). */
    --space-1: 4px;
    --space-2: 8px;
    --space-3: 12px;
    --space-4: 16px;
    --space-5: 24px;
    --space-6: 32px;
    --space-7: 48px;
    --space-8: 64px;

    /* Type scale (12 → 50px). */
    --font-size-xs: 12px;
    --font-size-sm: 13px;
    --font-size-base: 15px;
    --font-size-md: 17px;
    --font-size-lg: 20px;
    --font-size-xl: 26px;
    --font-size-2xl: 34px;
    --font-size-3xl: 50px;

    /* Data visualisation. Ordinal ramp for ranked values (clinical phase);
       categorical set for unordered classes (assay/activity type), chosen to
       stay distinguishable under the common colour-vision deficiencies.
       Charts must bind these by data meaning, never by row position. */
    --color-dv-seq-1: #5cbcae;
    --color-dv-seq-2: #3ba597;
    --color-dv-seq-3: #238e81;
    --color-dv-seq-4: #11786c;
    --color-dv-seq-5: #0a5b52;
    --color-dv-cat-1: #2a78d6;
    --color-dv-cat-2: #008300;
    --color-dv-cat-3: #e87ba4;
    --color-dv-cat-4: #eda100;
    --color-dv-cat-5: #1baf7a;
    --color-dv-cat-6: #eb6834;
    /* KPI figures: one accent plus neutral, so a dashboard does not turn
       into a colour chart. Aliases, so they follow the accent when it moves. */
    --color-dv-kpi: var(--color-primary);
    --color-dv-kpi-neutral: var(--color-text-muted);

    /* Density. Comfortable by default; data-dense views opt in to compact
       via the [data-density="compact"] rule below. */
    --cell-padding-y: 12px;
    --cell-padding-x: 16px;
    --box-padding: var(--space-5);

    /* ── Landing hero surface ────────────────────────────────────────
       The hero is a dark band on every theme today, so its inner surfaces
       were written as literal white overlays. Naming them lets the landing
       page retarget the band for the light spec without editing rules that
       other pages share. Values are unchanged from the literals they
       replace — introducing the names repaints nothing. */
    --color-hero-text: var(--color-text-inverse);
    --color-hero-text-soft: var(--color-nav-text-soft);
    --color-hero-text-muted: rgba(255, 255, 255, 0.7);
    --color-hero-field-bg: rgba(255, 255, 255, 0.1);
    --color-hero-field-bg-focus: rgba(255, 255, 255, 0.14);
    --color-hero-field-border: rgba(255, 255, 255, 0.15);
    --color-hero-chip-bg: rgba(255, 255, 255, 0.15);
    --color-hero-chip-bg-hover: rgba(255, 255, 255, 0.25);
    --color-hero-chip-border: rgba(255, 255, 255, 0.25);
    /* Panels sitting on the hero band: the stat tiles and the project badge. */
    --color-hero-panel-bg: rgba(255, 255, 255, 0.08);
    --color-hero-panel-border: rgba(255, 255, 255, 0.12);
    --color-hero-badge-border: rgba(255, 255, 255, 0.18);
    --color-hero-badge-text: rgba(255, 255, 255, 0.92);
    /* Decorative glows behind the hero copy. */
    --color-hero-glow-1: rgba(56, 189, 248, 0.08);
    --color-hero-glow-2: rgba(37, 99, 235, 0.06);

    /* PR5b-1 batch E — row action buttons. These live in main.css rather than
       search.css because .inline-fav-btn and .memo-popover render on pages
       other than /search; a token defined in the page stylesheet would be
       undefined there and the colour would disappear.

       --color-fav-active holds the same value as --color-warning and is
       deliberately a separate token: a favourite being on is not a warning,
       and retargeting one must not move the other. It has no dark pair — no
       [data-theme="dark"] rule overrides .inline-fav-btn, and PR7 3단계 leaves
       it alone (keep-semantic).

       --color-popover-shadow WAS the same story until PR7 3단계 retargeted it
       onto a canonical (var(--color-text)-based) value below. That canonical
       differs by theme, so a dark pin was added to :root[data-theme="dark"]
       (search below for "PR7 3단계 — 다크 pin") to freeze .memo-popover's dark
       shadow at its pre-retarget value — see docs/service-platform/
       PR7_PAGE_TOKEN_CLASSIFICATION.md's 다크 고정 정책. */
    --color-fav-active: #fbbf24;
    --color-popover-shadow: color-mix(in srgb, var(--color-text) 10%, transparent);

    /* PR6 batch 3 — project evidence chip. Rendered by both the compound and
       the target page (.cpd-evidence-retrieval / .target-evidence-retrieval)
       with the same meaning and the same values, and neither page stylesheet
       loads the other — so the shared pair lives here rather than in either.
       The chip's border is target-only and stays in target.css.

       No dark pair: nothing overrides this chip today. PR6 fixes structure
       only; the light-only pastel is PR7's sweep to resolve. */
    --color-evidence-retrieval-bg: #eef2ff;
    --color-evidence-retrieval-text: #3730a3;

    /* Color scheme hint for native form controls and scrollbars. */
    color-scheme: light;
}

/* Compact density — inert until a view opts in with data-density="compact". */
[data-density="compact"] {
    --cell-padding-y: 8px;
    --cell-padding-x: 13px;
    --box-padding: var(--space-4);
}

/* ── Dark theme overrides ────────────────────────────────────────────
   Activated by document.documentElement.dataset.theme = "dark", set by
   the inline boot script in base.html before CSS loads (no FOUC).
   Only the tokens that need to flip are listed; everything inherited
   from :root keeps its semantic role (radii, shadows, font, etc.). */
:root[data-theme="dark"] {
    color-scheme: dark;

    /* Surfaces — slate ramp anchored on the existing nav-bg so the
       header blends seamlessly into the body. */
    --color-bg: #0b1220;
    --color-surface: #131c2e;
    --color-surface-hover: #1c2740;
    /* Elevation tokens flip semantically: "elevated" stays lighter than
       surface, "sunken" stays darker. The per-page gradients and hero
       panels pick these up automatically. */
    --color-surface-elevated: #1c2740;
    --color-surface-sunken: #0b1220;
    --color-border: #3d5070;
    --color-border-light: #2d3f58;

    /* Typography — high-contrast on the dark surface. */
    --color-text: #f1f5f9;
    --color-text-secondary: #cbd5e1;
    --color-text-muted: #94a3b8;
    /* text-inverse stays #ffffff so primary buttons keep their look. */

    /* Brand — slightly brighter so it pops on dark backgrounds. */
    --color-primary: #3b82f6;
    --color-primary-dark: #2563eb;
    --color-primary-light: rgba(59, 130, 246, 0.18);

    /* #249 1단계 — solid-fill role (white text on a brand-colour background:
       buttons, active chips/badges). --color-primary/--color-success/--color-cta
       above are tuned as ACCENT/TEXT colours against the dark surface (that's
       what "brighter so it pops" means) and are used that way in 94+ places —
       darkening them directly would fix white-on-brand contrast but break
       every text/accent usage. These four are a separate role, reusing values
       that already exist elsewhere in the codebase (light theme's own
       --color-primary-dark/--color-cta/--color-cta-hover) rather than
       inventing new colours. See AUDIT4_DARK_CONTRAST_2026_07_24.md. */
    --color-primary-on-fill: #2563eb;
    --color-primary-on-fill-hover: #1d4ed8;
    --color-cta-on-fill: #047857;
    --color-cta-on-fill-hover: #065f46;
    --color-danger-on-fill: #dc2626;
    --color-warning-on-fill: #b45309;

    /* #249 2단계 — accent-on-own-tint role (text-only, e.g. --color-primary
       read as text over var(--color-primary-light)/color-mix()). The
       danger/warning families already have a "strong" bright variant for
       this exact role (--color-danger-strong, --color-warning-strong);
       primary/cta didn't. Values reuse the same blue/green already
       introduced by the #249 1단계 palette (project-css.md), not new colours. */
    --color-primary-strong: #93c5fd;
    --color-cta-strong: #4ade80;

    --color-accent: #22d3ee;
    --color-accent-light: rgba(34, 211, 238, 0.18);

    --color-success: #10b981;
    --color-warning: #fbbf24;
    --color-cta: #10b981;
    --color-cta-hover: #059669;
    --color-cta-light: rgba(16, 185, 129, 0.18);

    --color-danger: #f87171;
    --color-danger-soft: rgba(248, 113, 113, 0.12);
    --color-danger-border: rgba(248, 113, 113, 0.35);
    --color-danger-strong: #fca5a5;
    --color-indigo: #818cf8;
    --color-surface-secondary: #1c2740;
    --color-text-tertiary: #7a8599;
    --color-phase-4: #10b981;
    --color-phase-3: #3b82f6;
    --color-phase-2: #22d3ee;
    --color-phase-default: #64748b;
    --color-warning-soft: rgba(251, 191, 36, 0.12);
    --color-warning-strong: #fcd34d;
    --color-info-soft: rgba(56, 189, 248, 0.12);
    --color-info-strong: #7dd3fc;

    --color-fieldset-bg: #131c2e;
    --color-fieldset-border: #2a3550;

    /* Nav stays dark in both modes — minor tweaks to keep contrast
       against the now-darker body. */
    --color-nav-bg: #07101f;
    --color-nav-bg-soft: #131c2e;
    --color-nav-divider: #2a3550;
    --color-nav-divider-strong: #3a4866;

    /* Hero gradient — keep cinematic but darker. */
    --color-hero-bg: linear-gradient(135deg, #07101f 0%, #131c2e 50%, #0b3a5e 100%);

    /* Shadows — pure black at higher opacity reads better on dark. */
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
    --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.5), 0 2px 4px -2px rgba(0, 0, 0, 0.4);
    --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.55), 0 4px 6px -4px rgba(0, 0, 0, 0.4);
    --shadow-card-hover: 0 12px 24px -4px rgba(0, 0, 0, 0.6);

    /* PR7 3단계 — 다크 고정(pin). --color-popover-shadow was retargeted above
       to color-mix(in srgb, var(--color-text) 10%, transparent), and
       --color-text differs by theme. Without a dark pin, .memo-popover's
       dark shadow would silently pick up --color-text's dark value instead
       of staying at its pre-retarget rgba(0,0,0,0.1) — this line exists
       purely to freeze that render. See PR7_PAGE_TOKEN_CLASSIFICATION.md's
       다크 고정 정책. */
    --color-popover-shadow: rgba(0,0,0,0.1);
}

/* ── light-core4 approved light values (PR7 activation) ──────────────────
   Moved here from pages/landing.css, where PR4 piloted them. The tokens are
   defined by main.css and the rules that read them (.hero, .card-grid, the
   generic surfaces) live here too, so this is where the approved values
   belong — a shared component's value decided in a page stylesheet splits
   "where is this token set?" across two files.

   THE :not() SCOPE IS A CONTRACT, NOT A STYLE CHOICE. Eleven of these have a
   :root[data-theme="dark"] counterpart above and would be shadowed anyway, but
   --radius and fifteen --color-hero-* tokens do not. Promote this block to a
   plain :root and those leak into dark: the hero turns light and the radius
   changes. PR7 retargets light only; dark keeps its current appearance, which
   is why --radius is 8px here and stays 10px in dark.

   The only live surface reading --color-hero-* is the landing route; book.html
   carries the same class but /book is a redirect (PR7_ROUTE_INVENTORY.md).
   Rule-level pilot overrides (.hero-chip:hover, .hero-search, focus-visible)
   stay in landing.css — they are rules, not token decisions. */
:root:not([data-theme="dark"]) {
    /* Single deep-teal accent family, replacing the blue. */
    --color-primary: #087e73;
    --color-primary-dark: #06665e;
    --color-primary-light: #e8f5f2;

    --color-bg: #f6f8fa;
    --color-surface-secondary: #f1f5f7;

    --color-text: #17212b;
    --color-text-secondary: #41505f;
    --color-text-muted: #5c6a75;

    --color-border: #c4cfd7;
    --color-border-light: #dfe6ea;

    --radius: 8px;
    --shadow-lg: 0 12px 34px rgba(20, 35, 46, 0.10);

    /* The hero band flips from the dark gradient to the page surface, so its
       inner elements stop being white-on-dark. */
    --color-hero-bg: var(--color-bg);
    --color-hero-text: var(--color-text);
    --color-hero-text-soft: var(--color-text-secondary);
    --color-hero-text-muted: var(--color-text-muted);
    --color-hero-field-bg: var(--color-surface);
    --color-hero-field-bg-focus: var(--color-surface);
    --color-hero-field-border: var(--color-border);
    --color-hero-chip-bg: var(--color-surface);
    --color-hero-chip-bg-hover: var(--color-surface);
    --color-hero-chip-border: var(--color-border);
    /* Panels on the band: the white overlays that worked on dark are
       invisible on a light band, so they become a real surface + border. */
    --color-hero-panel-bg: var(--color-surface);
    --color-hero-panel-border: var(--color-border-light);
    --color-hero-badge-border: var(--color-border);
    --color-hero-badge-text: var(--color-text-secondary);
    /* The decorative glows were tuned for the dark band; on a light one they
       read as smudges. */
    --color-hero-glow-1: transparent;
    --color-hero-glow-2: transparent;

    /* PR7 4단계 route sweep — these four were never covered by the canonical
       activation above, so they kept their pre-PR7 base :root values (tuned
       for the dark surface, see the base block's "slightly brighter so it
       pops on dark backgrounds" note). Against light surfaces those values
       fall short of WCAG AA text contrast; --color-text-tertiary was already
       flagged as a contrast-deficient candidate in the original PR7 plan. */
    --color-danger: #dc2626;
    --color-accent: #0e7490;
    --color-phase-4: #047857;
    --color-phase-2: #0e7490;
    --color-text-tertiary: #6b7280;
}

html {
    font-size: 16px;
    scroll-behavior: smooth;
}

body {
    font-family: var(--font-sans);
    color: var(--color-text);
    background: var(--color-bg);
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
    /* Sticky footer. 짧은 페이지(/chembl, /start, /privacy, 404)에서 어두운 푸터가
       화면 중간에 떠 있고 그 아래로 밝은 body 배경이 드러나던 것을 막는다.
       body min-height 가 0 이라 문서가 뷰포트를 채우지 못하는 것이 원인이었다. */
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}

/* 본문이 남은 공간을 가져가고, 헤더·푸터는 자기 높이를 지킨다.
   flex-shrink: 0 을 두지 않으면 내용이 긴 페이지에서 눌린다. */
body > main {
    flex: 1 0 auto;
}

body > .site-nav,
body > .site-footer {
    flex: 0 0 auto;
}

a {
    color: var(--color-primary);
    text-decoration: none;
    transition: color var(--transition);
}

a:hover {
    color: var(--color-primary-dark);
}

/* --- Typography --- */
h1,
h2,
h3,
h4 {
    font-weight: 600;
    line-height: 1.3;
    letter-spacing: -0.01em;
}

h1 {
    font-size: 2rem;
}

h2 {
    font-size: 1.5rem;
}

h3 {
    font-size: 1.125rem;
}

/* --- Container --- */
.container {
    max-width: var(--container-max);
    margin: 0 auto;
    padding: 0 1.5rem;
}

/* ==========================================================================
   Navigation
   ========================================================================== */
.site-nav {
    background: var(--color-nav-bg);
    position: sticky;
    top: 0;
    z-index: 100;
    border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.site-nav .container {
    display: flex;
    align-items: center;
    height: 56px;
    gap: 0;
}

.nav-brand {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    color: var(--color-text-inverse);
    font-weight: 700;
    font-size: 1.125rem;
    letter-spacing: -0.02em;
    margin-right: 2rem;
    flex-shrink: 0;
}

.nav-brand .brand-icon {
    width: 28px;
    height: 28px;
    background: var(--color-nav-accent);
    border-radius: 6px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.75rem;
    font-weight: 800;
    color: var(--color-nav-bg);
}

.nav-brand .brand-logo {
    width: 32px;
    height: 32px;
    object-fit: contain;
    border-radius: 6px;
    display: block;
}

.nav-links {
    display: flex;
    align-items: center;
    gap: 0;
    overflow-x: auto;
    scrollbar-width: none;
    flex: 1;
    min-width: 0;
}

.nav-links::-webkit-scrollbar {
    display: none;
}

.nav-links > a {
    color: var(--color-nav-text);
    font-size: 0.8125rem;
    font-weight: 500;
    padding: 0.375rem 0.375rem;
    border-radius: var(--radius-sm);
    white-space: nowrap;
    transition: all var(--transition);
}

.nav-links > a:hover {
    color: var(--color-nav-text-hover);
    background: rgba(255, 255, 255, 0.08);
}

.nav-links > a.active {
    color: var(--color-nav-accent);
    background: rgba(56, 189, 248, 0.1);
}

.nav-divider {
    width: 1px;
    height: 20px;
    background: rgba(255, 255, 255, 0.12);
    margin: 0 0.25rem;
    flex-shrink: 0;
}

/* Mobile nav toggle */
.nav-toggle {
    display: none;
    background: none;
    border: none;
    color: var(--color-nav-text);
    font-size: 1.5rem;
    cursor: pointer;
    padding: 0.25rem;
    margin-left: auto;
}

/* --- Nav Right (lang + version) --- */
.nav-right {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-left: 0.75rem;
    flex-shrink: 0;
}

.lang-select {
    appearance: none;
    -webkit-appearance: none;
    background: rgba(255, 255, 255, 0.08);
    color: var(--color-nav-text);
    border: 1px solid rgba(255, 255, 255, 0.15);
    border-radius: var(--radius-sm);
    padding: 0.2rem 0.5rem;
    font-size: 0.6875rem;
    font-weight: 600;
    font-family: var(--font-sans);
    cursor: pointer;
    transition: all var(--transition);
}

.lang-select:hover {
    background: rgba(255, 255, 255, 0.14);
    border-color: rgba(255, 255, 255, 0.25);
}

.lang-select:focus {
    outline: none;
    border-color: var(--color-nav-accent);
}

.lang-select option {
    background: var(--color-nav-bg);
    color: var(--color-text-inverse);
}

.nav-version {
    font-size: 0.6875rem;
    color: var(--color-nav-accent);
    background: rgba(56, 189, 248, 0.12);
    padding: 0.125rem 0.5rem;
    border-radius: 999px;
    flex-shrink: 0;
    font-weight: 600;
}

/* ==========================================================================
   Hero Section (Landing)
   ========================================================================== */
.hero {
    background: var(--color-hero-bg);
    padding: 4rem 0 3.5rem;
    color: var(--color-hero-text);
    text-align: center;
    position: relative;
    overflow: hidden;
}

.hero::before {
    content: '';
    position: absolute;
    inset: 0;
    background:
        radial-gradient(ellipse 60% 50% at 20% 60%, var(--color-hero-glow-1) 0%, transparent 70%),
        radial-gradient(ellipse 40% 40% at 80% 30%, var(--color-hero-glow-2) 0%, transparent 70%);
    pointer-events: none;
}

.hero-content {
    position: relative;
    z-index: 1;
}

.hero h1 {
    font-size: 2.5rem;
    font-weight: 700;
    letter-spacing: -0.03em;
    margin-bottom: 0.75rem;
}

.hero-subtitle {
    font-size: 1.125rem;
    color: var(--color-hero-text-soft);
    max-width: 560px;
    margin: 0 auto 2rem;
    line-height: 1.7;
}

.hero-search {
    display: flex;
    /* 히어로 컬럼(680px)을 **가득 채운다.**
       - width 없이 max-width 만 두면 flex 안에서 내용 폭으로 줄어든다(실측 308px)
       - 560px 로 두면 컬럼보다 좁아 제목·본문과 왼쪽 모서리가 어긋난 채 떠 보인다
         (실측: 폼 x=776 vs h1 x=716)
       첫 과업이 "검색해 보기" 인 화면에서 입력창은 컬럼과 같은 폭이어야 의도적으로
       보인다. 상한을 컬럼 폭으로 두어 더 넓은 부모에서도 과하게 늘어나지 않는다. */
    width: 100%;
    max-width: 680px;
    margin: 0 0 1.5rem;
    gap: 0;
    background: var(--color-hero-field-bg);
    border: 1px solid var(--color-hero-field-border);
    border-radius: var(--radius-md);
    overflow: hidden;
    backdrop-filter: blur(8px);
    transition: border-color var(--transition);
}

.hero-search:focus-within {
    border-color: var(--color-nav-accent);
    background: var(--color-hero-field-bg-focus);
}

.hero-search input {
    flex: 1;
    padding: 0.875rem 1.25rem;
    background: transparent;
    border: none;
    color: var(--color-hero-text);
    font-size: 0.9375rem;
    outline: none;
}

.hero-search input::placeholder {
    color: var(--color-text-secondary);
}

.hero-search button {
    padding: 0.875rem 1.5rem;
    background: var(--color-primary);
    color: var(--color-text-inverse);
    border: none;
    font-weight: 600;
    font-size: 0.875rem;
    cursor: pointer;
    transition: background var(--transition);
}

.hero-search button:hover {
    background: var(--color-primary-dark);
}

/* #249 1단계 — white text on --color-primary fails WCAG AA in dark (3.67:1).
   :hover already swaps to --color-primary-dark (passes), only rest state needs it. */
:root[data-theme="dark"] .hero-search button {
    background: var(--color-primary-on-fill);
}

.hero-stats {
    display: flex;
    justify-content: center;
    gap: 2.5rem;
    margin-top: 2.5rem;
    flex-wrap: wrap;
}

.hero-stat {
    text-align: center;
}

.hero-stat-value {
    font-size: 1.5rem;
    font-weight: 700;
    color: var(--color-hero-text);
    letter-spacing: -0.02em;
}

.hero-stat-label {
    font-size: 0.75rem;
    color: var(--color-hero-text-soft);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    margin-top: 0.125rem;
}

.hero-examples {
    display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap;
    margin-top: 1.25rem; justify-content: center;
}
.hero-examples-label { font-size: 0.875rem; color: var(--color-hero-text-muted); }
.hero-chip {
    font-size: 0.8125rem; padding: 0.375rem 0.75rem;
    background: var(--color-hero-chip-bg); color: var(--color-hero-text);
    border: 1px solid var(--color-hero-chip-border); border-radius: 999px;
    text-decoration: none; transition: background 0.15s;
}
.hero-chip:hover { background: var(--color-hero-chip-bg-hover); }

/* ==========================================================================
   Feature Cards Grid (Landing)
   ========================================================================== */
.section {
    padding: 3rem 0;
}

/* .section-header → .section-head (components.css §20) */
/* .section-label → .kicker (components.css §19) */

.card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 1rem;
}

.feature-card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: 1.5rem;
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    transition: all var(--transition);
    cursor: pointer;
    text-decoration: none;
    color: inherit;
}

.feature-card:hover {
    border-color: var(--color-primary);
    box-shadow: var(--shadow-card-hover);
    transform: translateY(-2px);
    color: inherit;
}

.card-icon {
    width: 40px;
    height: 40px;
    border-radius: var(--radius-sm);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.25rem;
    flex-shrink: 0;
}

.card-icon.blue {
    background: #eff6ff;
    color: #2563eb;
}

.card-icon.cyan {
    background: #ecfeff;
    color: #0e7490;
}

.card-icon.green {
    background: #ecfdf5;
    color: #047857;
}

.card-icon.orange {
    background: #fff7ed;
    color: #c2410c;
}

.card-icon.purple {
    background: #f5f3ff;
    color: #7c3aed;
}

.card-icon.rose {
    background: #fff1f2;
    color: #e11d48;
}

.card-icon.teal {
    background: #f0fdfa;
    color: #0d9488;
}

.card-icon.indigo {
    background: #eef2ff;
    color: #4f46e5;
}

/* card-icon dark mode overrides */
:root[data-theme="dark"] .card-icon.blue   { background: rgba(59, 130, 246, 0.15); color: #93c5fd; }
:root[data-theme="dark"] .card-icon.cyan   { background: rgba(34, 211, 238, 0.15); color: #67e8f9; }
:root[data-theme="dark"] .card-icon.green  { background: rgba(16, 185, 129, 0.15); color: #6ee7b7; }
:root[data-theme="dark"] .card-icon.orange { background: rgba(249, 115, 22, 0.15); color: #fdba74; }
:root[data-theme="dark"] .card-icon.purple { background: rgba(139, 92, 246, 0.15); color: #c4b5fd; }
:root[data-theme="dark"] .card-icon.rose   { background: rgba(244, 63, 94, 0.15);  color: #fda4af; }
:root[data-theme="dark"] .card-icon.teal   { background: rgba(20, 184, 166, 0.15); color: #5eead4; }
:root[data-theme="dark"] .card-icon.indigo { background: rgba(99, 102, 241, 0.15); color: #a5b4fc; }

.card-title {
    font-size: 0.9375rem;
    font-weight: 600;
    color: var(--color-text);
}

.card-desc {
    font-size: 0.8125rem;
    color: var(--color-text-secondary);
    line-height: 1.5;
    flex: 1;
}

/* .card-tag → .type-badge (components.css §19) */

/* Highlight card (search) */
.feature-card.highlight {
    border-color: var(--color-primary);
    background: linear-gradient(135deg, var(--color-primary-light) 0%, var(--color-surface) 100%);
    grid-column: 1 / -1;
    flex-direction: row;
    align-items: center;
    padding: 2rem;
}

.feature-card.highlight .card-icon {
    width: 56px;
    height: 56px;
    font-size: 1.5rem;
}

.feature-card.highlight .card-content {
    flex: 1;
}

.feature-card.highlight .card-title {
    font-size: 1.125rem;
}

.feature-card.highlight .card-desc {
    font-size: 0.875rem;
}

.card-arrow {
    color: var(--color-primary);
    font-size: 1.25rem;
    opacity: 0;
    transition: all var(--transition);
    flex-shrink: 0;
}

.feature-card:hover .card-arrow {
    opacity: 1;
    transform: translateX(4px);
}

/* ==========================================================================
   Footer
   ========================================================================== */
.site-footer {
    background: var(--color-nav-bg);
    color: var(--color-nav-text-soft);
    padding: 2rem 0;
    font-size: 0.8125rem;
    margin-top: 2rem;
}

.footer-content {
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: 1rem;
}

.footer-links {
    display: flex;
    gap: 1.25rem;
    flex-wrap: wrap;
}

.footer-links a {
    color: #cbd5e1;
    font-size: 0.8125rem;
    transition: color var(--transition);
}

.footer-links a:hover {
    color: #e2e8f0;
}

.footer-copy {
    color: #cbd5e1;
}

.footer-copy a {
    color: #bfdbfe;
}

/* ==========================================================================
   Page Content (Tool pages, info pages)
   ========================================================================== */
.page-content {
    padding: 2rem 0;
}

.page-content .container {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    padding: 2rem;
}

/* .tool-page, .tool-page h1 → tool.css (base_tool.html 전용) */

/* .tool-body label → .form-label (components.css §20) */
/* .tool-body input/textarea/select → .form-input (components.css §20) */
/* .tool-body button → .btn-primary (components.css §20); page overrides in tool.css */

.form-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 0.25rem 1rem;
}

.form-grid label {
    margin-top: 0.5rem;
}

/* Results Box */
.results-box {
    margin-top: 1rem;
    padding: 1rem;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
}

/* 계산 전에는 상자를 그리지 않는다. 내용은 JS 가 채우므로 서버에 조건부 렌더의
   근거가 없고, 그대로 두면 padding·테두리만 남아 34px 빈 상자가 보인다.
   ★ `:empty` 는 자식 노드가 하나도 없을 때만 성립한다 — 템플릿의 `></div>` 사이에
   공백을 넣으면 조용히 무력해진다(`.tool-cta` 가 그래서 이 방법을 못 썼다).
   `test_empty_results_box.py` ERB-02 가 그 전제를 고정한다. */
.results-box:empty {
    display: none;
}

.results-box h3 {
    margin-bottom: 0.75rem;
    color: var(--color-text);
}

/* .tool-body table → tool.css §table (page-specific overrides) */

/* Tabs */
.tabs {
    display: flex;
    gap: 0.25rem;
    border-bottom: 2px solid var(--color-border);
    margin-bottom: 1rem;
}

.tab-btn {
    padding: 0.5rem 1rem;
    background: none;
    border: none;
    border-bottom: 2px solid transparent;
    margin-bottom: -2px;
    font-size: 0.875rem;
    font-weight: 500;
    color: var(--color-text-secondary);
    cursor: pointer;
    transition: all var(--transition);
    font-family: var(--font-sans);
}

.tab-btn:hover {
    color: var(--color-text);
    background: var(--color-surface-hover);
}

.tab-btn.active {
    color: var(--color-primary);
    border-bottom-color: var(--color-primary);
    font-weight: 600;
}

/* Warning / Error */
.warning {
    padding: 0.75rem 1rem;
    background: #fff7ed;
    border: 1px solid #fed7aa;
    border-radius: var(--radius-sm);
    color: #9a3412;
    font-size: 0.875rem;
    margin-top: 0.5rem;
}

.error {
    padding: 0.75rem 1rem;
    background: #fef2f2;
    border: 1px solid #fecaca;
    border-radius: var(--radius-sm);
    color: #991b1b;
    font-size: 0.875rem;
    margin-top: 0.5rem;
}

/* #249 1단계 — light-only literal pastel, no dark override (project-css.md
   red palette). */
:root[data-theme="dark"] .error {
    background: rgba(239, 68, 68, 0.16);
    border-color: var(--color-danger-border);
    color: var(--color-danger-strong);
}

/* .tool-cta, .tool-cta a → tool.css (base_tool.html 전용) */

/* Compare layout */
.compare-inputs {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.compare-inputs > div {
    flex: 1;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-width: 0;
}

.compare-inputs label {
    flex-shrink: 0;
    white-space: nowrap;
    margin-bottom: 0;
}

@media (max-width: 640px) {
    .compare-inputs {
        flex-direction: column;
        align-items: stretch;
    }
    .compare-inputs > div {
        flex: none;
    }
}

.structures-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1.5rem;
    margin: 1rem 0;
}

.structure-col {
    text-align: center;
}

.structure-col code {
    display: block;
    font-size: 0.75rem;
    color: var(--color-text-secondary);
    margin: 0.25rem 0 0.5rem;
    word-break: break-all;
}

.structure-image svg {
    max-width: 100%;
    height: auto;
}

/* Compare table */
.compare-table {
    margin-top: 1rem;
}

.badge-drug-like {
    background: #ecfdf5;
    color: #059669;
}

.badge-borderline {
    background: #fff7ed;
    color: #d97706;
}

.badge-poor {
    background: #fef2f2;
    color: #dc2626;
}

/* Properties table */
.properties-table {
    margin-top: 1rem;
}

/* Heatmap grid */
.heatmap {
    margin: 1rem 0;
    overflow-x: auto;
}

/* Editor nav */
.editor-nav button {
    background: var(--color-surface);
    color: var(--color-primary);
    border: 1px solid var(--color-primary);
}

.editor-nav button:hover {
    background: var(--color-primary);
    color: var(--color-text-inverse);
}

/* #249 1단계 — white text on --color-primary fails WCAG AA in dark (3.67:1). */
:root[data-theme="dark"] .editor-nav button:hover {
    background: var(--color-primary-on-fill);
}

/* ==========================================================================
   Info Pages (glossary, resources, data-sources, terms, feed, qna)
   ========================================================================== */
.info-page {
    max-width: var(--container-max);
    margin: 0 auto;
    padding: 1.75rem 1.5rem 3.25rem;
    display: grid;
    /* PR7 4단계: without an explicit column track, a grid container's single
       implicit column sizes to its widest child's min-content — on feed/
       approvals that child's own nested grid (wide stat values, long option
       text) has a min-content wider than the viewport, blowing out .info-page
       itself at narrow widths. minmax(0, 1fr) is the standard fix: it lets
       the column (and everything in it) shrink below that min-content. */
    grid-template-columns: minmax(0, 1fr);
    gap: 1.5rem;
}

.info-page h1 {
    font-size: clamp(2rem, 3vw, 2.5rem);
    margin: 0.35rem 0 0.75rem;
}

.info-page .page-desc {
    color: var(--color-text-secondary);
    font-size: 1rem;
    line-height: 1.75;
    max-width: 64ch;
}

/* .info-hero → .grid-2col (components.css §19) */

.info-hero-main {
    position: relative;
    overflow: hidden;
    background: linear-gradient(135deg, #ffffff 0%, #f8fbff 58%, #eef6ff 100%);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    padding: 1.75rem;
    box-shadow: var(--shadow-sm);
}

/* .info-kicker → .kicker (components.css §19) */

.info-hero-copy {
    display: grid;
    gap: 0.75rem;
}

.info-hero-panel {
    display: grid;
    /* ★ 암묵 트랙은 `auto` 라 **min-content 자동 최소값**을 존중한다. 그래서 패널이
       340px 인데 트랙이 614px 로 잡혀 자식이 밖으로 나갔고, 페이지가 가로로
       249px 스크롤됐다(L-11 D-13). `components.css` 의 `.grid-2col` 주석이 같은
       부류를 이미 설명한다.

       `minmax(0, 1fr)` 로 그 바닥을 없앤다. */
    grid-template-columns: minmax(0, 1fr);
    gap: 0.9rem;
    align-content: start;
    padding: 1.35rem;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
}

/* ── Open DB 컨텍스트 카드의 축소 규칙 ─────────────────────────────────────
   ★ 처음에는 이 규칙을 **호스트 패널**(`.info-hero-panel`)에 걸었다. `/assay`·
     `/feed`·`/compound` 는 그것으로 닫혔지만 `/monitoring`(222px)·`/approvals`
     (226px)는 **그대로였다** — 두 화면은 `.monitoring-side` 나 일반 `.card` 를
     사이드바로 쓰기 때문이다.

     그래서 규칙을 **블록 자체**에 붙인다. 이러면 어느 컨테이너에 들어가도 따라간다.
     실측: monitoring 222 → 0, approvals 226 → 0 (사이드바별 규칙 없이).

   왜 하위 트리 전체인가 — 트랙 하나만 고쳐서는 부족했다. `.surface-open-db-*` 의
   중첩 그리드가 층마다 min-content 바닥을 갖고 있어, `/assay` 기준 249 → 53px
   까지만 줄었다. */
.surface-open-db-context,
.surface-open-db-context * {
    min-width: 0;
}

.surface-open-db-context {
    grid-template-columns: minmax(0, 1fr);
}

/* `.info-pill` 은 `nowrap` 이라 340px 사이드바에서 221px 짜리 출처 라벨이 최소 폭을
   밀어 올렸다. 넓은 본문에서는 한 줄이 맞으므로 **이 카드 안에서만** 줄바꿈한다.
   실측: 24px → 0px. */
.surface-open-db-context .info-pill {
    white-space: normal;
}

/* ★ 위 규칙이 만든 회귀를 함께 닫는다.

   하위 트리 `min-width: 0` 이 상태 칩(`부분 컨텍스트`)을 43px 로 짓눌러 **세 줄
   (높이 77px)로 쪼갰다.** 넘침 0 · 넘치는 요소 0 이라는 **수치는 전부 통과한
   상태**였다 — 스크린샷을 보지 않았으면 그대로 배포됐다.

   짧은 상태 라벨이므로 칩은 줄이지 않고 헤더가 줄바꿈하게 둔다. */
.surface-open-db-head {
    flex-wrap: wrap;
}

.surface-open-db-state {
    flex-shrink: 0;
    white-space: nowrap;
}

.info-panel-title {
    font-size: 0.8125rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--color-text-muted);
}

.info-panel-copy {
    font-size: 0.9rem;
    color: var(--color-text-secondary);
    line-height: 1.7;
}

.info-stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: 0.75rem;
}

.info-stat {
    padding: 0.95rem 1rem;
    border-radius: var(--radius-md);
    border: 1px solid var(--color-border-light);
    background: rgba(255, 255, 255, 0.86);
}

/* .info-stat-label → .text-kicker (components.css §19) */

.info-stat-value {
    display: block;
    font-size: 1.3rem;
    font-weight: 700;
    color: var(--color-text);
}

.info-stat-detail {
    display: block;
    margin-top: 0.2rem;
    font-size: 0.8rem;
    color: var(--color-text-secondary);
}

.info-callout {
    padding: 1rem 1.1rem;
    border-radius: var(--radius-md);
    border: 1px solid #dbeafe;
    background: linear-gradient(135deg, #f8fbff 0%, #eff6ff 100%);
    font-size: 0.9rem;
    color: var(--color-text-secondary);
    line-height: 1.7;
    margin-bottom: 1.25rem;
}

.info-callout--success {
    border-color: #bbf7d0;
    background: #f0fdf4;
}

:root[data-theme="dark"] .info-hero-main {
    border-color: rgba(59, 130, 246, 0.18);
    background:
        linear-gradient(135deg, var(--color-surface) 0%, var(--color-surface-elevated) 100%);
}

:root[data-theme="dark"] .info-stat {
    background: var(--color-surface);
    border-color: var(--color-border-light);
}

:root[data-theme="dark"] .info-pill {
    background: var(--color-primary-light);
    border-color: rgba(59, 130, 246, 0.35);
    color: #93c5fd;
}

:root[data-theme="dark"] .info-callout {
    border-color: var(--color-border);
    background: var(--color-surface);
}

:root[data-theme="dark"] .info-callout--success {
    border-color: rgba(16, 185, 129, 0.35);
    background: var(--color-surface);
}

/* .info-card → .card (components.css §19) */

.info-card--compact {
    gap: 0.55rem;
    padding: 0.95rem 1rem;
    border-radius: var(--radius-md);
}

.info-card-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 0.75rem;
}

.info-card-title {
    font-size: 1rem;
    font-weight: 700;
    line-height: 1.45;
    color: var(--color-text);
}

.info-card-meta {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
}

.info-card-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.18rem 0.52rem;
    border-radius: 999px;
    border: 1px solid var(--color-border-light);
    background: var(--color-bg);
    color: var(--color-text-secondary);
    font-size: 0.74rem;
    font-weight: 600;
    line-height: 1.2;
    flex-shrink: 0;
    white-space: nowrap;
}

.info-card-summary {
    padding: 0.9rem 0.95rem;
    border-radius: var(--radius-md);
    border: 1px solid var(--color-border-light);
    background: var(--color-surface-elevated);
    color: var(--color-text-secondary);
    font-size: 0.88rem;
    line-height: 1.65;
}

.info-card-actions {
    display: flex;
    gap: 0.75rem;
    align-items: center;
    flex-wrap: wrap;
    margin-top: 0.75rem;
}

.info-card-link {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    color: var(--color-primary);
    text-decoration: none;
    font-size: 0.84rem;
    font-weight: 700;
}

.info-card-link:hover {
    text-decoration: underline;
}

.info-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.35rem;
    padding: 0.62rem 1rem;
    border-radius: 999px;
    border: 1px solid var(--color-primary);
    background: var(--color-primary);
    color: var(--color-text-inverse);
    font: inherit;
    font-size: 0.875rem;
    font-weight: 700;
    text-decoration: none;
    cursor: pointer;
    transition: background var(--transition), border-color var(--transition), color var(--transition), box-shadow var(--transition), transform var(--transition);
}

.info-button:hover {
    background: var(--color-primary-dark);
    border-color: var(--color-primary-dark);
    color: var(--color-text-inverse);
    box-shadow: var(--shadow-sm);
}

/* #249 1단계 — white text on --color-primary fails WCAG AA in dark (3.67:1).
   :hover already swaps to --color-primary-dark (passes), only rest state needs it. */
:root[data-theme="dark"] .info-button {
    background: var(--color-primary-on-fill);
    border-color: var(--color-primary-on-fill);
}

.info-button--secondary {
    background: var(--color-surface);
    border-color: var(--color-border);
    color: var(--color-text);
}

.info-button--secondary:hover {
    background: var(--color-surface);
    border-color: var(--color-primary);
    color: var(--color-primary);
    box-shadow: var(--shadow-sm);
}

.info-button:disabled {
    opacity: 0.5;
    cursor: not-allowed;
    box-shadow: none;
    transform: none;
}

.info-alert {
    padding: 0.8rem 1rem;
    border-radius: var(--radius-md);
    border: 1px solid transparent;
    font-size: 0.9rem;
    line-height: 1.65;
    margin-bottom: 0.85rem;
}

.info-alert--success {
    background: #ecfdf5;
    border-color: #86efac;
    color: #166534;
}

.info-alert--error {
    background: #fef2f2;
    border-color: #fca5a5;
    color: #991b1b;
}

.info-status {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.18rem 0.52rem;
    border-radius: 999px;
    border: 1px solid var(--color-border-light);
    background: var(--color-bg);
    color: var(--color-text-secondary);
    font-size: 0.67rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    line-height: 1.2;
    text-transform: uppercase;
    white-space: nowrap;
}

.info-status--open {
    background: #dbeafe;
    border-color: #bfdbfe;
    color: #1e40af;
}

.info-status--answered,
.info-status--resolved {
    background: #ecfdf5;
    border-color: #bbf7d0;
    color: #166534;
}

.info-status--closed {
    background: var(--color-bg);
    border-color: var(--color-border);
    color: var(--color-text-muted);
}

:root[data-theme="dark"] .info-status--open {
    background: rgba(37, 99, 235, 0.18);
    border-color: rgba(59, 130, 246, 0.3);
    color: #93c5fd;
}

:root[data-theme="dark"] .info-status--answered,
:root[data-theme="dark"] .info-status--resolved {
    background: rgba(22, 101, 52, 0.2);
    border-color: rgba(34, 197, 94, 0.25);
    color: #86efac;
}

.info-action-row {
    display: flex;
    gap: 0.75rem;
    flex-wrap: wrap;
    margin-top: 0.25rem;
}

.info-link-card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 0.9rem;
}

.info-link-card {
    display: grid;
    gap: 0.55rem;
    min-height: 100%;
    padding: 1.05rem 1.1rem;
    border-radius: var(--radius-md);
    border: 1px solid var(--color-border);
    background: linear-gradient(180deg, #ffffff 0%, #f9fbfd 100%);
    color: inherit;
    text-decoration: none;
    transition: transform var(--transition), box-shadow var(--transition), border-color var(--transition);
}

.info-link-card:hover {
    color: inherit;
    border-color: rgba(37, 99, 235, 0.3);
    box-shadow: var(--shadow-md);
    transform: translateY(-2px);
}

:root[data-theme="dark"] .info-link-card {
    background: var(--color-surface);
    border-color: var(--color-border);
    box-shadow: var(--shadow-sm);
}

:root[data-theme="dark"] .info-link-card:hover {
    border-color: rgba(59, 130, 246, 0.28);
    box-shadow: var(--shadow-md);
}

/* .info-link-eyebrow → .text-kicker (components.css §19) */

.info-link-title {
    font-size: 1rem;
    font-weight: 700;
    color: var(--color-text);
}

.info-link-desc {
    font-size: 0.875rem;
    line-height: 1.65;
    color: var(--color-text-secondary);
}

.info-link-action {
    font-size: 0.8125rem;
    font-weight: 700;
    color: var(--color-primary);
}

/* .info-section → .card (components.css §19) */

/* .info-section-header → .section-head (components.css §20) */
.info-section-title-block {
    display: grid;
    gap: 0.35rem;
}

/* .info-section-kicker → .text-kicker (components.css §19) */

.info-section h2,
.info-section-title {
    font-size: 1.25rem;
    margin: 0;
}

.info-section-copy {
    font-size: 0.92rem;
    color: var(--color-text-secondary);
    line-height: 1.7;
    max-width: 64ch;
}

.info-list {
    list-style: none;
    display: grid;
    gap: 0.8rem;
    margin: 0;
    padding: 0;
}

.info-list li {
    position: relative;
    padding-left: 1rem;
    font-size: 0.94rem;
    color: var(--color-text-secondary);
    line-height: 1.75;
}

.info-list li::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0.72rem;
    width: 0.4rem;
    height: 0.4rem;
    border-radius: 999px;
    background: var(--color-primary);
}

/* PR7 4단계: inline links in body prose (terms, manual) relied on color alone
   (var(--color-primary) vs. var(--color-text-secondary)) to read as links,
   which axe's link-in-text-block flags regardless of the exact contrast
   number — underline is the standard fix, not a contrast tweak. */
.info-section-copy a,
.info-list li a,
.info-callout a {
    text-decoration: underline;
}

.info-pill-list {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
}

.info-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.42rem 0.72rem;
    border-radius: 999px;
    border: 1px solid #dbeafe;
    background: #f8fbff;
    color: var(--color-primary-dark);
    font-size: 0.8rem;
    font-weight: 600;
    text-decoration: none;
    white-space: nowrap;
}

.info-table-shell {
    overflow-x: auto;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface);
}

.info-grid-2 {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1rem;
}

/* 본문 소제목이 앞 블록에 달라붙지 않게 띄운다.
   `h3` 에는 여백 규칙이 없고 `.info-list` 는 `margin: 0` 이라, 목록 항목끼리는
   `gap: 0.8rem` 으로 벌어지는데 소제목만 앞 문단에 붙어 버렸다(운영 관측 2026-08-17).
   섹션 첫 소제목은 위 여백이 필요 없으므로 **앞에 형제가 있을 때만** 적용한다. */
.info-grid-2 * + h3 {
    margin-top: 1.5rem;
}

.info-grid-2 h3 {
    margin-bottom: 0.5rem;
}

.info-grid-3 {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1rem;
}

/* Glossary */
.glossary-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
    gap: 1rem;
}

.glossary-card {
    display: grid;
    gap: 0.7rem;
    background: linear-gradient(180deg, #ffffff 0%, #f9fbfd 100%);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: 1.1rem 1.15rem;
    transition: border-color var(--transition), box-shadow var(--transition), transform var(--transition);
    box-shadow: var(--shadow-sm);
}

.glossary-card dl {
    display: grid;
    gap: 0.7rem;
    margin: 0;
}

.glossary-card:hover {
    border-color: rgba(37, 99, 235, 0.32);
    box-shadow: var(--shadow-md);
    transform: translateY(-2px);
}

.glossary-card dt {
    font-weight: 700;
    color: var(--color-text);
    font-size: 1rem;
}

.glossary-card dd {
    font-size: 0.875rem;
    color: var(--color-text-secondary);
    line-height: 1.65;
}

.glossary-card a {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.8125rem;
    font-weight: 700;
    color: var(--color-primary);
}

/* Resource cards */
.resource-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
    gap: 1rem;
}

.resource-card {
    background: linear-gradient(180deg, #ffffff 0%, #f9fbfd 100%);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: 1.15rem 1.2rem;
    text-decoration: none;
    color: inherit;
    transition: transform var(--transition), box-shadow var(--transition), border-color var(--transition);
    display: grid;
    gap: 0.55rem;
    box-shadow: var(--shadow-sm);
}

.resource-card:hover {
    border-color: rgba(37, 99, 235, 0.3);
    box-shadow: var(--shadow-md);
    transform: translateY(-2px);
    color: inherit;
}

.resource-card .rc-name {
    font-weight: 700;
    font-size: 1rem;
    color: var(--color-text);
}

.resource-card .rc-desc {
    font-size: 0.875rem;
    color: var(--color-text-secondary);
    line-height: 1.65;
}

.resource-card .rc-badge {
    display: inline-block;
    width: fit-content;
    font-size: 0.6875rem;
    font-weight: 700;
    padding: 0.22rem 0.58rem;
    border-radius: 999px;
}

/* Data sources table */
.info-page table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.875rem;
}

.info-page table th,
.info-page table td {
    padding: 0.625rem 0.75rem;
    text-align: left;
    border-bottom: 1px solid var(--color-border-light);
}

.info-page table th {
    font-weight: 600;
    color: var(--color-text-secondary);
    font-size: 0.8125rem;
    background: #f8fafc;
}

.info-page table a {
    font-weight: 500;
}

@media (max-width: 900px) {
    /* .info-hero → .grid-2col responsive handled in components.css */
    .info-grid-2,
    .info-grid-3 {
        grid-template-columns: 1fr;
    }
}

@media (max-width: 768px) {
    .info-page {
        padding: 1.25rem 1rem 2.5rem;
    }

    .info-hero-main,
    .info-hero-panel {
        padding: 1.2rem;
    }

    /* .info-section-header responsive → covered by .section-head @media in components.css §20 */
}

/* ==========================================================================
   Privacy Page
   ========================================================================== */
.privacy-header {
    margin-bottom: 2rem;
}

.privacy-meta {
    display: flex;
    gap: 0.5rem;
    align-items: center;
    font-size: 0.8125rem;
    color: var(--color-text-tertiary);
    margin-top: 0.5rem;
}

.privacy-meta-sep {
    opacity: 0.4;
}

/* Quick summary cards */
.privacy-summary {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    padding: 1.5rem;
    margin-bottom: 2rem;
}

.privacy-summary-title {
    font-weight: 600;
    font-size: 0.875rem;
    color: var(--color-text-secondary);
    margin-bottom: 1rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.privacy-summary-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 1rem;
}

.privacy-summary-item {
    text-align: center;
    padding: 0.75rem 0.5rem;
}

.privacy-summary-icon {
    color: var(--color-primary);
    margin-bottom: 0.5rem;
}

.privacy-summary-label {
    font-weight: 600;
    font-size: 0.875rem;
    margin-bottom: 0.25rem;
}

.privacy-summary-detail {
    font-size: 0.75rem;
    color: var(--color-text-tertiary);
}

/* Table of contents */
.privacy-toc {
    background: var(--color-bg);
    border: 1px solid var(--color-border-light);
    border-radius: var(--radius);
    padding: 1.25rem 1.5rem;
    margin-bottom: 2rem;
}

.privacy-toc-title {
    font-weight: 600;
    font-size: 0.8125rem;
    color: var(--color-text-secondary);
    margin-bottom: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.privacy-toc ol {
    list-style: none;
    padding: 0;
    margin: 0;
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 0.375rem 2rem;
}

.privacy-toc li {
    counter-increment: none;
}

.privacy-toc a {
    font-size: 0.875rem;
    color: var(--color-text);
    text-decoration: none;
    padding: 0.25rem 0;
    display: block;
    transition: color var(--transition);
}

.privacy-toc a:hover {
    color: var(--color-primary);
}

/* Sections */
.privacy-section {
    margin-bottom: 2rem;
    scroll-margin-top: 5rem;
}

.privacy-section h2 {
    font-size: 1.125rem;
    font-weight: 600;
    margin-bottom: 0.75rem;
    padding-bottom: 0.5rem;
    border-bottom: 1px solid var(--color-border-light);
}

.privacy-section p {
    font-size: 0.9375rem;
    color: var(--color-text-secondary);
    line-height: 1.8;
}

/* Privacy tables */
.privacy-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.875rem;
    margin: 0.75rem 0;
}

.privacy-table th {
    text-align: left;
    padding: 0.625rem 0.75rem;
    font-weight: 600;
    font-size: 0.8125rem;
    color: var(--color-text-secondary);
    background: var(--color-bg);
    border-bottom: 2px solid var(--color-border);
}

.privacy-table td {
    padding: 0.625rem 0.75rem;
    border-bottom: 1px solid var(--color-border-light);
    color: var(--color-text);
    line-height: 1.6;
}

.privacy-table code {
    background: var(--color-bg);
    padding: 0.125rem 0.375rem;
    border-radius: 0.25rem;
    font-size: 0.8125rem;
}

/* Note callout */
.privacy-note {
    background: #eff6ff;
    border-left: 3px solid var(--color-primary);
    padding: 0.75rem 1rem;
    margin-top: 0.75rem;
    border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
    font-size: 0.875rem;
    color: var(--color-text-secondary);
    line-height: 1.6;
}

/* Lists */
.privacy-list {
    margin: 0.5rem 0 0 1.25rem;
    padding: 0;
}

.privacy-list li {
    font-size: 0.9375rem;
    color: var(--color-text-secondary);
    line-height: 1.8;
    margin-bottom: 0.25rem;
}

/* Rights cards */
.privacy-rights-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 1rem;
    margin-top: 1rem;
}

.privacy-right-card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 1.25rem;
    transition: box-shadow var(--transition), transform var(--transition);
}

.privacy-right-card:hover {
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
    transform: translateY(-1px);
}

.privacy-right-title {
    font-weight: 600;
    font-size: 0.9375rem;
    margin-bottom: 0.5rem;
}

.privacy-right-card p {
    font-size: 0.8125rem;
    color: var(--color-text-secondary);
    line-height: 1.6;
    margin-bottom: 0.5rem;
}

.privacy-right-card code {
    background: var(--color-bg);
    padding: 0.25rem 0.5rem;
    border-radius: 0.25rem;
    font-size: 0.8125rem;
    color: var(--color-primary);
}

/* Contact */
.privacy-contact {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 1.25rem 1.5rem;
    display: flex;
    align-items: center;
    gap: 1rem;
}

.privacy-contact p {
    margin: 0;
}

.privacy-contact-email {
    font-weight: 600;
    font-size: 1rem;
    color: var(--color-primary);
    text-decoration: none;
}

.privacy-contact-email:hover {
    text-decoration: underline;
}

/* Mobile */
@media (max-width: 768px) {
    .privacy-summary-grid {
        grid-template-columns: repeat(2, 1fr);
    }

    .privacy-toc ol {
        grid-template-columns: 1fr;
    }

    .privacy-rights-grid {
        grid-template-columns: 1fr;
    }

    .privacy-contact {
        flex-direction: column;
        align-items: flex-start;
    }
}

.feed-card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    padding: 1rem 1.25rem;
    transition: border-color var(--transition);
}

.feed-card:hover {
    border-color: var(--color-primary);
}

.feed-card .fc-title {
    font-weight: 600;
    font-size: 0.9375rem;
    color: var(--color-text);
    line-height: 1.4;
}

.feed-card .fc-meta {
    font-size: 0.75rem;
    color: var(--color-text-muted);
    margin-top: 0.25rem;
    display: flex;
    gap: 0.75rem;
    flex-wrap: wrap;
}

.feed-card .fc-summary {
    font-size: 0.8125rem;
    color: var(--color-text-secondary);
    margin-top: 0.5rem;
    line-height: 1.5;
}

/* Pagination */
.pagination {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-top: 1.5rem;
    padding-top: 1rem;
    border-top: 1px solid var(--color-border);
}

.pagination a {
    padding: 0.375rem 0.75rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    font-size: 0.8125rem;
    font-weight: 500;
    transition: all var(--transition);
}

.pagination a:hover {
    border-color: var(--color-primary);
    background: var(--color-primary-light);
}

.pagination .page-info {
    font-size: 0.8125rem;
    color: var(--color-text-muted);
}

/* ==========================================================================
   Gradio Theme Override (/admin only)
   ========================================================================== */
.gradio-container {
    max-width: var(--container-max) !important;
    font-family: var(--font-sans) !important;
}

.gradio-container footer {
    display: none !important;
}

.built-with {
    display: none !important;
}

/* ==========================================================================
   Responsive
   ========================================================================== */
@media (max-width: 768px) {
    .nav-toggle {
        display: block;
    }

    .nav-links {
        display: none;
        position: absolute;
        top: 56px;
        left: 0;
        right: 0;
        background: var(--color-nav-bg);
        flex-direction: column;
        padding: 0.5rem 1rem 1rem;
        border-bottom: 1px solid rgba(255, 255, 255, 0.06);
    }

    .nav-links.open {
        display: flex;
    }

    .nav-divider {
        display: none;
    }

    .nav-links > a {
        padding: 0.625rem 0.75rem;
        width: 100%;
    }

    .hero {
        padding: 3rem 0 2.5rem;
    }

    .hero h1 {
        font-size: 1.75rem;
    }

    .hero-subtitle {
        font-size: 1rem;
    }

    .hero-stats {
        gap: 1.5rem;
    }

    .card-grid {
        grid-template-columns: 1fr;
    }

    .feature-card.highlight {
        flex-direction: column;
        grid-column: 1;
    }

    .footer-content {
        flex-direction: column;
        text-align: center;
    }
}

@media (max-width: 480px) {
    .hero h1 {
        font-size: 1.5rem;
    }

    .hero-search {
        flex-direction: column;
    }

    .hero-search button {
        padding: 0.75rem;
    }
}

/* ==========================================================================
   Point 1: Form Fieldset Grouping
   5+ 입력 필드가 있는 도구 폼의 논리적 섹션 구분
   ========================================================================== */
.form-fieldset {
    border: 1px solid var(--color-fieldset-border);
    border-radius: var(--radius-md);
    background: var(--color-fieldset-bg);
    padding: 1rem 1.25rem 0.75rem;
    margin-bottom: 1rem;
}

.form-fieldset-legend {
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--color-text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.03em;
    margin-bottom: 0.5rem;
    padding-bottom: 0.375rem;
    border-bottom: 1px solid var(--color-border-light);
}

/* ==========================================================================
   Point 2: CTA (Call-to-Action) High-Contrast Buttons
   검색, Export, Send to Profiler 등 주요 액션 유도 버튼
   ========================================================================== */
.btn-cta,
.tool-body button.btn-cta,
button.btn-cta {
    background: var(--color-cta);
    color: var(--color-text-inverse);
    border: none;
    border-radius: var(--radius-sm);
    padding: 0.625rem 1.5rem;
    font-size: 0.875rem;
    font-weight: 700;
    font-family: var(--font-sans);
    cursor: pointer;
    transition: background var(--transition), box-shadow var(--transition);
    box-shadow: 0 1px 3px rgba(5, 150, 105, 0.3);
}

.btn-cta:hover,
.tool-body button.btn-cta:hover {
    background: var(--color-cta-hover);
    box-shadow: 0 2px 8px rgba(5, 150, 105, 0.4);
}

.btn-cta:active {
    transform: translateY(1px);
}

/* #249 1단계 — white text on --color-cta fails WCAG AA in dark (2.53:1),
   --color-cta-hover fails too (3.77:1). */
:root[data-theme="dark"] .btn-cta,
:root[data-theme="dark"] .tool-body button.btn-cta,
:root[data-theme="dark"] button.btn-cta {
    background: var(--color-cta-on-fill);
}

:root[data-theme="dark"] .btn-cta:hover,
:root[data-theme="dark"] .tool-body button.btn-cta:hover {
    background: var(--color-cta-on-fill-hover);
}

/* Secondary CTA (outline 변형) */
.btn-cta-outline {
    background: transparent;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 2.25rem;
    color: var(--color-cta);
    border: 1.5px solid var(--color-cta);
    border-radius: var(--radius-sm);
    padding: 0.4rem 1.25rem;
    font-size: 0.875rem;
    font-weight: 600;
    cursor: pointer;
    transition: all var(--transition);
}

.btn-cta-outline:hover {
    background: var(--color-cta-light);
    border-color: var(--color-cta-hover);
}

/* ==========================================================================
   Point 3: Compact Density Mode
   데이터 테이블/결과 화면의 정보 밀도 토글 (body.compact)
   ========================================================================== */
body.compact .tool-body table th,
body.compact .tool-body table td {
    padding: 0.25rem 0.5rem;
    font-size: 0.8125rem;
    line-height: 1.35;
}

/* Search results table compact */
body.compact .data-table th {
    padding: 0.25rem 0.5rem;
    font-size: 0.75rem;
    line-height: 1.3;
}

body.compact .data-table td {
    padding: 0.2rem 0.5rem;
    font-size: 0.75rem;
    line-height: 1.3;
}

body.compact .card,
body.compact .result-card {
    padding: 0.75rem;
    gap: 0.375rem;
}

body.compact .tool-body label {
    margin-top: 0.375rem;
    margin-bottom: 0.125rem;
    font-size: 0.75rem;
}

body.compact .tool-body input[type="text"],
body.compact .tool-body input[type="number"],
body.compact .tool-body textarea,
body.compact .tool-body select {
    padding: 0.3rem 0.5rem;
    font-size: 0.8125rem;
}

body.compact .result-grid,
body.compact .card-grid-view {
    gap: 0.5rem;
}

body.compact .result-grid .card img,
body.compact .result-card img {
    max-height: 120px;
}

/* Compact toggle button (도구/검색 페이지 상단에 배치) */
.density-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.25rem 0.625rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    background: var(--color-surface);
    font-size: 0.75rem;
    font-weight: 500;
    color: var(--color-text-secondary);
    cursor: pointer;
    transition: all var(--transition);
}

.density-toggle:hover {
    border-color: var(--color-primary);
    color: var(--color-primary);
}

.density-toggle.active {
    background: var(--color-primary-light);
    border-color: var(--color-primary);
    color: var(--color-primary);
}

/* Column label toggle (friendly ↔ raw) */
.col-label-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.25rem 0.625rem;
    border: 1px solid var(--color-border);
    border-radius: 0.375rem;
    background: transparent;
    font-size: 0.75rem;
    color: var(--color-text-secondary);
    cursor: pointer;
    transition: all var(--transition);
}

.col-label-toggle:hover {
    border-color: var(--color-primary);
    color: var(--color-primary);
}

.col-label-toggle.active {
    background: var(--color-primary-light);
    border-color: var(--color-primary);
    color: var(--color-primary);
}

/* ==========================================================================
   Point 4: Pill-Shaped Tab Navigation
   /account, /tools/properties 등의 로컬 네비게이션
   ========================================================================== */
.tab-bar-pill {
    display: inline-flex;
    gap: 0.25rem;
    padding: 0.25rem;
    background: var(--color-surface-hover);
    border-radius: var(--radius-lg);
    margin-top: 1.5rem;
    margin-bottom: 1.5rem;
}

.tab-btn-pill {
    padding: 0.5rem 1.25rem;
    background: transparent;
    border: none;
    border-radius: calc(var(--radius-lg) - 2px);
    font-size: 0.875rem;
    font-weight: 500;
    color: var(--color-text-secondary);
    cursor: pointer;
    transition: all var(--transition);
    font-family: var(--font-sans);
    white-space: nowrap;
}

.tab-btn-pill:hover {
    color: var(--color-text);
}

.tab-btn-pill.active {
    background: var(--color-surface);
    color: var(--color-primary);
    font-weight: 600;
    box-shadow: var(--shadow-sm);
}

@media (max-width: 768px) {
    .tab-bar-pill {
        width: 100%;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }

    .tab-btn-pill {
        padding: 0.625rem 1rem;
        font-size: 0.8125rem;
    }
}

/* ==========================================================================
   Phase 1a: Recent Searches, Inline Fav/Memo, Nav Badge
   ========================================================================== */

/* Hero recent searches */
.hero-recent {
    display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap;
    margin-top: 1.25rem; justify-content: center;
}
.hero-chip-more {
    border-style: dashed;
    opacity: 0.85;
}
.hero-chip-more:hover {
    opacity: 1;
}

/* Inline favorite & memo buttons (search results) */
.row-actions {
    white-space: nowrap;
    text-align: center;
}
.inline-fav-btn, .inline-memo-btn {
    background: none; border: none; cursor: pointer;
    font-size: 1rem; padding: 0.125rem 0.25rem;
    color: var(--color-text-muted);
    transition: color 0.15s;
    line-height: 1;
}
.inline-fav-btn:hover { color: var(--color-fav-active); }
.inline-memo-btn:hover { color: var(--color-primary); }
.inline-fav-btn.active { color: var(--color-fav-active); font-size: 1.1rem; }
.inline-memo-btn.active { color: var(--color-primary); }

/* Card grid actions */
.rc-actions {
    display: flex; gap: 0.25rem; justify-content: flex-end;
    padding: 0.25rem 0.5rem;
}

/* Memo popover */
.memo-popover {
    position: absolute; right: 0; top: 100%; z-index: 100;
    background: var(--color-bg); border: 1px solid var(--color-border);
    border-radius: 0.5rem; padding: 0.75rem;
    box-shadow: 0 4px 12px var(--color-popover-shadow);
    min-width: 220px;
}
.memo-textarea {
    width: 100%; resize: vertical; border: 1px solid var(--color-border);
    border-radius: 0.375rem; padding: 0.5rem; font-size: 0.8125rem;
    font-family: inherit;
}
.memo-textarea:focus { outline: none; border-color: var(--color-primary); }
.memo-actions {
    display: flex; gap: 0.5rem; justify-content: flex-end; margin-top: 0.5rem;
}
.memo-save-btn {
    background: var(--color-primary); color: var(--color-text-inverse); border: none;
    border-radius: 0.375rem; padding: 0.375rem 0.75rem; font-size: 0.8125rem;
    cursor: pointer;
}
.memo-save-btn:hover { opacity: 0.9; }

/* #249 1단계 — white text on --color-primary fails WCAG AA in dark (3.67:1). */
:root[data-theme="dark"] .memo-save-btn { background: var(--color-primary-on-fill); }
:root[data-theme="dark"] .memo-save-btn:hover { opacity: 1; background: var(--color-primary-on-fill-hover); }

.memo-cancel-btn {
    background: none; border: 1px solid var(--color-border);
    border-radius: 0.375rem; padding: 0.375rem 0.75rem; font-size: 0.8125rem;
    cursor: pointer; color: var(--color-text-muted);
}

/* Navigation badge */
.nav-badge {
    display: none;
    background: var(--color-primary); color: var(--color-text-inverse);
    font-size: 0.625rem; font-weight: 700;
    min-width: 16px; height: 16px; line-height: 16px;
    border-radius: 999px; text-align: center;
    padding: 0 4px; margin-left: 4px;
    vertical-align: middle;
}

/* #249 1단계 — white text on --color-primary fails WCAG AA in dark (3.67:1). */
:root[data-theme="dark"] .nav-badge {
    background: var(--color-primary-on-fill);
}


/* ── Navigation: auth, profile dropdown, project switcher, tools dropdown ── */
.nav-signin {
    display: inline-flex; align-items: center; gap: 0.375rem;
    padding: 0.375rem 0.875rem; border: 1px solid rgba(255,255,255,0.2);
    border-radius: 6px; font-size: 0.8125rem; font-weight: 500;
    color: #e2e8f0; text-decoration: none; transition: all 0.2s;
    white-space: nowrap;
}
.nav-signin:hover { border-color: rgba(255,255,255,0.5); background: rgba(255,255,255,0.05); }
.nav-profile { position: relative; }
.profile-trigger {
    background: none; border: none; cursor: pointer; padding: 0;
    display: flex; align-items: center;
}
.profile-avatar {
    width: 32px; height: 32px; border-radius: 50%;
    background: var(--color-primary); color: var(--color-text-inverse);
    display: flex; align-items: center; justify-content: center;
    font-size: 0.8125rem; font-weight: 700;
}

/* #249 1단계 — white text on --color-primary fails WCAG AA in dark (3.67:1). */
:root[data-theme="dark"] .profile-avatar {
    background: var(--color-primary-on-fill);
}
.profile-dropdown {
    display: none; position: absolute; right: 0; top: calc(100% + 8px);
    background: var(--color-surface); border: 1px solid var(--color-border);
    border-radius: 8px; min-width: 220px; padding: 0.5rem 0;
    box-shadow: 0 8px 24px rgba(0,0,0,0.12); z-index: 100;
}
.profile-dropdown.open { display: block; }
.profile-name { padding: 0.5rem 1rem; font-weight: 600; font-size: 0.875rem; color: var(--color-text); }
.profile-email { padding: 0 1rem 0.5rem; font-size: 0.75rem; color: var(--color-text-muted); }
.profile-divider { height: 1px; background: var(--color-border-light); margin: 0.25rem 0; }
.profile-dropdown a {
    display: block; padding: 0.5rem 1rem; font-size: 0.875rem;
    color: var(--color-text); text-decoration: none; transition: background 0.15s;
}
.profile-dropdown a:hover { background: var(--color-bg); }
.profile-logout {
    width: 100%; text-align: left; padding: 0.5rem 1rem;
    font-size: 0.875rem; color: var(--color-danger); background: none;
    border: none; cursor: pointer; font-family: var(--font-sans);
}
.profile-logout:hover { background: var(--color-danger-soft); }
.nav-profile form { margin: 0; }
.nav-project-switcher {
    display: inline-flex; align-items: center; gap: 0.45rem;
    padding: 0.3rem 0.6rem; border: 1px solid rgba(255,255,255,0.16);
    border-radius: 10px; background: rgba(255,255,255,0.05);
    margin-right: 0.75rem;
}
.nav-project-label {
    font-size: 0.6875rem; font-weight: 600; letter-spacing: 0.03em;
    color: #cbd5e1; text-transform: uppercase;
}
.nav-project-current {
    display: inline-flex; align-items: center;
    max-width: 180px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    padding: 0.15rem 0.55rem; border-radius: 999px;
    background: rgba(255,255,255,0.08); color: var(--color-nav-text-strong);
    font-size: 0.75rem; font-weight: 700;
}
.nav-project-select {
    min-width: 150px; max-width: 180px;
    padding: 0.3rem 0.5rem; border-radius: 6px; border: 1px solid rgba(255,255,255,0.16);
    background: rgba(15,23,42,0.55); color: var(--color-text-inverse); font: inherit;
}
.nav-project-create {
    border: 1px solid rgba(255,255,255,0.16); background: rgba(255,255,255,0.06); color: var(--color-text-inverse);
    border-radius: 6px; padding: 0.3rem 0.55rem; font-size: 0.75rem; cursor: pointer;
}
.nav-project-create:hover { background: rgba(255,255,255,0.12); }
@media (max-width: 980px) {
    .nav-project-label { display: none; }
    .nav-project-current { max-width: 130px; }
    .nav-project-select { min-width: 120px; max-width: 140px; }
}
@media (max-width: 768px) {
    .nav-signin { font-size: 0.75rem; padding: 0.25rem 0.625rem; }
    .site-nav .nav-version { display: none; }
    /* Language toggle lives in nav-right next to the (now hidden) version chip;
       hide it on mobile to avoid horizontal overflow. The footer text toggle
       (한국어 | English) remains the mobile language-switch path. */
    .site-nav .settings-choice-group { display: none; }
    .profile-dropdown { right: -1rem; }
    .nav-project-switcher { margin-right: 0.4rem; padding: 0.2rem 0.35rem; gap: 0.25rem; }
    .nav-project-current { max-width: 96px; padding: 0.1rem 0.4rem; font-size: 0.6875rem; }
    .nav-project-select { min-width: 96px; max-width: 112px; font-size: 0.75rem; }
    .nav-project-create { padding: 0.25rem 0.4rem; font-size: 0.6875rem; }
}
@media (max-width: 640px) {
    /* PR7 4단계: components.css already hides .workbench-project-switcher at
       this breakpoint (workbench-shell pages). Pages that render the plain
       .site-nav (no "workbench-" class, e.g. evidence-card) never got the
       same treatment, so the switcher's min-width floor (96px select +
       37px button + label/gaps) still overflows a 390px viewport. */
    .nav-project-switcher { display: none; }
}

/* ── Tools dropdown (groups secondary tools so the top nav fits) ── */
.nav-dropdown { position: relative; display: inline-flex; }
.nav-dropdown-btn {
    background: none; border: none; cursor: pointer;
    color: var(--color-nav-text); font: inherit;
    font-size: 0.75rem; font-weight: 500;
    padding: 0.25rem 0.5rem; border-radius: var(--radius-sm);
    display: inline-flex; align-items: center; gap: 0.25rem;
    white-space: nowrap; transition: all var(--transition);
}
.nav-dropdown-btn::after {
    content: "▾"; font-size: 0.625rem; opacity: 0.7;
}
.nav-dropdown-btn:hover {
    color: var(--color-nav-text-hover);
    background: rgba(255, 255, 255, 0.08);
}
.nav-dropdown-btn.active {
    color: var(--color-nav-accent);
    background: rgba(56, 189, 248, 0.1);
}
.nav-dropdown-menu {
    display: none; position: absolute; top: calc(100% + 6px); left: 0;
    min-width: 180px; padding: 0.375rem 0;
    background: var(--color-surface); border: 1px solid var(--color-border);
    border-radius: 8px; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
    z-index: 110;
}
.nav-dropdown-menu.open { display: block; }
.nav-dropdown-menu a {
    display: block; padding: 0.5rem 0.875rem;
    font-size: 0.8125rem; color: var(--color-text);
    text-decoration: none; transition: background 0.15s;
    white-space: nowrap;
}
.nav-dropdown-separator {
    height: 1px;
    margin: 0.35rem 0.875rem;
    background: var(--color-border-light);
}
.nav-dropdown-menu a:hover { background: var(--color-bg); }
.nav-dropdown-menu a.active {
    color: var(--color-primary); font-weight: 600;
    background: rgba(56, 189, 248, 0.08);
}

/* ── Compression: tighter top nav so all primary items fit ── */
.nav-brand { margin-right: 1rem; }
.site-nav .nav-links > a {
    font-size: 0.75rem;
    padding: 0.25rem 0.5rem;
}
.site-nav .nav-divider { margin: 0 0.125rem; }
/* The Tools dropdown menu is absolutely positioned below .nav-links.
   The default `overflow-x: auto` on .nav-links forces overflow-y to
   `auto` per CSS spec, which clips the dropdown. Now that the items
   fit on one line, allow overflow to be visible so the menu shows. */
.site-nav .nav-links {
    overflow: visible;
}
/* Full logo with icon + "AIDD Soln" wordmark.
   Source PNG is 2583×687 (aspect ≈ 3.76:1) — icon on the left, text on
   the right. Use the natural aspect ratio so both parts are visible.
   Sized at 80% of the original 56px brief — wordmark stays readable. */
.site-nav .container { height: 60px; }
.nav-brand .brand-logo {
    height: 45px;
    width: auto;
    max-width: 192px;
    object-fit: contain;
    object-position: left center;
    display: block;
    flex-shrink: 0;
}

/* ── Dark-mode surface fixes for info-page widgets lacking theme-aware
   backgrounds (light-only rules above stay intact for light mode). ── */
[data-theme="dark"] .glossary-card,
[data-theme="dark"] .resource-card {
    background: var(--color-surface);
}
[data-theme="dark"] .info-page table th {
    background: var(--color-surface-secondary);
}
[data-theme="dark"] .privacy-note {
    background: linear-gradient(135deg, rgba(59, 130, 246, 0.13), var(--color-surface));
}
