/* ============================================================
   EU Trade Dashboard — SCREEN layer: components, layout, widgets,
   responsive rules. Loaded by every page after base.css.

   Never fed to weasyprint: everything here is interactive or
   screen-responsive chrome the print medium must not parse.
   Companion: main.css (component-compiled) + leaflet.css (vendor)
   ============================================================ */

/* ============================================================
   BASE PRIMITIVES
   ============================================================ */

/* -- Surface ------------------------------------------------ */

.card {
    background: var(--clr-surface);
    border: var(--micro-1) solid var(--clr-border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
}

/* Svelte components usually pad a .card via their own scoped <style> block;
   plain static pages (oauth.html, ...) have no such scope, so this general
   modifier covers the same need. */
.card-padded {
    padding: var(--space-5);
}

/* -- Button -------------------------------------------------
   .btn           outlined neutral button (default)
   .btn.active    pressed / toggled state (filled accent)
   .btn-accent    permanent CTA (filled accent at rest)
   .btn-sm        compact size
   .btn-block     stretches to fill its container
   .btn-icon      circular icon-only button
   ----------------------------------------------------------- */

.btn {
    font: inherit;
    font-size: var(--text-base);
    font-weight: 600;
    color: var(--clr-text);
    padding: var(--space-2) var(--space-3);
    border: var(--micro-2) solid var(--clr-border);
    border-radius: var(--radius);
    background: var(--clr-surface);
    cursor: pointer;
    white-space: nowrap;
    transition: all var(--transition);
}

.btn:hover {
    background: var(--clr-accent-light);
    border-color: var(--clr-accent);
    color: var(--clr-accent);
}

.btn.active,
.btn-accent {
    background: var(--clr-accent);
    border-color: var(--clr-accent);
    color: var(--clr-text-inverse);
}

.btn-accent:hover,
.btn.active:hover {
    background: var(--clr-accent-hover);
    border-color: var(--clr-accent-hover);
    color: var(--clr-text-inverse);
}

.btn:disabled,
.btn-accent:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* Filled destructive CTA (delete account) — the error-coloured
   counterpart of .btn-accent, layered on a plain .btn. */
.btn-danger {
    background: var(--clr-error);
    border-color: var(--clr-error);
    color: var(--clr-text-inverse);
}

.btn-danger:hover {
    background: color-mix(in srgb, var(--clr-error) 85%, black);
    border-color: color-mix(in srgb, var(--clr-error) 85%, black);
}

.btn-sm {
    padding: var(--space-1) var(--space-2);
    font-size: var(--text-sm);
}

/* Compact chart-action variant: even smaller than .btn-sm,
   used for the Rebase / % / Table / PNG / Excel buttons in
   each chart card's header row. */
.btn-xs {
    padding: var(--micro-3) var(--space-2);
    font-size: var(--text-sm);
    font-weight: 700;
    color: var(--clr-text-muted);
}

.btn-block {
    display: block;
    width: 100%;
    padding: var(--space-3);
    font-size: var(--text-base);
    font-weight: 700;
    letter-spacing: var(--tracking-normal);
}

.btn-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--space-7);
    min-width: var(--space-7);
    height: var(--space-7);
    padding: 0;
    border: var(--micro-2) solid var(--clr-border);
    border-radius: var(--radius);
    background: var(--clr-surface);
    color: var(--clr-text);
    font: inherit;
    font-size: var(--text-base);
    font-weight: 700;
    text-decoration: none;
    text-align: center;
    cursor: pointer;
    flex-shrink: 0;
    transition: all var(--transition);
}

.btn-icon:hover {
    background: var(--clr-accent-light);
    border-color: var(--clr-accent);
    color: var(--clr-accent);
}

/* -- Chip -- rectangular clickable badge ---------------------
   Used wherever the UI presents a short clickable token of
   information (welcome examples, header section switcher,
   product chip, breadcrumb step). Inline-flex so it can hold
   an icon next to a label.
   ----------------------------------------------------------- */

.chip {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    padding: var(--space-1) var(--space-3);
    font: inherit;
    font-size: var(--text-base);
    font-weight: 600;
    color: var(--clr-accent);
    background: var(--clr-surface);
    border: var(--micro-2) solid var(--clr-accent-light);
    border-radius: var(--radius);
    line-height: var(--leading-snug);
    white-space: nowrap;
    cursor: pointer;
    text-decoration: none;
    transition: all var(--transition);
}

.chip:hover {
    background: var(--clr-accent-light);
    border-color: var(--clr-accent);
    color: var(--clr-accent-hover);
}

.chip.active {
    background: var(--clr-accent);
    border-color: var(--clr-accent);
    color: var(--clr-text-inverse);
}

/* -- Button group containers -- merged with .btn ------------
   Each container layers its own arrangement on top of plain
   .btn children. The .toggle-group base class does NOT carry
   button styling itself.
   ----------------------------------------------------------- */

/* Sidebar form: bordered single-choice picker.
   Used for the Frequency and Outliers radios. */
.toggle-group {
    display: flex;
    border: var(--micro-2) solid var(--clr-border);
    border-radius: var(--radius);
    overflow: hidden;
}

.toggle-group .btn {
    flex: 1;
    border-radius: 0;
    border-width: 0;
}

.toggle-group .btn + .btn {
    border-left: var(--micro-2) solid var(--clr-border);
}

/* Section switcher (Lens / Tier 1) — lives at the top of the content
   column. The chips join into a single bordered strip (same joined-group
   geometry as .tabs and .toggle-group); the active item is told apart
   purely by its filled accent background (.chip.active). The strip
   scrolls horizontally on narrow viewports rather than hiding behind
   a dropdown. It sits flush on top of the .tabs strip — together they
   form one stacked navigation block. */
.section-nav {
    display: flex;
    flex-wrap: nowrap;
    margin-bottom: 0;
    overflow-x: auto;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    width: fit-content;
    max-width: 100%;
    background: var(--clr-surface);
    border: var(--micro-1) solid var(--clr-border);
    border-radius: var(--radius) var(--radius) 0 0;
}

.section-nav .chip {
    padding: var(--space-2) var(--space-3);
    border: none;
    border-radius: 0;
}

.section-nav .chip + .chip {
    border-left: var(--micro-1) solid var(--clr-border);
}

.section-nav::-webkit-scrollbar,
.tabs::-webkit-scrollbar {
    display: none;
}

/* -- Inline helpers ----------------------------------------- */

.residual {
    color: var(--clr-text-muted);
    font-size: var(--text-sm);
    font-style: italic;
}

.error {
    color: var(--clr-error);
}

.success {
    color: var(--clr-success);
}

/* Muted one-line helper text under a control or section
   (sidebar hints, search status lines, dialog hints). Margins stay
   contextual -- compose with a small layout class. */
.hint {
    font-size: var(--text-sm);
    color: var(--clr-text-muted);
}

/* -- Form primitives -----------------------------------------
   .input   bordered text box, sibling of .btn (sidebar filters,
            CN search, account dialog forms)
   .field   stacked <label>: bold small caption over a full-width
            control
   ------------------------------------------------------------ */

.input {
    width: 100%;
    min-width: 0;
    padding: var(--space-2) var(--space-3);
    font: inherit;
    font-size: var(--text-base);
    color: var(--clr-text);
    background: var(--clr-surface);
    border: var(--micro-2) solid var(--clr-border);
    border-radius: var(--radius);
    transition:
        border-color var(--transition),
        box-shadow var(--transition);
}

.input:hover {
    border-color: var(--clr-accent);
}

.field {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    margin-bottom: var(--space-3);
    font-size: var(--text-sm);
    font-weight: 600;
}

/* ===== FOCUS ===== */

input:focus,
select:focus {
    outline: var(--micro-2) solid var(--clr-accent);
    outline-offset: var(--micro-1);
    border-color: var(--clr-accent);
    box-shadow: 0 0 0 var(--micro-3) var(--clr-accent-light);
}

:focus-visible {
    outline: var(--micro-2) solid var(--clr-accent);
    outline-offset: var(--micro-2);
}

:focus:not(:focus-visible) {
    outline: none;
}

/* ============================================================
   LAYOUT
   ============================================================ */

.layout {
    display: grid;
    grid-template-columns: var(--sidebar-width) 1fr;
    min-height: calc(100vh - var(--header-height));
    /* Dynamic viewport height: tracks mobile browser chrome showing/hiding
       instead of reserving space for it permanently (100vh fallback above). */
    min-height: calc(100dvh - var(--header-height));
}

/* -- Skip link --------------------------------------------- */

.skip-link {
    position: absolute;
    top: 0;
    left: var(--space-4);
    padding: var(--space-2) var(--space-4);
    background: var(--clr-accent);
    color: var(--clr-text-inverse);
    border-radius: 0 0 var(--radius) var(--radius);
    font-weight: 700;
    font-size: var(--text-base);
    z-index: 9999;
    text-decoration: none;
    transform: translateY(-100%);
    transition: transform var(--transition);
}

