/* === Typographic scale (Major Third, 1.25× modular) ===
   Single source of truth for every font-size in the dashboard. Six steps cover
   every UI surface; change any token here and the whole dashboard updates. */
:root {
    --fs-h2:    1.5rem;      /* 24 px — section titles                            */
    --fs-h3:    1.25rem;     /* 20 px — subsection titles + nav brand             */
    --fs-h4:    1.125rem;    /* 18 px — caveat header / log-drawer title          */
    --fs-body:  1rem;        /* 16 px — body, section description, list items     */
    --fs-ui:    0.875rem;    /* 14 px — form controls / labels / chips / buttons  */
    --fs-small: 0.8125rem;   /* 13 px — hints / notes / btn-small / delta chips   */
    --fs-tiny:  0.75rem;     /* 12 px — counters / micro-labels / ✦ badge         */
}

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

/* Reserve the vertical scrollbar's gutter at the root so toggling
   `body.sim-locked { overflow: hidden }` (when the strategy-info modal
   opens) does not cause the dashboard underneath to shift sideways. */
html { scrollbar-gutter: stable; }

body {
    font-family: 'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    color: #1C1C1C;
    font-size: var(--fs-body);
    line-height: 1.6;
    background: #F3F3F3;
}

/* === Nav (EPRI style) === */
#main-nav {
    position: fixed; top: 0; left: 0; right: 0; z-index: 100;
    height: 56px;
    display: flex; justify-content: space-between; align-items: center;
    padding: 0 1.5rem;
    background: #1565c0; color: #fff;
    box-shadow: 0 2px 2px 0 rgba(0,0,0,0.14), 0 3px 1px -2px rgba(0,0,0,0.12), 0 1px 5px 0 rgba(0,0,0,0.2);
}
.nav-brand { display: flex; align-items: center; gap: 0.5rem; }
.nav-title { font-weight: 700; font-size: var(--fs-h3); letter-spacing: 0.5px; }
.nav-links { display: flex; align-items: center; gap: 0.3rem; }
.nav-links a {
    color: #fff; text-decoration: none; font-size: var(--fs-body);
    padding: 0.4rem 0.75rem; border-radius: 6px;
    opacity: 0.85; transition: all 0.2s;
}
.nav-links a:hover { opacity: 1; background: rgba(255,255,255,0.15); }
/* Live Demo — clean white pill (CIGRE style; no shadow/animation).
   Specificity raised via `.nav-links .nav-pill` so the pill's font-size wins
   over `.nav-links a`'s body size. */