.skip-link:focus {
    transform: translateY(0);
}

.header-help {
    display: flex;
    align-items: center;
    gap: var(--space-1);
    margin-inline-start: auto; /* pin to the right end of the header */
    color: var(--clr-text-muted);
    text-decoration: none;
    font-size: var(--text-sm);
    font-weight: 600;
    padding: var(--space-1) var(--space-2);
    border-radius: var(--radius);
    transition:
        background var(--transition),
        color var(--transition);
}

.header-help:hover {
    background: var(--clr-accent-light);
    color: var(--clr-accent);
}

/* -- Header right-hand cluster ----------------------------- */

.header-actions {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

/* ── Header dropdowns (language & palette) ──────────────── */
.hdr-drop {
    position: relative;
}

.hdr-drop-btn {
    display: flex;
    align-items: center;
    gap: var(--micro-2);
    font: inherit;
    font-size: var(--text-sm);
    font-weight: 700;
    padding: var(--space-2) var(--space-3);
    background: var(--clr-surface-alt);
    border: var(--micro-1) solid var(--clr-border);
    border-radius: var(--radius);
    color: var(--clr-text-muted);
    cursor: pointer;
    white-space: nowrap;
}

.hdr-drop-btn > svg {
    flex-shrink: 0;
}

.hdr-drop-menu {
    display: flex;
    flex-direction: column;
    position: absolute;
    top: 100%;
    right: 0;
    padding-top: var(--space-1);
    background: var(--clr-surface);
    border: var(--micro-1) solid var(--clr-border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-md);
    overflow: hidden;
    width: max-content;
    min-width: var(--space-16);
    z-index: 200;
    visibility: hidden;
    opacity: 0;
    transition:
        visibility 0s 180ms,
        opacity 80ms ease 180ms;
}

.hdr-drop:hover .hdr-drop-menu,
.hdr-drop:focus-within .hdr-drop-menu {
    visibility: visible;
    opacity: 1;
    transition:
        visibility 0s,
        opacity 80ms ease;
}

.hdr-drop-opt {
    font: inherit;
    font-size: var(--text-sm);
    font-weight: 600;
    padding: var(--micro-4) var(--space-3);
    background: transparent;
    border: none;
    color: var(--clr-text-muted);
    cursor: pointer;
    text-align: left;
    white-space: nowrap;
}

.hdr-drop-opt:hover {
    background: var(--clr-accent-light);
    color: var(--clr-accent);
}

.hdr-drop-opt.active {
    background: var(--clr-accent);
    color: var(--clr-text-inverse);
}

/* ── Consolidated header menu (account · palette · language · FAQ) ── */
.hdr-menu {
    min-width: var(--space-20);
    width: max-content;
    padding-bottom: var(--space-1);
}

/* Language menu: caps height and scrolls so the full EU language set fits. */
.hdr-menu-lang {
    max-height: var(--space-32);
    overflow-y: auto;
}

.hdr-section {
    padding: var(--space-1) var(--space-3) var(--micro-2);
    font-size: var(--text-sm);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: var(--tracking-wide);
    color: var(--clr-text-muted);
}

.hdr-sep {
    height: var(--micro-1);
    margin: var(--space-1) 0;
    background: var(--clr-border);
}

.hdr-account {
    font-weight: 700;
    color: var(--clr-accent);
}

.hdr-account-email {
    display: block;
    max-width: var(--space-32);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.hdr-drop-btn.signed-in {
    color: var(--clr-accent);
    border-color: var(--clr-accent);
}

/* FAQ link reuses .hdr-drop-opt; strip the anchor defaults. */
a.hdr-drop-opt {
    text-decoration: none;
    display: block;
}

.nav-back {
    display: flex;
    align-items: center;
    gap: var(--space-1);
}

.nav-back a {
    font-size: var(--text-base);
    font-weight: 600;
    color: var(--clr-text-muted);
    text-decoration: none;
    padding: var(--space-1) var(--space-3);
    border-radius: var(--radius);
    transition:
        background var(--transition),
        color var(--transition);
}

/* -- Sidebar ------------------------------------------------ */

.sidebar {
    position: sticky;
    top: var(--header-height);
    height: calc(100dvh - var(--header-height));
    overflow: hidden;
    background: var(--clr-surface);
    border-right: var(--micro-1) solid var(--clr-border);
    display: flex;
    flex-direction: column;
}

.sidebar form {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    padding: var(--space-5) var(--space-4) var(--space-2);
}

.sidebar fieldset {
    border: none;
    padding: 0;
}

.sidebar legend {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    font-size: var(--text-base);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: var(--tracking-wider);
    color: var(--clr-accent);
    border-bottom: var(--micro-2) solid rgba(212, 149, 46, 0.45);
    padding-bottom: var(--space-1);
    margin-bottom: var(--space-2);
}

.legend-help {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--em-lg);
    height: var(--em-lg);
    border-radius: var(--radius);
    border: var(--micro-2) solid var(--clr-text-muted);
    color: var(--clr-text-muted);
    font-size: var(--text-sm);
    font-weight: 700;
    line-height: var(--leading-tight);
    text-decoration: none;
    padding: var(--micro-2);
    flex-shrink: 0;
    transition: all var(--transition);
}

.legend-help:hover {
    border-color: var(--clr-accent);
    color: var(--clr-surface);
    background: var(--clr-accent);
}

/* Backdrop appears behind the open sidebar on mobile */
.sidebar-backdrop {
    position: fixed;
    inset: 0;
    background: transparent;
    border: none;
    cursor: default;
    z-index: -1;
}

/* Pinned footer area inside the sidebar (Apply button + credits) */
.sidebar-sticky {
    flex-shrink: 0;
    padding: var(--space-3) var(--space-4);
    border-top: var(--micro-1) solid var(--clr-border);
    background: var(--clr-surface);
}

.sidebar-footer {
    margin-top: var(--space-2);
    font-size: var(--text-sm);
    color: var(--clr-text-muted);
    text-align: center;
    line-height: var(--leading-loose);
}

.sidebar-update {
    margin: 0;
    font-size: var(--text-sm);
    color: var(--clr-text-muted);
    text-align: center;
    opacity: 0.75;
}

.footer-line {
    display: block;
}
.footer-sep {
    margin: 0 var(--space-1);
    opacity: 0.5;
}

/* Close × button — visible on mobile only */
.sidebar-close {
    display: none;
    position: absolute;
    top: var(--space-3);
    right: var(--space-3);
    background: none;
    border: none;
    font-size: var(--text-xl);
    color: var(--clr-text-muted);
    cursor: pointer;
    z-index: 10;
    line-height: var(--leading-tight);
}

/* Mobile-only hamburger */
.toggle {
    display: none;
    flex-direction: row;
    align-items: center;
    gap: var(--space-2);
    background: var(--clr-accent);
    border: none;
    cursor: pointer;
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius);
    color: var(--clr-text-inverse);
}

.toggle svg {
    flex-shrink: 0;
}

.toggle-label {
    font-size: var(--text-sm);
    font-weight: 700;
    letter-spacing: var(--tracking-wide);
    text-transform: uppercase;
}

/* -- Form helpers ------------------------------------------ */

/* A horizontal row of form controls (text input + button, two dates, …) */
.field-row {
    display: flex;
    gap: var(--space-2);
    align-items: center;
}

/* Children that should expand to share the row equally (date pickers,
   month inputs, etc.). The `input[type="month"]` form was used before
   we replaced those with <PeriodPicker> selects. */
.field-row > select,
.field-row > input[type="month"] {
    flex: 1;
    min-width: 0;
}

/* Stacked variant: controls go one per line instead of side by side
   (product code input with its Validate button, so the long placeholder
   stays fully visible). */
.field-row--stack {
    flex-direction: column;
    align-items: stretch;
}

.input-sep {
    color: var(--clr-text-muted);
    font-size: var(--text-base);
    font-weight: 600;
    flex-shrink: 0;
}

/* Sidebar text inputs use the shared .input primitive (markup); only
   the select keeps its own rule here (same box, plus the chevron). */
.sidebar select {
    width: 100%;
    min-width: 0;
    padding: var(--space-2) var(--space-3);
    font: inherit;
    font-size: var(--text-base);
    color: var(--clr-text);
    background: var(--clr-surface);
    border: var(--micro-2) solid var(--clr-border);
    border-radius: var(--radius);
    transition:
        border-color var(--transition),
        box-shadow var(--transition);
    cursor: pointer;
    appearance: none;
    padding-right: var(--space-8);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' fill='none'%3E%3Cpath d='M1 1.5l5 5 5-5' stroke='%235c6b88' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right var(--space-2) center;
    background-size: var(--space-3);
}

.sidebar select:hover {
    border-color: var(--clr-accent);
}

.search-input {
    margin-bottom: var(--space-1);
}

/* Slightly smaller placeholder so the full example hint fits */
.product-input::placeholder {
    font-size: var(--text-sm);
}

/* -- Product chips (validated codes in sidebar) ------------ */

.product-chips {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-1);
    margin-top: var(--space-1);
    list-style: none;
}

.product-chips:empty {
    display: none;
}

/* Filled accent variant of .chip with an inline remove button */
.product-chip {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    padding: var(--space-1) var(--space-1) var(--space-1) var(--space-3);
    color: var(--clr-accent);
    background: var(--clr-accent-light);
    border: var(--micro-2) solid var(--clr-accent);
    border-radius: var(--radius);
    font-size: var(--text-sm);
    font-weight: 600;
    line-height: var(--leading-snug);
}

.product-chip-remove {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--em-lg);
    height: var(--em-lg);
    padding: 0;
    border: none;
    border-radius: var(--radius);
    background: transparent;
    color: var(--clr-accent);
    font: inherit;
    font-size: var(--text-base);
    font-weight: 700;
    line-height: var(--leading-tight);
    cursor: pointer;
    transition: all var(--transition);
}

.product-chip-remove:hover {
    background: var(--clr-error);
    color: var(--clr-text-inverse);
}

/* Colour/size come from the shared .hint primitive; only the layout
   is sidebar-specific. */
.multi-code-hint {
    margin-top: var(--space-2);
    line-height: var(--leading-snug);
}

/* -- Main column ------------------------------------------- */

.main {
    padding: var(--space-5);
    position: relative;
    min-height: var(--space-32);
    min-width: 0;
    overflow: hidden;
    background: transparent;
}

/* -- Welcome screen ---------------------------------------- */

.welcome {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    min-height: 50vh;
    gap: var(--space-3);
    color: var(--clr-text-muted);
    padding: var(--space-6) var(--space-5);
    max-width: 52.5rem;
    margin: var(--space-6) auto;
}

.welcome h2 {
    font-size: var(--text-xl);
    font-weight: 700;
    color: var(--clr-accent);
}

.welcome code {
    font-size: var(--em-sm);
}

.welcome-hint {
    font-size: var(--text-base);
}

.welcome-cn-note {
    max-width: 38rem;
    text-align: justify;
    hyphens: auto;
}

.welcome-sub-heading {
    margin-top: var(--space-4);
    font-size: var(--text-md);
    font-weight: 700;
    color: var(--clr-text-muted);
}

.welcome-examples {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    justify-content: center;
    margin: var(--space-4) 0;
    list-style: none;
}

/* Separates the "find a code" act (search, CN notes, CN browser) from
   the feature-tour table below it. */
.welcome-divider {
    width: 100%;
    border: 0;
    border-top: var(--micro-1) solid var(--clr-border);
    margin: var(--space-5) 0 var(--space-2);
}

/* Feature tour: one hairline-separated row per dashboard menu, section
   label + guiding question on the left, example chips stacked on the
   right. Same hairline language as the joined strips. No border-top
   here — the .welcome-divider above the table already plays that role. */
.tour-table {
    width: 100%;
    margin-top: var(--space-2);
    list-style: none;
    text-align: left;
}

.tour-row {
    display: grid;
    grid-template-columns: 13rem 1fr;
    gap: var(--space-4);
    padding: var(--space-3) 0;
    border-bottom: var(--micro-1) solid var(--clr-border);
    align-items: start;
}

.tour-label .welcome-sub-heading {
    margin-top: 0;
    font-size: var(--text-base);
}

.tour-question {
    font-size: var(--text-sm);
    margin-top: var(--micro-3);
}

/* Chips stack vertically inside their row, tighter than the base
   centered wrap used elsewhere. */
.tour-row .welcome-examples {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-1);
    margin: 0;
}

/* SEO feature lists — only used by the static pre-JS welcome page in
   index.html (the Svelte app replaces it on mount). */
.welcome-group-heading {
    margin-top: var(--space-4);
    font-size: var(--text-base);
    font-weight: 700;
    color: var(--clr-text-muted);
}

.welcome-features {
    text-align: left;
    list-style: disc;
    margin: var(--space-3) 0 0;
    padding-left: var(--space-5);
    max-width: 40rem;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    font-size: var(--text-base);
}

.welcome-features strong {
    color: var(--clr-text);
}

.welcome-faq-link {
    margin-top: var(--space-3);
    padding: var(--space-3) var(--space-5);
}

/* ============================================================
   NOMENCLATURE HIERARCHY (shared)
   Code → description rows shared by the dashboard product
   breadcrumb (ProductBreadcrumb.svelte) and the welcome-page CN
   browser (CNBrowser.svelte). One definition for both.
   ============================================================ */

/* Clickable code, styled as an accent link. */
.nom-code {
    background: none;
    border: 0;
    padding: 0;
    font: inherit;
    font-weight: 600;
    color: var(--clr-accent);
    cursor: pointer;
    white-space: nowrap;
}

.nom-code:hover {
    color: var(--clr-accent-hover);
    text-decoration: underline;
}

/* Muted descriptive text shown next to a code. */
.nom-desc {
    color: var(--clr-text-muted);
    font-weight: 400;
    margin-left: var(--space-1);
}

/* Truncatable parent-level description (breadcrumb click-to-expand). */
.nom-desc-parent.truncated {
    cursor: pointer;
    border-bottom: 1px dotted currentColor;
    opacity: 0.75;
    transition: opacity var(--transition);
}

.nom-desc-parent.truncated:hover,
.nom-desc-parent.desc-expanded {
    opacity: 1;
}

.nom-desc-parent.desc-expanded {
    border-bottom: none;
}

/* Residual catch-all hint: "(other than 2009 11, …)". */
.nom-residual {
    margin-left: var(--space-1);
    color: var(--clr-text-muted);
    font-size: var(--text-sm);
    font-style: italic;
    cursor: help;
}

/* Untranslated marker: the localized scope note is missing, so the
   English self-explanatory text is shown instead. */
.nom-untranslated {
    margin-left: var(--space-1);
    padding: 0 var(--space-1);
    border: var(--micro-1) solid var(--clr-border);
    border-radius: var(--radius);
    font-size: var(--text-sm);
    font-weight: 600;
    line-height: var(--leading-snug);
    color: var(--clr-text-muted);
    text-transform: uppercase;
    letter-spacing: var(--tracking-wide);
    cursor: help;
    white-space: nowrap;
    vertical-align: baseline;
}

/* Expand/collapse chevron. */
.nom-arrow {
    display: inline-block;
    font-size: var(--text-sm);
    line-height: var(--leading-tight);
    transition: transform var(--transition);
}

.nom-arrow.open {
    transform: rotate(90deg);
}

/* -- Product breadcrumb (dashboard) ------------------------- */
/* Composed with global `.card`; only the layout lives here. */
.product-breadcrumb {
    display: flex;
    align-items: flex-start;
    gap: 0;
    margin-bottom: var(--space-3);
    padding: var(--space-3) var(--space-4);
    font-size: var(--text-sm);
    line-height: var(--leading-loose);
    position: relative;
}

.breadcrumb-rows {
    flex: 1;
    min-width: 0;
}

.breadcrumb-row {
    display: block;
}

.breadcrumb-row + .breadcrumb-row {
    padding-top: var(--space-1);
    border-top: 1px solid var(--clr-border);
    margin-top: var(--space-1);
}

.breadcrumb-item:not(:last-child)::after {
    content: "›";
    margin: 0 var(--space-1);
    color: var(--clr-text-muted);
    font-weight: 600;
}

/* Collapsible behaviour — fold the panel and show a toggle. */
.product-breadcrumb.collapsible:not(.expanded) .breadcrumb-rows {
    max-height: var(--em-2xl);
    overflow: hidden;
}

.product-breadcrumb.expanded {
    max-height: none;
    overflow: visible;
}

.breadcrumb-toggle {
    display: inline-flex;
    align-items: center;
    background: none;
    border: none;
    padding: var(--space-1);
    cursor: pointer;
    color: var(--clr-accent);
    flex-shrink: 0;
    align-self: flex-start;
    margin-right: var(--space-1);
}

.breadcrumb-toggle:hover {
    opacity: 0.75;
}

.breadcrumb-toggle .nom-arrow {
    color: var(--clr-accent);
}

/* -- Welcome CN browser ------------------------------------- */
/* The root "All chapters" toggle inherits the welcome page's centering;
   the tree itself is left-aligned. */
.cn-browser {
    width: 100%;
    margin: var(--space-2) 0;
}