.nav-links .nav-pill {
    background: #fff; color: #1565c0 !important;
    padding: 0.35rem 1rem; border-radius: 20px; font-weight: 600;
    font-size: var(--fs-ui); letter-spacing: 0.2px; opacity: 1 !important;
    margin-right: 0.5rem;
}
.nav-links .nav-pill:hover { background: #e3f2fd !important; }

/* === Buttons (EPRI style) === */
.btn {
    display: inline-block; padding: 0.5rem 1rem; border-radius: 6px;
    text-decoration: none; font-weight: 600; font-size: var(--fs-ui); cursor: pointer;
    font-family: inherit; transition: all 0.2s;
}
.btn-small {
    padding: 0.4rem 0.75rem; font-size: var(--fs-ui);                  /* match search/pageLength height in the DataTables toolbars */
    background: #1565c0; color: #fff; border: 1px solid #1565c0; border-radius: 6px;
}
.btn-small:hover { background: #1558A0; }
.btn-large {
    padding: 0.6rem 1.5rem; font-size: var(--fs-body);
    background: #1565c0; color: #fff; border: 2px solid #1565c0; border-radius: 6px;
}
.btn-large:hover { background: #1558A0; }

/* === Sections === */
section {
    padding: 2rem 2.25rem; max-width: 1440px; margin: 0 auto;
    background: #fff; border-radius: 8px;
    margin-bottom: 1rem; box-shadow: 0 1px 3px rgba(0,0,0,0.08);
}
section:first-of-type { margin-top: 72px; }
section h2 {
    font-size: var(--fs-h2); color: #1565c0; font-weight: 700;
    border-bottom: 2px solid #1565c0; padding-bottom: 0.5rem; margin-bottom: 0.75rem;
}
section h3 { font-size: var(--fs-h3); color: #1C1C1C; font-weight: 600; margin: 1rem 0 0.5rem; }
.section-desc { color: #495057; margin-bottom: 0.75rem; font-size: var(--fs-body); line-height: 1.55; }
/* Uniform small / hint / footnote text */
.hint { font-size: var(--fs-small); color: #6c757d; font-weight: 600; }

/* Uniform chart subtitle — used by every subchart description and the
   "click bar / row name" tip beside each Metric dropdown. Body-size for
   readability; charcoal for contrast without competing with section h3. */
.chart-sub { font-size: var(--fs-body); color: #495057; font-weight: 400; line-height: 1.5; }

/* === Controls === */
.control-group { display: inline-flex; align-items: center; gap: 0.5rem; margin: 0.5rem 1rem 0.5rem 0; }
select, .ctl {
    font-family: inherit; font-weight: 600; font-size: var(--fs-ui); color: #1C1C1C;
    padding: 0.4rem 1.9rem 0.4rem 0.7rem; border: 1px solid #CBD5E1; border-radius: 7px;
    background-color: #fff; cursor: pointer;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'><path d='M1 1l4 4 4-4' fill='none' stroke='%23495057' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/></svg>");
    background-repeat: no-repeat; background-position: right 0.65rem center; background-size: 0.7rem;
    -webkit-appearance: none; appearance: none; transition: border-color 0.15s, box-shadow 0.15s;
}
select:hover, .ctl:hover { border-color: #1565c0; }
select:focus, .ctl:focus { outline: none; border-color: #1565c0; box-shadow: 0 0 0 3px rgba(21,101,192,0.15); }
label { font-weight: 600; font-size: var(--fs-ui); color: #495057; }

/* === Tables === */
.about-content { display: grid; grid-template-columns: 1fr 1fr; gap: 2rem; }
.about-content ul { list-style: disc; padding-left: 1.5rem; }
.about-content li { margin-bottom: 0.3rem; font-size: var(--fs-body); color: #495057; }
table.summary-table { width: 100%; border-collapse: collapse; margin: 1rem 0; font-size: var(--fs-ui); }
table.summary-table th {
    background: #1565c0; color: #fff; padding: 0.6rem 0.75rem;
    text-align: left; font-weight: 600;
}
table.summary-table td { padding: 0.6rem 0.75rem; border-bottom: 1px solid #e9ecef; }
table.summary-table tr:hover { background: #e3f2fd; }
table.summary-table a { color: #1565c0; font-weight: 600; }

/* === Retrieval + Modifier DataTables — clean column alignment ============
   Goal: name columns don't wrap (long strategy names like
   rrf_llm_listwise_rerank_dense_candidate stay on one line); numeric
   columns right-align with tabular-nums so digits sit on a vertical grid;
   monospace on the code-like name cells matches the chart's y-tick style.
   Selectors target the four data tables by id. */
table#modifier-table,
table#retrieval-table,
table[id^="retrieval-table-"] {
    font-variant-numeric: tabular-nums;
    /* No forced width: scrollX:true wraps the table in .dt-scroll-body and
       handles horizontal overflow when the nowrap cells push the natural
       table width past the container. Forcing width:100%!important here
       suppresses that overflow and breaks the in-table horizontal scroll. */
}
/* Every body cell is centered + nowrap — uniform across all four tables (col 1 included). */
table#modifier-table tbody td,
table#retrieval-table tbody td,
table[id^="retrieval-table-"] tbody td {
    white-space: nowrap;
    text-align: center;
}
/* Col 1 keeps monospace because it carries the code-like row identifier (Strategy in
   retrieval per-family, Model elsewhere). Only the font changes; alignment is inherited
   from the centered rule above.
   IMPORTANT: modifier uses a class (.mod-col-model) instead of nth-child(1) because the
   modifier Compare-Δ table removes Model cells from rows 2/3 of each rowspan group; that
   shifts the Scorer cell into nth-child(1) position, and a positional rule would then
   pick it up and render Scorer in monospace (different from row 1's Scorer in Manrope —
   exactly the "different fonts in the Scorer column" bug). Class-based targeting follows
   the actual Model cells regardless of their nth-child position. */
table#modifier-table tbody td.mod-col-model,
table#retrieval-table tbody td:nth-child(1),
table[id^="retrieval-table-"] tbody td:nth-child(1) {
    font-family: ui-monospace, monospace;
}
/* Retrieval tables col 2 also carries a code-like name (Model in per-family, Strategy in
   Compare) so we keep monospace there for readability. We target both the (hidden) body
   thead and the visible scroll-head clone DT creates when scrollX:true is set. */
table#retrieval-table tbody td:nth-child(2),
table#retrieval-table thead th:nth-child(2),
table[id^="retrieval-table-"] tbody td:nth-child(2),
table[id^="retrieval-table-"] thead th:nth-child(2),
#retrieval-table_wrapper .dt-scroll-head th:nth-child(2),
[id^="retrieval-table-"][id$="_wrapper"] .dt-scroll-head th:nth-child(2) {
    font-family: ui-monospace, monospace;
}
/* Every header cell is centered + nowrap (matches the body). The 1.5rem balanced horizontal
   padding neutralises DT 2.x's padding-right:30px on sortable headers (added for the absolute
   ▲/▼ sort indicator) so centered text reads at the column's true center on every column —
   col 1 included. !important so it beats DT's per-family rule.
   IMPORTANT: when scrollX:true is set, DT 2.x hides the original table's thead (height:0)
   and creates a CLONED <table> inside .dt-scroll-head that doesn't carry our table ID.
   The ID-based selectors below only match the hidden original thead; the .dt-scroll-head
   selector matches the VISIBLE floating header. Both must be styled or the visible header
   stays left-aligned with DT's default styling. */
table#modifier-table thead th,
table#retrieval-table thead th,
table[id^="retrieval-table-"] thead th,
.dt-scroll-head table thead th {
    text-align: center !important;                                    /* !important to beat any inline style DT 2.x may set on the cloned scroll-head th (without !important, an inline text-align would win regardless of CSS specificity) */
    white-space: nowrap;
    padding-left: 1.5rem !important;
    padding-right: 1.5rem !important;
}
/* Cell padding so the dense numeric grid breathes. */
table#modifier-table tbody td,
table#retrieval-table tbody td,
table[id^="retrieval-table-"] tbody td {
    padding: 0.45rem 0.7rem;
}
table#modifier-table thead th,
table#retrieval-table thead th,
table[id^="retrieval-table-"] thead th {
    padding: 0.5rem 0.7rem;
}

/* Unified retrieval toolbar — Export CSV (left) + single Search (right) on one row,
   above the three family tables. The search input wires to all 3 DataTables via dt.search(). */
.ret-table-toolbar {
    display: flex; justify-content: space-between; align-items: center;
    margin: 0 0 0.6rem; gap: 1rem;
}
.ret-search-input {
    font-family: inherit; font-weight: 500; font-size: var(--fs-ui);
    color: #1C1C1C; padding: 0.4rem 0.7rem;
    border: 1px solid #CBD5E1; border-radius: 7px;
    background-color: #fff;
    min-width: 220px; outline: none;                                  /* matches the DT 2.x .dt-input min-width so all four search bars are the same width */
    transition: border-color 0.15s, box-shadow 0.15s;
}
.ret-search-input:hover { border-color: #1565c0; }
.ret-search-input:focus {
    border-color: #1565c0; box-shadow: 0 0 0 3px rgba(21,101,192,0.15);
}

/* === DataTables UI — works for both DT 2.x (.dt-*) and legacy 1.x (.dataTables_*) ====
   Restyles every DataTables-rendered control to match the dashboard's
   .ctl / .lbl / .seg idiom: same border, same focus ring, same Manrope
   weight and size, same uppercase Manrope label for the "Search:" caption. */
.dt-container, .dataTables_wrapper { margin-bottom: 0.5rem; }

.dt-search, .dataTables_filter { margin: 0; }                          /* zero margin: DT's layout-cell is flex with align-items:center, so any vertical margin (e.g. the old 0 0 0.5rem) shifts the search wrapper off-center relative to siblings (legend, pageLength, CSV button) */
.dt-search label, .dataTables_filter label {
    font-family: inherit; font-weight: 700; font-size: var(--fs-ui);
    text-transform: uppercase; letter-spacing: 0.04em; color: #495057;
    display: inline-flex; align-items: center; gap: 0.5rem;
}
/* !important on the visual props because DataTables' bundled CSS uses higher
   specificity (div.dt-container input.dt-input) than any reasonable
   user-stylesheet selector — `!important` is the cleanest cross-library override. */
.dt-container .dt-search input,
.dt-container .dt-input,
.dt-container .dataTables_filter input,
.dataTables_wrapper .dataTables_filter input {
    font-family: inherit !important;
    font-weight: 500 !important;
    font-size: var(--fs-ui) !important;
    color: #1C1C1C !important;
    padding: 0.4rem 0.7rem !important;
    border: 1px solid #CBD5E1 !important;
    border-radius: 7px !important;
    background-color: #fff !important;
    min-width: 220px !important;
    outline: none !important;
    transition: border-color 0.15s, box-shadow 0.15s !important;
}
.dt-container .dt-search input:hover,
.dt-container .dt-input:hover,
.dt-container .dataTables_filter input:hover,
.dataTables_wrapper .dataTables_filter input:hover {
    border-color: #1565c0 !important;
}
.dt-container .dt-search input:focus,
.dt-container .dt-input:focus,
.dt-container .dataTables_filter input:focus,
.dataTables_wrapper .dataTables_filter input:focus {
    border-color: #1565c0 !important;
    box-shadow: 0 0 0 3px rgba(21,101,192,0.15) !important;
}
/* Compact entries-per-page select (DT 2.x) — narrower than the 220-px search input
   that shares the .dt-input class, but with the same vertical padding so heights
   align. min-width 80 px fits "100" + native OS dropdown arrow comfortably.
   .dt-length .dt-input has 0,3,0 specificity which wins over the .dt-container
   .dt-input (0,2,0) rule. */
.dt-container .dt-length .dt-input,
.dt-container .dt-length select,
.dt-container .dataTables_length select {
    min-width: 80px !important;
    width: auto !important;
    padding: 0.4rem 0.7rem !important;
}

/* Info + paging (only render on tables that keep paging:true; styled to match anyway) */
.dt-info, .dataTables_info {
    font-size: var(--fs-small); color: #6c757d; font-weight: 600;
    padding-top: 0.5rem;
}
.dt-paging, .dataTables_paginate { padding-top: 0.5rem; }
.dt-paging .dt-paging-button,
.dataTables_paginate .paginate_button {
    font-family: inherit; font-size: var(--fs-small); padding: 0.25rem 0.7rem;
    border: 1px solid #CBD5E1; border-radius: 6px; margin: 0 0.15rem;
    background: #fff; color: #495057; cursor: pointer;
    transition: border-color 0.15s, background 0.15s, color 0.15s;
}
.dt-paging .dt-paging-button:hover,
.dataTables_paginate .paginate_button:hover {
    border-color: #1565c0; color: #1565c0; background: #e3f2fd;
}
.dt-paging .dt-paging-button.current, .dt-paging .dt-paging-button.current:hover,
.dataTables_paginate .paginate_button.current, .dataTables_paginate .paginate_button.current:hover {
    background: #1565c0; color: #fff !important; border-color: #1565c0;
}
.dt-paging .dt-paging-button.disabled, .dt-paging .dt-paging-button.disabled:hover,
.dataTables_paginate .paginate_button.disabled, .dataTables_paginate .paginate_button.disabled:hover {
    color: #c5c9cf !important; cursor: default;
    background: #fff; border-color: #e9ecef;
}

/* === Chart containers === */
#retrieval-chart-container, #tier-chart-container, #pareto-chart-container,
#mod-chart-container { min-height: 400px; margin: 0.5rem 0; }
#mod-heatmap-container { min-height: 250px; margin: 0.5rem 0; }

/* === Scroll offset for fixed nav === */
section[id] { scroll-margin-top: 72px; }

/* === Logs === */
#logs { text-align: center; }
.note { font-size: var(--fs-small); color: #979797; margin-top: 1rem; }

/* === About === */
#about h3 { color: #1565c0; }

/* === Responsive === */
@media (max-width: 768px) {
    .about-content { grid-template-columns: 1fr; }
    #main-nav { height: auto; flex-direction: column; gap: 0.5rem; padding: 0.5rem 1rem; }
    .nav-links { display: flex; flex-wrap: wrap; gap: 0.25rem; }
    section:first-of-type { margin-top: 100px; }
}

/* =====================================================================
   v2 control / legend / chart / drawer components
   (ported from the validated UI prototypes; EPRI idiom preserved)
   ===================================================================== */

/* Filter bar — sticky per-section control area (Machine / Families / View) */
.filterbar {
    background: #fafcff; border: 1px solid #CBD5E1; border-radius: 8px;
    padding: 0.7rem 0.8rem; display: flex; gap: 1.4rem; align-items: center;
    flex-wrap: wrap; margin: 0.4rem 0 1rem;
}
.fg { display: flex; align-items: center; gap: 0.6rem; }
.lbl {
    font-weight: 700; font-size: var(--fs-ui); text-transform: uppercase;
    letter-spacing: 0.04em; color: #495057;
}
/* (.ctl shares the unified select style above) */

/* Segmented toggle (Machine, View) */
.seg { display: inline-flex; background: #e7ecf3; border-radius: 7px; padding: 3px; }
.seg button {
    border: 0; background: transparent; font-family: inherit; font-weight: 700;
    font-size: var(--fs-ui); color: #495057; padding: 6px 14px; border-radius: 6px; cursor: pointer;
}
.seg button.on { background: #1565c0; color: #fff; }
.seg.alt button.on { background: #37474f; }

/* Family checkboxes */
.fam {
    display: inline-flex; align-items: center; gap: 0.4rem; font-size: var(--fs-ui);
    font-weight: 600; cursor: pointer; user-select: none;
    border: 1px solid #CBD5E1; border-radius: 7px; padding: 6px 12px; background: #fff;
}
.fam.on { background: #e3f2fd; border-color: #9bc1ee; color: #1565c0; }
.fam .cnt { font-size: var(--fs-ui); color: #979797; font-weight: 700; }     /* unified with .fam name + .lbl + .seg button — all 14 px across the View / Machine / Families cards */
.fam.on .cnt { color: #1565c0; }
.fam input { accent-color: #1565c0; }

/* LLM legend chips (color key + model filter) */
.legend { display: flex; gap: 0.45rem; flex-wrap: wrap; align-items: center; flex: 1; }
.lgbox {
    display: inline-flex; align-items: center; justify-content: center; gap: 6px; font-size: var(--fs-ui);
    font-weight: 600; border: 1px solid #CBD5E1; border-radius: 20px;
    padding: 5px 12px; cursor: pointer; background: #fff; user-select: none; flex: 1 1 auto;
}
.lgbox .sw { display: inline-block; width: 11px; height: 11px; border-radius: 3px; }
.lgbox .rz { font-size: var(--fs-tiny); }
.lgbox.off { opacity: 0.32; text-decoration: line-through; }

/* Chart container box */
.chartbox { border: 1px solid #e9ecef; border-radius: 8px; padding: 1rem 1.1rem; }

/* Per-family subsections (single-machine Chart/Table views) */
.fam-sub { margin: 0 0 1.1rem; }
.fam-sub-head {
    display: flex; align-items: center; justify-content: space-between;
    margin: 0.6rem 0 0.4rem;
}
.fam-sub-head h3 { margin: 0; }                       /* reuse section h3 type, drop its margins */
.expand-btn {
    border: 1px solid #CBD5E1; background: #fff; color: #1565c0;
    font-family: inherit; font-weight: 700; font-size: var(--fs-small);
    padding: 4px 12px; border-radius: 6px; cursor: pointer; transition: all 0.15s;
}
.expand-btn:hover { border-color: #1565c0; background: #e3f2fd; }
/* Scroll container: default caps height to ~5 rows; Expand removes the cap.
   Chart vs table get different caps via the view-modifier class. */
.fam-scroll {
    overflow-y: auto;
    border: 1px solid #e9ecef; border-radius: 8px;
}
.fam-scroll.chart-scroll {
    max-height: 450px;                                    /* ~7-8 strategy groups, then vertical scroll */
    overflow-x: hidden;                                   /* charts auto-fit container via Plotly responsive:true — no h-scroll */
}
.fam-scroll.table-scroll {
    /* DataTables manages its own scrollY/scrollX viewport via scrollY:'250px' on
       each per-family DataTable. Opt out of the outer cap + overflow so the
       h-scrollbar at the dt-scroll-body bottom is visible (same UX as modifier). */
    max-height: none;
    overflow: visible;
}
.fam-scroll.expanded { max-height: none; overflow: visible; }

/* Dropdown category (optgroup) + option label fonts — consistent/readable */
select optgroup { font-weight: 700; font-style: normal; color: #1565c0; font-size: var(--fs-small); }
select option { font-weight: 500; color: #1C1C1C; font-size: var(--fs-ui); }

/* Delta cells (Compare view): green good / amber warn / red bad */
.d { font-weight: 700; border-radius: 5px; padding: 1px 6px; font-size: var(--fs-small); }
.d.good { color: #1a8c5a; background: #e7f6ee; }
.d.warn { color: #b7791f; background: #fbf3e2; }
.d.bad  { color: #c5384a; background: #fdecef; }

/* Modifier Compare-Δ table: the Model column is merged via rowspan after each DataTables
   draw (one cell spans the 3 scorer rows for each model). Style that merged cell so it
   reads as a "group header" sitting on the left edge: vertical-centered name, soft
   background, and a clear right border separating the model column from the per-scorer
   data columns. Only the merged cells have a rowspan attribute, so this rule only
   affects the Compare-Δ view (per-row modifier table never sets rowspan). */
table#modifier-table tbody td[rowspan] {
    vertical-align: middle;
    background-color: #f8f9fa;
    border-right: 2px solid #e9ecef;
}

/* Non-sortable headers (e.g. modifier Compare-Δ with ordering:false): no sort indicator,
   so the 1.5rem balanced padding I add for sortable headers (to compensate for DT's
   padding-right:30px on .dt-orderable-* cells) just creates excess whitespace and visually
   throws off the alignment with body cells underneath. Restore natural 0.7rem padding so
   header text centers identically to the body cells. Specificity (0,1,4,2) wins over the
   sortable-header rule (0,1,1,2). */
table#modifier-table thead th:not(.dt-orderable-asc):not(.dt-orderable-desc):not(.dt-ordering-asc):not(.dt-ordering-desc),
table#retrieval-table thead th:not(.dt-orderable-asc):not(.dt-orderable-desc):not(.dt-ordering-asc):not(.dt-ordering-desc),
table[id^="retrieval-table-"] thead th:not(.dt-orderable-asc):not(.dt-orderable-desc):not(.dt-ordering-asc):not(.dt-ordering-desc) {
    padding-left: 0.7rem !important;
    padding-right: 0.7rem !important;
}

/* No custom min-widths on #modifier-table — auto-sizing matches the other tables. */

/* |Δ| color-key chips, rendered inside the DataTables top-right toolbar via DT 2.x layout.
   Sits inline with the search input — keeps the chips on the same row as the controls.
   A thin border + 7-px radius + white background draws a small "card" around the chips so the
   legend reads as a distinct UI element rather than free-floating coloured text. */
.delta-legend {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    margin-right: 0.9rem;
    padding: 0.35rem 0.5rem;                                         /* vertical padding tuned so the legend box height matches the search input / pageLength dropdown / Export CSV button (~28-29 px total) */
    border: 1px solid #CBD5E1;
    border-radius: 7px;
    background-color: #fff;
}

/* Per-row log drawer + scrim */
#log-scrim {
    position: fixed; inset: 0; background: rgba(20,30,60,0.2);
    opacity: 0; pointer-events: none; transition: 0.2s; z-index: 90;
}
#log-scrim.on { opacity: 1; pointer-events: auto; }
#log-drawer {
    /* Anchor below the fixed nav (height varies by viewport — see --nav-h set by
       log-drawer.js) so the drawer header (title + × close) sits in its own band
       instead of being covered by the nav (z-index 100). */
    position: fixed; top: var(--nav-h, 56px); right: 0;
    height: calc(100vh - var(--nav-h, 56px));
    width: 390px; background: #fff;
    box-shadow: -12px 0 40px rgba(0,0,0,0.18); transform: translateX(100%);
    transition: 0.22s; z-index: 95; display: flex; flex-direction: column;
}
#log-drawer.open { transform: translateX(0); }
#log-drawer .dh {
    background: #1565c0; color: #fff; padding: 1rem 1.1rem;
    display: flex; justify-content: space-between; align-items: center;
}
#log-drawer .dh h4 { font-size: var(--fs-h4); }
#log-drawer .dh .x { cursor: pointer; font-size: var(--fs-h3); }
#log-drawer .db { padding: 1.1rem; overflow: auto; }
#log-drawer .db .kv {
    display: flex; justify-content: space-between; padding: 0.5rem 0;
    border-bottom: 1px dashed #e9ecef; font-size: var(--fs-ui);
}
#log-drawer .db .kv span { color: #495057; }
#log-drawer .db .sub {
    color: #979797; font-size: var(--fs-tiny); text-transform: uppercase;
    letter-spacing: 0.05em; font-weight: 700; margin: 1rem 0 0.3rem;
}
#log-drawer .db .go {
    display: block; text-align: center; margin-top: 1.1rem; background: #1565c0;
    color: #fff; padding: 0.7rem; border-radius: 7px; font-weight: 700;
}

/* Overview pipeline diagram */
.overview-diagram { margin: 0.5rem auto 1.25rem; text-align: center; }
.overview-diagram img {
    max-width: 600px; width: 100%; height: auto; border: 1px solid #e9ecef;
    border-radius: 8px; background: #fff; padding: 0.4rem;
}
.fig-cap {
    margin: 0.65rem auto 0; max-width: 940px; font-size: var(--fs-body); line-height: 1.5;
    color: #495057; text-align: center;
}
.fig-cap strong { color: #1565c0; }
/* Stage labels keyed to the diagram's green (Stage 1) / orange (Stage 2) boxes */
.fig-cap .stage1 { color: #146c43; font-weight: 700; }
.fig-cap .stage2 { color: #c25e08; font-weight: 700; }

/* Caveats callout (Overview) — collapsible, uniform typography */
.caveat {
    margin-top: 1rem; border-left: 4px solid #b7791f; background: #fbf9f0;
    border-radius: 6px; padding: 0.55rem 1rem;
}
.caveat > summary {
    cursor: pointer; font-weight: 600; font-size: var(--fs-h4); color: #1C1C1C;
    list-style: none; padding: 0.2rem 0;
}
.caveat > summary::-webkit-details-marker { display: none; }
.caveat > summary::before { content: '\25B8\00a0'; color: #b7791f; }       /* ▸ */
.caveat[open] > summary::before { content: '\25BE\00a0'; color: #b7791f; } /* ▾ */
.caveat-body { color: #495057; font-size: var(--fs-body); line-height: 1.6; padding-top: 0.3rem; }
.caveat-body p { margin: 0.5rem 0; }
.caveat-body ul { margin: 0; padding-left: 1.25rem; }
.caveat-body li { margin-bottom: 0.35rem; }
.caveat-body strong { color: #1C1C1C; }
.caveat-foot { font-size: var(--fs-small); color: #6c757d; margin-top: 0.6rem; }
.caveat a { color: #1565c0; font-weight: 600; }

/* ============================================================
   Strategy Info Modal — info button (header-inline) + dialog
   Pattern mirrors #log-drawer (same blue header bar, same X)
   but centered as a dialog rather than slide-from-right.
   ============================================================ */

/* Inline info button next to a section h2 */
.info-btn {
    display: inline-flex; align-items: center; justify-content: center;
    margin-left: 0.55rem;
    background: none; border: none; padding: 0;
    color: #1565c0; cursor: pointer;
    font-size: 1.3rem; line-height: 1; vertical-align: 0.06em;
    opacity: 0.85; transition: opacity 0.15s, transform 0.15s;
}
.info-btn:hover  { opacity: 1; transform: scale(1.08); }
.info-btn:focus  { outline: 2px solid #1565c0; outline-offset: 3px; border-radius: 4px; }

/* Scrim under the modal */
#sim-scrim {
    position: fixed; inset: 0; background: rgba(20,30,60,0.4);
    opacity: 0; pointer-events: none; transition: 0.2s; z-index: 110;
}
#sim-scrim.on { opacity: 1; pointer-events: auto; }

/* Modal dialog — centered, capped width + height, body scrolls inside */
#sim-modal {
    position: fixed; top: 50%; left: 50%;
    transform: translate(-50%, -48%) scale(0.98);
    width: min(720px, calc(100vw - 2rem));
    max-height: 80vh;
    background: #fff; border-radius: 10px;
    box-shadow: 0 24px 60px rgba(0,0,0,0.25);
    opacity: 0; pointer-events: none; transition: 0.18s;
    z-index: 115; display: flex; flex-direction: column;
}
#sim-modal[hidden] { display: none; }
#sim-modal.open {
    opacity: 1; pointer-events: auto;
    transform: translate(-50%, -50%) scale(1);
}

/* Lock body scroll when modal is open */
body.sim-locked { overflow: hidden; }

/* Modal header — blue bar matching #log-drawer .dh */
#sim-modal .sim-dh {
    background: #1565c0; color: #fff;
    padding: 0.85rem 1.1rem;
    border-radius: 10px 10px 0 0;
    display: flex; justify-content: space-between; align-items: center;
    flex-shrink: 0;
}
#sim-modal .sim-dh h3 {
    font-size: var(--fs-h4); margin: 0; color: #fff; font-weight: 700;
}
#sim-modal .sim-dh .sim-x {
    cursor: pointer; background: none; border: none; color: #fff;
    font-size: var(--fs-h3); line-height: 1; padding: 0 0.25rem;
}
#sim-modal .sim-dh .sim-x:hover  { opacity: 0.75; }
#sim-modal .sim-dh .sim-x:focus  { outline: 2px solid #fff; outline-offset: 2px; border-radius: 4px; }

/* Modal body — scrollable */
#sim-modal .sim-db {
    padding: 1rem 1.2rem 1.2rem; overflow: auto; flex: 1 1 auto;
}

/* One section per family */
#sim-modal .sim-family { margin-bottom: 1.4rem; }
#sim-modal .sim-family:last-child { margin-bottom: 0.4rem; }
#sim-modal .sim-family h4 {
    font-size: var(--fs-h4); margin: 0 0 0.25rem; color: #1C1C1C;
    border-bottom: 1px solid #e9ecef; padding-bottom: 0.3rem;
}
#sim-modal .sim-count {
    color: #6c757d; font-size: var(--fs-small); font-weight: 500;
}
#sim-modal .sim-family-blurb {
    color: #495057; font-size: var(--fs-small); margin: 0.35rem 0 0.65rem;
    line-height: 1.5;
}

/* Definition list — name + description */
#sim-modal dl { margin: 0; }
#sim-modal dt {
    margin-top: 0.55rem;
}
#sim-modal dt code {
    background: #f1f3f5; color: #1565c0;
    padding: 0.1rem 0.4rem; border-radius: 4px;
    font-size: var(--fs-small);
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    word-break: break-all;
}
#sim-modal dd {
    margin: 0.2rem 0 0 0;
    color: #1C1C1C; font-size: var(--fs-ui); line-height: 1.5;
}