.cn-browser-root {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    background: none;
    border: 0;
    padding: var(--space-1) 0;
    font: inherit;
    font-weight: 700;
    color: var(--clr-accent);
    cursor: pointer;
}

.cn-browser-root:hover {
    color: var(--clr-accent-hover);
}

.cn-browser-root .nom-arrow {
    color: inherit;
}

.cn-browser-status {
    color: var(--clr-text-muted);
    font-size: var(--text-sm);
    margin: var(--space-2) 0;
}

.cn-browser-retry {
    background: none;
    border: 0;
    padding: 0;
    font: inherit;
    color: var(--clr-accent);
    cursor: pointer;
    text-decoration: underline;
}

/* Tree lists. */
.nom-tree,
.nom-children {
    list-style: none;
    margin: 0;
    padding: 0;
}

.nom-tree {
    margin-top: var(--space-1);
    text-align: left;
}

/* Indented children with a guide line. */
.nom-children {
    margin-left: var(--space-2);
    padding-left: var(--space-3);
    border-left: var(--micro-2) solid var(--clr-border);
}

/* One code → description row. */
.nom-node {
    display: flex;
    align-items: baseline;
    gap: var(--space-1);
    padding: var(--space-1) 0;
    line-height: var(--leading-normal);
}

/* Description wraps within the row — many CN texts are long. */
.nom-node .nom-desc {
    flex: 1 1 auto;
    min-width: 0;
    margin-left: 0;
    font-size: var(--text-sm);
}

/* The tree's arrow is itself the toggle button. */
.cn-browser .nom-arrow {
    flex-shrink: 0;
    width: var(--space-4);
    text-align: center;
    color: var(--clr-accent);
}

.cn-browser button.nom-arrow {
    background: none;
    border: 0;
    padding: 0;
    cursor: pointer;
}

.nom-arrow-leaf {
    visibility: hidden;
}

@media (max-width: 1024px) {
    .product-breadcrumb {
        padding: var(--space-2) var(--space-3);
        margin-bottom: var(--space-3);
    }
    .product-breadcrumb.collapsible:not(.expanded) .breadcrumb-rows {
        max-height: var(--em-2xl);
    }
    .breadcrumb-item:not(:last-child)::after {
        margin: 0 var(--space-1);
    }
}

@media (max-width: 768px) {
    .product-breadcrumb.collapsible:not(.expanded) .breadcrumb-rows {
        max-height: var(--em-2xl);
    }
}

@media (max-width: 480px) {
    .product-breadcrumb {
        padding: var(--space-1) var(--space-2);
        margin-bottom: var(--space-1);
    }
}

/* ============================================================
   DASHBOARD WIDGETS
   ============================================================ */

/* -- Tab bar -------------------------------------------------
   Same joined-strip geometry as .section-nav, one tier down: the
   active tab is set apart by a light accent wash and accent text
   instead of a solid fill, so the two rows read as primary and
   secondary rather than competing button bars. The strip sticks to
   the .section-nav above it: no top border, no top rounding.
   ------------------------------------------------------------ */

.tabs {
    display: flex;
    margin-bottom: var(--space-4);
    overflow-x: auto;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    width: fit-content;
    max-width: 100%;
    background: var(--clr-surface);
    border: var(--micro-1) solid var(--clr-border);
    border-top: none;
    border-radius: 0 0 var(--radius) var(--radius);
}

.tab {
    padding: var(--space-2) var(--space-4);
    /* one step below the .section-nav above it, at every viewport:
       the strips scroll horizontally when tight, so no shrinking */
    font-size: var(--text-sm);
    font-weight: 600;
    border: none;
    background: transparent;
    color: var(--clr-text-muted);
    cursor: pointer;
    transition:
        background var(--transition),
        color var(--transition);
    white-space: nowrap;
    flex: 0 0 auto;
}

.tab + .tab {
    border-left: var(--micro-1) solid var(--clr-border);
}

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

.tab.active {
    background: var(--clr-accent-light);
    color: var(--clr-accent);
}

/* -- Tab explainer frame ---------------------------------------
   This new frame replaces the old TabExplainer component.
   It's centered, has a neutral background, and adapts its width
   based on screen size: full width on small screens (1x4 grid)
   or max-width of one chart card on larger screens (2x2 grid).
   --------------------------------------------------------- */

.tab-explainer-frame,
.note {
    width: 100%;
    max-width: 67%;
    margin-left: auto;
    margin-right: auto;
}

.tab-explainer-frame {
    background-color: var(--clr-surface-alt);
    border: var(--micro-1) solid var(--clr-border);
    border-radius: var(--radius);
    padding: var(--space-3) var(--space-4);
    margin-bottom: var(--space-5);
    font-size: var(--text-sm);
    line-height: var(--leading-relaxed);
}

.tab-explainer-frame p {
    margin: 0 0 var(--space-2);
}

.tab-explainer-frame p:last-child {
    margin-bottom: 0;
}

.tab-explainer-frame ol {
    margin: 0;
    padding-left: var(--space-5);
}

.tab-explainer-frame li {
    margin-bottom: var(--space-1);
}

.tab-explainer-frame a {
    color: var(--clr-accent);
    text-decoration: underline;
}

@media (max-width: 1024px) {
    .tab-explainer-frame,
    .note {
        max-width: 100%;
    }
}

/* -- Tab-panel sub-section heading ------------------------
   <h3> sitting directly inside a .tab-panel (between chart
   grids) gets section-heading styling for free — no class.
   A <select> inside such a heading is treated as an inline
   dropdown that reads as part of the sentence.
   --------------------------------------------------------- */

.tab-panel > h3 {
    margin: var(--space-5) 0 var(--space-2);
    font-size: var(--text-md);
    font-weight: 600;
    line-height: var(--leading-loose);
}

.tab-panel > h3:first-child {
    margin-top: 0;
}

.tab-panel > h3 select {
    width: auto;
    font-size: var(--text-base);
    font-weight: 700;
    padding: var(--space-1) var(--space-2);
    border: var(--micro-1) solid var(--clr-border);
    border-radius: var(--radius);
    background: var(--clr-surface);
    color: var(--clr-text);
    cursor: pointer;
    vertical-align: baseline;
}

/* -- Chart grid -------------------------------------------- */

.chart-grid {
    display: grid;
    gap: var(--space-4);
    max-width: 100%;
}

.grid-2x2 {
    grid-template-columns: 1fr 1fr;
}

/* -- Chart card -------------------------------------------- */

.chart-card {
    min-width: 0;
    overflow: hidden;
    position: relative;
    transition:
        box-shadow 0.2s ease,
        transform 0.2s ease;
}

.chart-card:hover {
    box-shadow: var(--shadow-md);
    transform: translateY(calc(-1 * var(--micro-2)));
}

/* Applied to chart cards or canvases that are clickable drill-downs */
.chart-clickable {
    cursor: pointer;
}

.chart-card canvas {
    width: 100% !important;
    height: auto !important;
    max-height: 18.75rem;
    max-width: 100%;
    padding: var(--space-3) var(--space-4);
    display: block;
}

/* Chart card header row — uses the semantic <header> element
   so consumers don't need a class. Children: a .chart-title-group
   on the left, optional .chart-actions on the right. */
.chart-card > header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--space-3) var(--space-4);
    position: relative;
    z-index: 10;
}

.chart-card > header:has(.chart-title-edit) {
    flex-wrap: wrap;
}

.chart-card > header h3 {
    font-size: var(--text-base);
    font-weight: 600;
    color: var(--clr-text);
    margin: 0;
}

.chart-card > header h3.has-custom {
    font-style: italic;
}

/* Layout for the title + InfoTip cluster on the left side of
   the chart-card header. */
.chart-title-group {
    display: flex;
    align-items: center;
    gap: var(--space-1);
    min-width: 0;
}

/* The chart title text is an <h3> wrapping a <button>: the h3
   keeps the heading semantics, the button makes the text
   click-to-edit and keyboard-focusable. The button visually
   inherits the h3 styling and adds the dashed-underline
   affordance on hover. */
.chart-titlebtn {
    all: unset;
    cursor: pointer;
    font: inherit;
    color: inherit;
    border-bottom: var(--micro-1) dashed transparent;
    transition:
        border-color var(--transition),
        color var(--transition);
}

.chart-titlebtn:hover {
    border-bottom-color: var(--clr-text-muted);
    color: var(--clr-accent);
}

.chart-title-edit {
    width: 100%;
    font: inherit;
    font-size: var(--text-base);
    font-weight: 600;
    color: var(--clr-text);
    padding: var(--space-1) var(--space-2);
    border: var(--micro-1) solid var(--clr-accent);
    border-radius: var(--radius);
    background: var(--clr-surface);
    box-shadow: 0 0 0 var(--micro-3) var(--clr-accent-light);
    resize: vertical;
    min-height: var(--em-2xl);
    max-height: calc(3.75 * var(--em-md));
    line-height: var(--leading-normal);
}

.chart-title-edit:focus {
    outline: none;
}

.chart-card.pair-hidden {
    display: none;
}
.chart-card.pair-table-active {
    grid-column: span 2;
}

/* Tall variant: spans both rows of a 2×2 grid, for dense category axes
   (e.g. the 27-member reporter ranking). The canvas height is one em-scaled
   row pitch per bar, so it grows with the root font size instead of being
   pinned to a fixed pixel height. */
.chart-card--tall {
    grid-row: span 2;
}
.chart-card--tall .card.chart > div {
    height: calc(27 * var(--em-2xl));
}
.chart-card--tall canvas {
    max-height: none;
}

/* -- Data table ----------------------------------------------
   Used for the flip-to-table view inside chart cards and any
   standalone data table. Wrap in .data-table-wrap to get a
   scrollable, bordered frame.

   Sticky first column: add class="col-country" to the first
   <th> and <td> in each row. The class works for any label
   column (country, member-state, partner, etc.).
   ----------------------------------------------------------- */

.data-table-wrap {
    flex: 1;
    min-height: 0;
    overflow: auto;
    border: var(--micro-1) solid var(--clr-border);
    border-radius: var(--radius);
}

.data-table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--text-sm);
    white-space: nowrap;
}

.data-table thead {
    position: sticky;
    top: 0;
    z-index: 1;
}

.data-table th {
    background: var(--clr-accent);
    color: var(--clr-text-inverse);
    font-weight: 600;
    padding: var(--space-1) var(--space-3);
    text-align: left;
    border-bottom: var(--micro-2) solid var(--clr-accent-hover);
}

.data-table td {
    padding: var(--space-1) var(--space-3);
    border-bottom: var(--micro-1) solid var(--clr-border);
    color: var(--clr-text);
}

.data-table tbody tr:nth-child(even) {
    background: rgba(0, 0, 0, 0.02);
}

.data-table tbody tr:hover,
.data-table tbody tr:nth-child(even):hover {
    background: var(--clr-accent-light);
}

.data-table td.num {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.data-table td.bal-pos {
    color: var(--clr-success);
}

.data-table td.period-cell {
    vertical-align: top;
    font-weight: 600;
}

/* PRODCOM member tables (production volumes / concentration, sub-contracting):
   a muted per-row "count of years by data status" notice column. Add .flagged
   to accent rows that carry at least one suppressed / missing year. */
.data-table td.cell-note {
    font-size: var(--text-sm);
    color: var(--clr-text-muted);
}

.data-table td.cell-note.flagged {
    color: var(--clr-accent);
}

/* A value-less data cell showing the reason the figure is absent
   (confidential / not available / …) in place of a number. */
.data-table td.cell-gap {
    font-size: var(--text-xs, var(--text-sm));
    font-style: italic;
    color: var(--clr-text-muted);
    white-space: nowrap;
}

/* Sticky first (label) column — apply col-country to the
   first <th> and first <td> in every row. */
.data-table .col-country {
    position: sticky;
    left: 0;
}

.data-table thead .col-country {
    z-index: 3; /* above sticky thead (z-index 1) AND body sticky cells */
    background: var(--clr-accent);
}

.data-table tbody .col-country {
    z-index: 1; /* above horizontally-scrolling data cells */
    background: var(--clr-surface);
    /* Reset the header look when the label cell is a <th> (row header):
       .data-table th would otherwise leave it white-on-white. */
    color: var(--clr-text);
}

/* Replicate the tr-level stripe/hover as a solid background
   so the sticky cell never becomes transparent over scrolling content. */
.data-table tbody tr:nth-child(even) .col-country {
    background: color-mix(in srgb, var(--clr-surface) 98%, #000 2%);
}

.data-table tbody tr:hover .col-country,
.data-table tbody tr:nth-child(even):hover .col-country {
    background: var(--clr-accent-light);
}

/* Map container — used inside chart cards of type="map". */
.map-container {
    height: 23.75rem;
    width: 100%;
    background: #d1e4f0;
    border-radius: 0 0 var(--radius) var(--radius);
    z-index: 0;
}

/* A chart card containing a Leaflet map must clip its overflow
   so the map respects the card's rounded corners. */
.chart-card:has(.map-container) {
    overflow: hidden;
}

/* -- Chart toolbar ----------------------------------------- */

.chart-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-3);
    width: fit-content;
    margin-bottom: var(--space-4);
    padding: var(--space-2) var(--space-3);
    background: var(--clr-surface-alt);
    border: var(--micro-1) solid var(--clr-border);
    border-radius: var(--radius);
    font-size: var(--text-base);
    color: var(--clr-text-muted);
}

.chart-toolbar .toolbar-sep {
    width: var(--micro-1);
    height: var(--em-lg);
    background: var(--clr-border);
    flex-shrink: 0;
}

/* Centred variant: a boxed toolbar (legends, toggles, pickers) sitting
   centred above its chart grid rather than flush-left. */
.chart-toolbar--center {
    margin-left: auto;
    margin-right: auto;
}

/* Bare, centred row for a measure switcher (SegmentedControl) with no
   surrounding surface — used above the chart grids on the Overview,
   breakdown and concentration tabs. */
.chart-measure-bar {
    display: flex;
    justify-content: center;
    margin-bottom: var(--space-4);
}

/* PRODCOM code picker — shared by IndustrialExposure, SubcontractingMembers,
   SubcontractingIntensity, and ProductionVolumes tabs. Centered, capped at one
   chart-card column so it never exceeds the chart grid width. */
.prodcom-picker {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin: 0 auto var(--space-4);
    width: fit-content;
    max-width: 100%;
}

.prodcom-picker-label {
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--clr-text);
    white-space: nowrap;
}

.prodcom-picker-select {
    padding: var(--space-1) var(--space-2);
    font-size: var(--text-sm);
    border: var(--micro-1) solid var(--clr-border);
    border-radius: var(--radius);
    background: var(--clr-surface);
    color: var(--clr-text);
    max-width: 100%;
}

.prodcom-picker-select:disabled {
    opacity: 0.6;
}

/* Volatility colour-scale legend (inside .chart-toolbar) */
.vol-legend-bar {
    height: var(--space-3);
    width: var(--space-32);
    border-radius: var(--radius);
    background: linear-gradient(
        to right,
        rgba(46, 168, 122, 0.85),
        rgba(212, 149, 46, 0.85),
        rgba(194, 90, 46, 0.85),
        rgba(140, 29, 47, 0.85)
    );
}

.vol-legend-label {
    white-space: nowrap;
    font-size: var(--text-base);
    color: var(--clr-text-muted);
}

/* Empty / loading / error state for any container that needs to
   say "nothing to show here". Flex-centred so it works both as
   a stand-alone <p> and inside a fixed-height parent (maps,
   table flip cards, bottle grids, etc.). */
.empty-state {
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    color: var(--clr-text-muted);
    font-style: italic;
    padding: var(--space-5) var(--space-4);
}

/* -- Sidebar partner checklist ----------------------------- */

.partner-custom {
    margin-top: var(--space-2);
}

.partner-checklist {
    max-height: 12.5rem;
    overflow-y: auto;
    border: var(--micro-1) solid var(--clr-border);
    border-radius: var(--radius);
    padding: var(--space-1);
    display: flex;
    flex-direction: column;
    gap: var(--micro-2);
}

.partner-checklist label {
    display: flex;
    align-items: center;
    gap: var(--space-1);
    padding: var(--space-1);
    font-size: var(--text-base);
    border-radius: var(--radius);
    cursor: pointer;
}

.partner-checklist label:hover {
    background: var(--clr-bg);
}
.partner-checklist label.hidden {
    display: none;
}

/* -- Sub-tree --------------------------------------------- */

.subtree {
    list-style: none;
    padding-left: var(--space-4);
    margin: var(--space-1) 0 0;
    border-left: var(--micro-2) solid var(--clr-border);
}

.subtree li {
    padding: var(--space-1) 0;
    line-height: var(--leading-normal);
}

/* Muted descriptive text shown next to each sub-tree code. */
.subtree-desc {
    color: var(--clr-text-muted);
    font-size: var(--text-sm);
}

/* Inline-flex <label> wrapping a checkbox + text. Used for the
   "Shared scale" toggle in chart toolbars and likely future
   inline checkboxes. */
.toggle-label {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--clr-text-muted);
    cursor: pointer;
    white-space: nowrap;
    user-select: none;
}

.toggle-label input[type="checkbox"] {
    width: auto;
    accent-color: var(--clr-accent);
}

/* -- Phase tag ----------------------------------------------
   Pill-shaped, colour-coded label for the lifecycle phase of
   a partner in the Supply Shocks tab. Reused inside the bottle
   grid and in the explainer text. One base rule + one one-line
   modifier per phase, driven by a --phase custom property.
   ----------------------------------------------------------- */

.phase-tag {
    --phase: var(--clr-text-muted);
    display: inline-block;
    font-weight: 700;
    font-size: var(--text-sm);
    line-height: var(--leading-normal);
    letter-spacing: var(--tracking-normal);
    white-space: nowrap;
    padding: var(--micro-2) var(--space-2);
    border-radius: var(--radius-pill);
    text-transform: capitalize;
    background: color-mix(in srgb, var(--phase) 14%, transparent);
    color: color-mix(in srgb, var(--phase), black 40%);
    border: var(--micro-1) solid
        color-mix(in srgb, var(--phase) 35%, transparent);
}

/* Supply-shock phase tags */
.phase-tag.phase-baseline {
    --phase: var(--clr-phase-baseline);
}
.phase-tag.phase-decline {
    --phase: var(--clr-phase-decline);
}
.phase-tag.phase-disruption {
    --phase: var(--clr-phase-disruption);
}
.phase-tag.phase-exit {
    --phase: var(--clr-phase-exit);
}
.phase-tag.phase-full_recovery {
    --phase: var(--clr-phase-full_recovery);
}
.phase-tag.phase-partial_recovery {
    --phase: var(--clr-phase-partial_recovery);
}
.phase-tag.phase-depressed {
    --phase: var(--clr-phase-depressed);
}
.phase-tag.phase-sporadic {
    --phase: var(--clr-phase-sporadic);
}
/* Price-shock phase tags */
.phase-tag.phase-price_spike {
    --phase: var(--clr-phase-price_spike);
}
.phase-tag.phase-price_drop {
    --phase: var(--clr-phase-price_drop);
}
.phase-tag.phase-shock {
    --phase: var(--clr-phase-shock);
}
.phase-tag.phase-volatile_trade {
    --phase: var(--clr-phase-volatile_trade);
}
.phase-tag.phase-price_volatility {
    --phase: var(--clr-phase-price_volatility);
}
.phase-tag.phase-volume_volatility {
    --phase: var(--clr-phase-volume_volatility);
}
.phase-tag.phase-return_to_baseline {
    --phase: var(--clr-phase-return_to_baseline);
}
.phase-tag.phase-post_shock {
    --phase: var(--clr-phase-post_shock);
}
.phase-tag.phase-price_exit {
    --phase: var(--clr-phase-price_exit);
}

/* Map --------------------------------------------------- */

.map-legend {
    background: var(--clr-surface);
    padding: var(--space-2);
    border-radius: var(--radius);
    box-shadow: var(--shadow-md);
    font-size: var(--text-sm);
    line-height: var(--leading-normal);
}

.map-legend .legend-title {
    font-weight: 600;
    margin-bottom: var(--space-1);
}
.map-legend .legend-row {
    display: flex;
    align-items: center;
    gap: var(--space-1);
}
.map-legend .legend-label {
    color: var(--clr-text-muted);
}

.map-legend .legend-swatch {
    display: inline-block;
    width: var(--space-4);
    height: var(--space-3);
    border-radius: var(--micro-2);
    border: var(--micro-1) solid rgba(0, 0, 0, 0.15);
    flex-shrink: 0;
}

.map-tooltip {
    font-size: var(--text-base);
    padding: var(--space-1) var(--space-2);
    border-radius: var(--radius);
    box-shadow: 0 var(--micro-2) var(--space-1) rgba(0, 0, 0, 0.2);
}

/* -- Info tip (click-popover) -------------------------------
   A small "i" button next to a heading that opens a popover
   (rendered by tippy.js into document.body). Two parts:
     .info-tip       the trigger button
     .info-tip-icon  the round "i" badge inside it
   The popover content is styled via the .tippy-box theme below.
   ----------------------------------------------------------- */

.info-tip {
    background: none;
    border: none;
    padding: 0;
    cursor: help;
    flex-shrink: 0;
    line-height: var(--leading-tight);
}

.info-tip-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--em-xl);
    height: var(--em-xl);
    border-radius: var(--radius);
    border: var(--micro-2) solid var(--clr-text-muted);
    color: var(--clr-text-muted);
    font-size: var(--text-sm);
    font-weight: 700;
    font-style: italic;
    transition: all var(--transition);
}

.info-tip:hover .info-tip-icon,
.info-tip:focus-visible .info-tip-icon {
    border-color: var(--clr-accent);
    color: var(--clr-accent);
    background: var(--clr-accent-light);
}

/* Tippy.js popover theme used by <InfoTip>. Tippy renders the
   popover into document.body, so these rules are global by
   necessity (no scoping possible). Kept here so the visual
   matches the rest of the design system. */
.tippy-box[data-theme~="info-tip"] {
    background: var(--clr-surface);
    color: var(--clr-text);
    border: var(--micro-1) solid var(--clr-border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-md);
    font-size: var(--text-sm);
    line-height: var(--leading-relaxed);
    padding: var(--space-2) var(--space-3);
}

.tippy-box[data-theme~="info-tip"] .tippy-arrow {
    color: var(--clr-surface);
}

.tippy-box[data-theme~="info-tip"] .tippy-arrow::before {
    border-bottom-color: var(--clr-border);
    transform: translateY(calc(-1 * var(--micro-1)));
}

.tippy-box[data-theme~="info-tip"] a {
    color: var(--clr-accent);
    text-decoration: underline;
    text-underline-offset: var(--micro-2);
}

.tippy-box[data-theme~="info-tip"] a:hover {
    color: var(--clr-highlight);
}

/* ============================================================
   STATUS BANNERS, LOADING, ERRORS
   ============================================================ */

/* Unified note family ---------------------------------------
   A `.note` is any contextual aside — quieter than a heading,
   not part of the primary content flow. Includes error banners,
   info blocks (product breakdown), warnings (Rotterdam effect),
   and the per-tab explainers (stripe variant).

   Markup:  <aside class="note note-info">…</aside>
            <aside class="note note-stripe"><svg/>…</aside>
   ----------------------------------------------------------- */

.note {
    display: flex;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    margin-bottom: var(--space-4);
    border: var(--micro-1) solid transparent;
    border-radius: var(--radius);
    font-size: var(--text-sm);
    line-height: var(--leading-normal);
}

.note > svg {
    flex-shrink: 0;
    margin-top: var(--micro-1);
    align-self: flex-start;
}

.note p {
    margin: 0 0 var(--space-2);
}

.note p:last-child {
    margin-bottom: 0;
}

.note strong {
    color: var(--clr-accent);
    font-weight: 700;
}

.note a {
    color: inherit;
    text-decoration: underline;
}

/* Tone modifiers */
.note-info {
    background: var(--clr-accent-light);
    color: var(--clr-accent);
    border-color: color-mix(in srgb, var(--clr-accent) 35%, transparent);
}

.note-warn {
    background: var(--clr-highlight-light);
    color: var(--clr-text-muted);
    border-color: var(--clr-highlight);
}

.note-error {
    background: var(--clr-error-bg);
    color: var(--clr-error);
    border-color: var(--clr-error-border);
}

/* Report pages' dashboard CTA banner --------------------------
   Injected mid-report by the reports build (canlipe/reports.py
   insert_dashboard_cta) into the static /reports/*.html pages only;
   the app's Report tab strips it from the lifted article. Those
   pages run no JS, so dismissal is the checkbox hack: the × <label>
   toggles the hidden checkbox, and :checked hides the aside. (A
   :target anchor instead would scroll the reader back up to the
   anchor when dismissing the fixed popup from further down.)
   ----------------------------------------------------------- */

.report-dash-cta {
    justify-content: space-between;
    align-items: baseline;
}

.report-dash-cta p {
    margin: 0;
}

.report-dash-cta-dismiss {
    flex-shrink: 0;
    margin-left: var(--space-3);
    font-weight: 700;
    cursor: pointer;
}

.report-dash-cta-toggle {
    display: none;
}

.report-dash-cta-toggle:checked + .report-dash-cta {
    display: none;
}

/* Scroll-triggered popup upgrade (pure CSS scroll-driven animations,
   no JS): the third h2 — the second body section's heading — carries
   a named view-timeline scoped to the article; when it scrolls into
   view, the banner leaves the prose flow and slides in as a fixed
   bottom card (fill mode keeps it shown further down, hides it back
   above). Unsupported browsers keep the plain inline note; reports
   too short for a third h2 (marked .report-dash-cta-static by the
   build) never upgrade. visibility participates in the keyframes so
   the not-yet-revealed popup doesn't swallow clicks. */
@supports (animation-timeline: view()) and (timeline-scope: --report-dash-cta) {
    #report-content {
        timeline-scope: --report-dash-cta;
    }

    #report-content > h2:nth-of-type(3) {
        view-timeline: --report-dash-cta block;
    }

    .report-dash-cta:not(.report-dash-cta-static) {
        position: fixed;
        z-index: 50;
        inset-inline: var(--space-4);
        bottom: var(--space-4);
        max-width: 46rem;
        margin: 0 auto;
        box-shadow: var(--shadow-md);
        animation: report-dash-cta-pop linear both;
        animation-timeline: --report-dash-cta;
        animation-range: entry 0% entry 100%;
    }

    @keyframes report-dash-cta-pop {
        from {
            visibility: hidden;
            opacity: 0;
            transform: translateY(var(--space-4));
        }
        to {
            visibility: visible;
            opacity: 1;
            transform: none;
        }
    }

    @media (prefers-reduced-motion: reduce) {
        @keyframes report-dash-cta-pop {
            from,
            to {
                visibility: visible;
                opacity: 1;
                transform: none;
            }
        }
    }
}

.error-log {
    font-family: monospace;
    font-size: var(--text-sm);
    white-space: pre-wrap;
    background: rgba(0, 0, 0, 0.03);
    border: var(--micro-1) solid var(--clr-error-border);
    border-radius: var(--radius);
    padding: var(--space-2);
    margin-bottom: var(--space-2);
    max-height: 7.5rem;
    overflow-y: auto;
    color: var(--clr-text-muted);
}

.error-detail {
    font-weight: 600;
    color: var(--clr-error);
}

.loading {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--space-4);
    background: rgba(241, 243, 247, 0.88);
    z-index: 50;
    border-radius: var(--radius);
}

.loading p {
    font-size: var(--text-base);
    color: var(--clr-text-muted);
    text-align: center;
    max-width: 20rem;
}

.spinner {
    width: var(--space-9);
    height: var(--space-9);
    border: var(--micro-3) solid var(--clr-border);
    border-top-color: var(--clr-accent);
    border-radius: 50%;
    animation: spin 0.7s linear infinite;
}

/* ============================================================
   SHOCK TABS — shared layout, bottle grid & tuning panel.
   Used by both PriceShocks and SupplyShocks.
   ============================================================ */

.shock-layout {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-4);
    align-items: start;
}

.shock-left {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    min-width: 0;
}

.shock-right {
    position: sticky;
    top: var(--space-4);
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

/* Bottle grid — a CSS-grid pseudo-table with SVG bottles per row. */

.bottle-grid-wrap {
    overflow-x: auto;
}

.bt-row {
    display: grid;
    grid-template-columns:
        var(--col-entity) 1fr var(--col-base) var(--col-stat)
        var(--col-stat) var(--col-stat);
    align-items: center;
    min-width: 0;
}

.bt-cell {
    min-width: 0;
    overflow: hidden;
}

.bt-head {
    position: sticky;
    top: 0;
    z-index: 2;
    background: var(--clr-surface);
    border-bottom: var(--micro-2) solid var(--clr-border);
    margin-bottom: var(--space-2);
}

.bt-head .bt-cell {
    padding: var(--space-1) var(--space-2);
    white-space: nowrap;
    font-weight: 600;
    font-size: var(--text-sm);
    text-transform: uppercase;
    letter-spacing: var(--tracking-wide);
    color: var(--clr-text-muted);
}

/* Preserve case for symbols (e.g. σ) inside uppercase headers */
.bt-head .no-transform {
    text-transform: none;
}

/* Negative shift value in shock grids */
.bt-shift-negative {
    color: var(--clr-phase-price_drop);
}

.bt-head .bt-stat {
    text-align: right;
}

.bt-head .sortable {
    cursor: pointer;
    user-select: none;
}

.bt-head .sortable:hover {
    color: var(--clr-text);
}

.bt-data {
    cursor: pointer;
    border-bottom: var(--micro-1) solid var(--clr-border);
    transition: background var(--transition);
}

.bt-data:hover {
    background: var(--clr-surface-alt);
}

.bt-data.selected {
    background: var(--clr-accent-light);
}

.bt-entity {
    padding: 0 var(--space-2);
    font-size: var(--text-sm);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    color: var(--clr-text);
}

.bt-bottle {
    padding: 0;
    line-height: 0;
    overflow: visible;
}

.bottle-row-svg {
    display: block;
    overflow: visible;
}

.bt-stat {
    text-align: right;
    padding: 0 var(--space-2);
    font-variant-numeric: tabular-nums;
    font-size: var(--text-sm);
    color: var(--clr-text-muted);
}

.bt-sigma {
    font-weight: 600;
    color: var(--clr-text);
}

.bt-foot {
    border: none;
}

.bt-foot .bt-bottle {
    line-height: 0;
}

.bottle-axis-svg {
    display: block;
}

.bottle-pinch-label {
    font-size: var(--text-sm);
    font-family: inherit;
    fill: var(--clr-text-muted);
    font-weight: 600;
    pointer-events: none;
}

.bottle-overlay-label {
    font-size: var(--text-sm);
    font-family: inherit;
    fill: var(--clr-text);
    font-weight: 600;
    dominant-baseline: middle;
    text-anchor: middle;
    paint-order: stroke fill;
    stroke: var(--clr-surface);
    stroke-width: var(--micro-4);
    stroke-linejoin: round;
    pointer-events: none;
}

.bottle-axis-label {
    font-size: var(--text-sm);
    font-family: inherit;
    fill: var(--clr-text-muted);
    letter-spacing: 0.02em;
}

/* Detection-parameters card */

.tuning-panel {
    margin: var(--space-3) 0 var(--space-4);
    overflow: hidden;
    width: 100%;
    max-width: 100%;
}

.tuning-header {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    width: 100%;
    padding: var(--space-3) var(--space-4);
    color: var(--clr-text-muted);
    font-size: var(--text-sm);
    font-weight: 600;
    font-family: inherit;
    background: none;
    border: none;
    cursor: pointer;
    text-align: left;
}

.tuning-header:hover {
    color: var(--clr-accent);
}

.tuning-body {
    display: grid;
    grid-template-columns: repeat(
        auto-fill,
        minmax(var(--tuning-slider-min), 1fr)
    );
    gap: var(--space-1) var(--space-4);
    padding: var(--space-2) var(--space-4) var(--space-3);
}

.tuning-slider {
    display: grid;
    grid-row: span 2;
    grid-template-rows: subgrid;
    min-width: 0;
    padding-bottom: var(--space-1);
}

.tuning-slider:has(.tuning-desc) {
    grid-row: span 3;
}

.tuning-label {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: var(--space-2);
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--clr-text);
}

.tuning-label strong {
    color: var(--clr-accent);
    font-variant-numeric: tabular-nums;
}

.tuning-slider input[type="range"] {
    width: 100%;
    accent-color: var(--clr-accent);
    align-self: start;
}

.tuning-desc-arrow {
    display: inline-block;
    font-size: var(--text-sm);
    transition: transform var(--transition);
    line-height: var(--leading-tight);
}

.tuning-desc-arrow.open {
    transform: rotate(90deg);
}

.tuning-desc {
    font-size: var(--text-sm);
    color: var(--clr-text-muted);
    line-height: var(--leading-normal);
    margin-top: var(--space-1);
}

/* ============================================================
   MATH / FORMULA DISPLAY
   Generic fraction-style equation block, shared across tabs
   that display indicator formulas (NIR, Trade Intensity, etc.)

   Markup:
     <div class="math-block">
       <div class="math-eq">
         <span>NIR</span>
         <span class="math-sign">=</span>
         <span class="math-frac">
           <span class="math-num">Imports − Exports</span>
           <span class="math-den">Apparent consumption</span>
         </span>
       </div>
       <p class="math-where">where</p>
       <div class="math-eq">
         <span>Apparent consumption = Production + Imports − Exports</span>
       </div>
     </div>
     <p class="math-note">Explanatory note…</p>
   ============================================================ */

.math-block {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-3) var(--space-4);
    background: var(--clr-surface-alt);
    border: var(--micro-1) solid var(--clr-border);
    border-radius: var(--radius);
    color: var(--clr-text);
}

.math-eq {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex-wrap: wrap;
    justify-content: center;
    font-size: var(--text-sm);
}

.math-sign {
    color: var(--clr-text-muted);
    padding: 0 var(--micro-2);
}

.math-frac {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    gap: var(--micro-2);
    line-height: var(--leading-tight);
}

.math-num {
    border-bottom: 1px solid currentColor;
    padding: 0 var(--space-2) var(--micro-2);
    text-align: center;
}

.math-den {
    padding: var(--micro-2) var(--space-2) 0;
    text-align: center;
}

.math-where {
    font-style: italic;
    color: var(--clr-text-muted);
    margin: 0;
    font-size: var(--text-sm);
}

/* ============================================================
   CONTENT PAGES (FAQ, reports, blog, 404, oauth, eurostat-check)
   → static/css/content.css, loaded by those pages after this file
   and on demand by the app (Report tab). Kept here: .faq-lang,
   which is site-header chrome used by the landing page fallback.
   ============================================================ */

/* ── FAQ language switcher (landing page header) ────────────── */
.faq-lang {
    display: flex;
    align-items: center;
    gap: var(--micro-1);
}

.faq-lang-opt {
    font-size: var(--text-sm);
    font-weight: 600;
    padding: var(--micro-4) var(--space-2);
    border-radius: var(--radius);
    color: var(--clr-text-muted);
    text-decoration: none;
    white-space: nowrap;
}

.faq-lang-opt:hover {
    background: var(--clr-accent-light);
    color: var(--clr-accent);
}

.faq-lang-opt.active {
    background: var(--clr-accent);
    color: var(--clr-text-inverse);
}

/* ============================================================
   UTILITIES
   ============================================================ */

.sr-only {
    position: absolute;
    width: var(--micro-1);
    height: var(--micro-1);
    padding: 0;
    margin: calc(-1 * var(--micro-1));
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* ============================================================
   ANIMATIONS
   ============================================================ */

@keyframes spin {
    to {
        transform: rotate(360deg);
    }
}

/* Draws attention to the sidebar's Apply button after a code is added
   from the welcome page (search or browser) without auto-submitting. */
@keyframes apply-bounce {
    0%,
    100% {
        transform: translateY(0);
    }
    25% {
        transform: translateY(-5px);
    }
    50% {
        transform: translateY(0);
    }
    75% {
        transform: translateY(-3px);
    }
}

.btn-block.apply-bounce {
    animation: apply-bounce 0.7s ease;
}

@media (prefers-reduced-motion: reduce) {
    .btn-block.apply-bounce {
        animation: none;
    }
}

/* ============================================================
   RESPONSIVE
   ============================================================ */

@media (max-width: 768px) {
    :root {
        /* Mobile column widths */
        --col-entity: var(--space-24); /* 6rem = 96px */
        --col-base: var(--space-16); /* 4rem = 64px */
        --col-stat: var(--space-12); /* 3rem = 48px */
    }

    .site-header {
        padding: 0 var(--space-3);
        gap: var(--space-2);
    }

    .has-dashboard .header-logo {
        width: var(--em-xl);
        height: var(--em-xl);
    }

    .hdr-label,
    .hdr-chevron {
        display: none;
    }

    .site-header:has(.faq-lang) .header-home {
        overflow: hidden;
        min-width: 0;
    }
    .site-header:has(.faq-lang) h1,
    .site-header:has(.faq-lang) .site-title {
        overflow: hidden;
        white-space: nowrap;
        mask-image: linear-gradient(to right, #000 70%, transparent);
        -webkit-mask-image: linear-gradient(to right, #000 70%, transparent);
    }
    .hdr-drop-btn {
        padding: var(--space-2);
    }
    .hdr-drop-opt {
        padding: var(--micro-2) var(--space-1);
    }

    .header-help {
        padding: var(--space-1);
        flex-shrink: 0;
    }

    .tabs {
        margin-bottom: var(--space-2);
    }
    .tab {
        padding: var(--space-2) var(--space-3);
    }
    .tuning-panel {
        margin: var(--space-1) 0 var(--space-3);
    }
    .tuning-header {
        padding: var(--space-2) var(--space-3);
    }
    .tuning-body {
        grid-template-columns: repeat(
            auto-fill,
            minmax(var(--tuning-slider-min), 1fr)
        );
        gap: var(--space-1) var(--space-3);
        padding: var(--space-2) var(--space-3) var(--space-3);
    }

    /* Touch-friendly chart toolbar buttons */
    .chart-card > header {
        flex-wrap: wrap;
    }
    .chart-actions .btn {
        min-height: var(--space-9);
        min-width: var(--space-9);
        padding: var(--space-1) var(--space-2);
        font-size: var(--text-sm);
        white-space: nowrap;
    }
    .chart-actions {
        gap: var(--space-1);
        flex-wrap: wrap;
        justify-content: flex-end;
    }

    .main {
        padding: var(--space-3) var(--space-2);
    }

    /* Feature tour collapses to a single column: label above chips */
    .tour-row {
        grid-template-columns: 1fr;
        gap: var(--space-1);
        padding: var(--space-2) 0;
    }

    .chart-grid {
        gap: var(--space-3);
    }
    .chart-card > header {
        padding: var(--space-2) var(--space-3);
    }
    .chart-card canvas {
        padding: var(--space-2) var(--space-3);
    }
    .card {
        border-radius: var(--micro-2);
    }
    .map-container {
        height: 18.75rem;
    }
}

@media (max-width: 1024px) {
    .grid-2x2 {
        grid-template-columns: 1fr;
    }

    /* Single-column grid: no rows left to span, the card just stacks. */
    .chart-card--tall {
        grid-row: auto;
    }

    .toggle {
        display: flex;
    }

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

    .sidebar {
        position: fixed;
        top: var(--header-height);
        left: 0;
        width: 18.75rem;
        height: calc(100dvh - var(--header-height));
        z-index: 90;
        transform: translateX(-100%);
        transition: transform 200ms ease;
        box-shadow: var(--shadow-md);
    }

    .sidebar.open {
        transform: translateX(0);
    }
    .sidebar.open .sidebar-close {
        display: block;
    }
    .sidebar.open::after {
        content: "";
        position: fixed;
        top: 0;
        left: 18.75rem;
        width: 100vw;
        height: 100vh;
        width: 100dvw;
        height: 100dvh;
        background: rgba(0, 0, 0, 0.3);
    }

    .main {
        padding: var(--space-4);
    }
    .map-container {
        height: 21.25rem;
    }
    .shock-layout {
        grid-template-columns: 1fr;
    }
    .shock-right {
        position: static;
    }
}

@media (max-width: 480px) {
    .toggle-label {
        display: none;
    }

    .main {
        padding: var(--space-2) var(--micro-4);
    }
    .tabs {
        margin-bottom: var(--space-1);
    }
    .tab {
        padding: var(--space-1) var(--space-2);
        font-size: var(--text-sm);
    }
    .nav-back a {
        font-size: var(--text-sm);
    }
    .tuning-panel {
        margin: 0 0 var(--space-2);
    }
    .tuning-header {
        padding: var(--space-1) var(--space-2);
    }
    .chart-grid {
        gap: var(--space-2);
    }
    .chart-card > header {
        padding: var(--space-2);
    }
    .chart-card canvas {
        padding: var(--space-1) var(--space-2);
    }
    .card {
        border-radius: 0;
        border-left: none;
        border-right: none;
    }
    .chart-toolbar {
        padding: var(--space-1) var(--space-2);
        gap: var(--space-2);
        font-size: var(--text-sm);
        flex-wrap: nowrap;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
        max-width: 100%;
    }
    .chart-toolbar::-webkit-scrollbar {
        display: none;
    }
    .chart-toolbar .toolbar-sep {
        display: none;
    }
    .vol-legend-bar {
        width: var(--space-20);
    }
    .data-table th,
    .data-table td {
        padding: var(--space-1) var(--space-2);
    }
    .welcome {
        padding: var(--space-4) var(--space-2);
    }
}

@media (min-width: 1200px) {
    .map-container {
        height: 27.5rem;
    }
}

@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        transition-duration: 0.01ms !important;
    }

    .spinner {
        animation: none;
        border-top-color: var(--clr-accent);
    }
    .chart-card:hover {
        transform: none;
    }
}

/* ============================================================
   BROWSER-ONLY RULES (moved out of content.css)
   weasyprint never parses this file, so browser/engine-specific
   declarations live here rather than tripping the PDF render:
   print-color-adjust is unknown to it, and it rejects the
   webkit-pseudo-element selector outright.
   ============================================================ */

/* Keep the light background accents when printing from the BROWSER —
   they are stripped by default (the PDF render keeps them either way). */
@media print {
    article blockquote,
    article tbody tr:nth-child(even),
    article details[open] summary {
        print-color-adjust: exact;
    }
}

article summary::-webkit-details-marker {
    display: none;
}

/* Screen-only declarations for base.css / content.css rules: weasyprint
   knows neither position: sticky nor box-shadow, so scoped under
   @media screen it skips them silently — and print never wanted them
   (content.css's @media print used to reset them explicitly). */
@media screen {
    .site-header {
        position: sticky;
        top: 0;
        box-shadow: var(--shadow-sm);
    }
    article {
        box-shadow: var(--shadow-sm);
    }
}
