/* ---------------------------------------------------------------------------
   Market — hand-written CSS, no build step.

   Colour is entirely token-driven. The light palette is the only place a
   colour is *defined*; the dark palette only reassigns the same tokens, in
   three places:

     @media (prefers-color-scheme: dark)  the visitor's OS setting
     :root[data-theme="dark"]             an explicit choice, toggle -> dark
     :root[data-theme="light"]            an explicit choice, wins over the OS

   Because of that last one the media query is guarded, so a visitor on a dark
   OS who picks light actually gets light.
--------------------------------------------------------------------------- */

:root {
    color-scheme: light;

    /* Surfaces, from furthest back to nearest front. */
    --bg: #f7f8fa;
    --bg-accent: #eef1f7;
    --surface: #ffffff;
    --surface-2: #f4f6f9;
    --surface-3: #eaeef4;

    /* Lines. --border is structural, --border-strong for emphasis. */
    --border: #e5e9f0;
    --border-strong: #d3dae5;

    /* Text, from loudest to quietest. */
    --text: #0d1421;
    --text-secondary: #445067;
    --text-muted: #6b7688;

    --accent: #2b55e8;
    --accent-hover: #2246c9;
    --accent-soft: rgba(43, 85, 232, 0.09);
    --accent-contrast: #ffffff;
    --accent-ring: rgba(43, 85, 232, 0.32);

    --up: #0a7b48;
    --up-soft: rgba(10, 123, 72, 0.1);
    --down: #c22f2f;
    --down-soft: rgba(194, 47, 47, 0.09);

    /* Neither up nor down: the "unchanged" tally on the statistics board. Amber
       rather than grey, so a zero reads as a real count and not a disabled card. */
    --flat: #b06a10;
    --flat-soft: rgba(176, 106, 16, 0.1);

    /* Candle chart. Deliberately not --up/--down: on a chart of several hundred
       bars, red-on-green is the worst possible pairing for the ~8% of men with
       a red-green deficiency, who would see a wall of identical bars. Blue
       against magenta separates on brightness as well as hue, so the up/down
       split survives both colour blindness and a greyscale print. It is also
       the convention O'Neil charts use, which is what this chart is modelled on. */
    --candle-up: #2f6fe4;
    --candle-down: #e0439a;
    --chart-ma-fast: #e2574c;
    --chart-ma-slow: #d9a441;
    --chart-gridline: rgba(120, 134, 158, 0.18);
    --chart-index: #8792a6;
    --chart-rs: #7b3fbf;

    --shadow-sm: 0 1px 2px rgba(13, 20, 33, 0.04);
    --shadow: 0 1px 2px rgba(13, 20, 33, 0.04), 0 4px 16px rgba(13, 20, 33, 0.045);
    --shadow-lg: 0 2px 4px rgba(13, 20, 33, 0.05), 0 12px 32px rgba(13, 20, 33, 0.09);
    --header-bg: rgba(255, 255, 255, 0.82);

    --radius: 14px;
    --radius-sm: 10px;
    --radius-xs: 7px;
    --radius-pill: 999px;

    /* One spacing rhythm, used everywhere instead of ad hoc rem values. */
    --space-1: 0.25rem;
    --space-2: 0.5rem;
    --space-3: 0.75rem;
    --space-4: 1rem;
    --space-5: 1.5rem;
    --space-6: 2rem;
    --space-7: 3rem;

    --font: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

    --ease: cubic-bezier(0.32, 0.72, 0, 1);
}

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        color-scheme: dark;

        --bg: #0a0d13;
        --bg-accent: #0f141d;
        --surface: #141a24;
        --surface-2: #1b2230;
        --surface-3: #222b3b;

        --candle-up: #5a92f5;
        --candle-down: #f06ab4;
        --chart-ma-fast: #f2776b;
        --chart-ma-slow: #e5b95c;
        --chart-gridline: rgba(150, 165, 190, 0.16);
        --chart-index: #9aa6bb;
        --chart-rs: #b083ea;

        --border: #232c3a;
        --border-strong: #334054;

        --text: #eaeff7;
        --text-secondary: #b3bfd0;
        --text-muted: #8592a6;

        --accent: #7592ff;
        --accent-hover: #8ba5ff;
        --accent-soft: rgba(117, 146, 255, 0.14);
        --accent-contrast: #0a0d13;
        --accent-ring: rgba(117, 146, 255, 0.4);

        --up: #34d399;
        --up-soft: rgba(52, 211, 153, 0.14);
        --down: #fb7185;
        --down-soft: rgba(251, 113, 133, 0.14);
        --flat: #e0a458;
        --flat-soft: rgba(224, 164, 88, 0.14);

        --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
        --shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 4px 16px rgba(0, 0, 0, 0.3);
        --shadow-lg: 0 2px 4px rgba(0, 0, 0, 0.45), 0 14px 36px rgba(0, 0, 0, 0.45);
        --header-bg: rgba(20, 26, 36, 0.82);
    }
}

:root[data-theme="dark"] {
    color-scheme: dark;

    --bg: #0a0d13;
    --bg-accent: #0f141d;
    --surface: #141a24;
    --surface-2: #1b2230;
    --surface-3: #222b3b;

    --candle-up: #5a92f5;
    --candle-down: #f06ab4;
    --chart-ma-fast: #f2776b;
    --chart-ma-slow: #e5b95c;
    --chart-gridline: rgba(150, 165, 190, 0.16);
    --chart-index: #9aa6bb;
    --chart-rs: #b083ea;

    --border: #232c3a;
    --border-strong: #334054;

    --text: #eaeff7;
    --text-secondary: #b3bfd0;
    --text-muted: #8592a6;

    --accent: #7592ff;
    --accent-hover: #8ba5ff;
    --accent-soft: rgba(117, 146, 255, 0.14);
    --accent-contrast: #0a0d13;
    --accent-ring: rgba(117, 146, 255, 0.4);

    --up: #34d399;
    --up-soft: rgba(52, 211, 153, 0.14);
    --down: #fb7185;
    --down-soft: rgba(251, 113, 133, 0.14);
    --flat: #e0a458;
    --flat-soft: rgba(224, 164, 88, 0.14);

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
    --shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 4px 16px rgba(0, 0, 0, 0.3);
    --shadow-lg: 0 2px 4px rgba(0, 0, 0, 0.45), 0 14px 36px rgba(0, 0, 0, 0.45);
    --header-bg: rgba(20, 26, 36, 0.82);
}

/* Base --------------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
    margin: 0;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    background: var(--bg);
    color: var(--text);
    font-family: var(--font);
    font-size: 15px;
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

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

:where(a, button, input, select, textarea):focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
    border-radius: var(--radius-xs);
}

h1, h2, h3 { margin: 0; line-height: 1.2; font-weight: 640; letter-spacing: -0.018em; }
h1 { font-size: clamp(1.5rem, 1.25rem + 1vw, 1.85rem); }
h2 { font-size: 1.0rem; letter-spacing: -0.01em; }
h3 {
    font-size: 0.72rem; font-weight: 620; text-transform: uppercase;
    letter-spacing: 0.07em; color: var(--text-muted);
}

p { margin: 0.35rem 0; }

code {
    font-family: var(--mono); font-size: 0.84em;
    background: var(--surface-2); border: 1px solid var(--border);
    padding: 0.1em 0.4em; border-radius: var(--radius-xs);
}

svg { display: block; }

.wrap { width: min(1200px, 100% - 2.5rem); margin-inline: auto; }
.muted { color: var(--text-muted); }
.small { font-size: 0.85rem; }

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

.skip-link {
    position: absolute; left: var(--space-4); top: -3rem; z-index: 100;
    background: var(--accent); color: var(--accent-contrast);
    padding: var(--space-2) var(--space-4); border-radius: var(--radius-sm);
    font-size: 0.88rem; font-weight: 600; transition: top 0.15s var(--ease);
}
.skip-link:focus { top: var(--space-3); text-decoration: none; }

/* Header ------------------------------------------------------------------- */

.site-header {
    position: sticky;
    top: 0;
    z-index: 20;
    background: var(--header-bg);
    border-bottom: 1px solid var(--border);
    backdrop-filter: saturate(180%) blur(14px);
    -webkit-backdrop-filter: saturate(180%) blur(14px);
}

@supports not (backdrop-filter: blur(1px)) {
    .site-header { background: var(--surface); }
}

/* Currency ticker ----------------------------------------------------------

   A CSS-only marquee. The track holds two identical copies of the list and
   slides from 0 to -50%: at the end of the pass the second copy is exactly
   where the first started, so it loops with no visible jump. One copy would
   snap back across the whole viewport every time round.

   Deliberately not sticky. The header above it is, and pinning a second band
   under a sticky element means hard-coding that element's height — which
   changes with the viewport, so it would be wrong at most widths.
-------------------------------------------------------------------------- */

.ticker {
    position: relative;
    overflow: hidden;
    background: var(--bg-accent);
    border-bottom: 1px solid var(--border);
    font-size: 0.84rem;
}

.ticker-track {
    display: flex;
    width: max-content;
    animation: ticker-scroll var(--ticker-duration, 45s) linear infinite;
}

/* Pause on hover so a rate can be read, and on focus so it can be reached
   with a keyboard rather than chased. */
.ticker:hover .ticker-track,
.ticker:focus-within .ticker-track { animation-play-state: paused; }

@keyframes ticker-scroll {
    from { transform: translateX(0); }
    to { transform: translateX(-50%); }
}

.ticker-list {
    display: flex; align-items: center;
    list-style: none; margin: 0; padding: 0;
}

.ticker-item {
    display: flex; align-items: baseline; gap: 0.4rem;
    padding: 0.5rem var(--space-4);
    white-space: nowrap;
    border-right: 1px solid var(--border);
}

.ticker-pair { font-weight: 640; color: var(--text); }
.ticker-rate { color: var(--text-secondary); font-variant-numeric: tabular-nums; }

.ticker-change {
    display: inline-flex; align-items: center; gap: 0.25rem;
    font-weight: 560; font-variant-numeric: tabular-nums;
}
.ticker-change--up { color: var(--up); }
.ticker-change--down { color: var(--down); }
.ticker-caret { width: 9px; height: 8px; flex: none; fill: currentColor; }

/* Both edges fade rather than cutting a pair in half at the boundary. */
.ticker::before,
.ticker::after {
    content: ""; position: absolute; top: 0; bottom: 0; width: 48px;
    pointer-events: none; z-index: 1;
}
.ticker::before { left: 0; background: linear-gradient(90deg, var(--bg-accent), transparent); }
.ticker::after { right: 0; background: linear-gradient(270deg, var(--bg-accent), transparent); }

/*
 | Motion in the corner of the eye is exactly what this setting is for. With it
 | on, the strip becomes an ordinary horizontal scroller — and the duplicate
 | copy is removed, since without the animation it is just every rate listed
 | twice.
 */
@media (prefers-reduced-motion: reduce) {
    .ticker { overflow-x: auto; }
    .ticker-track { animation: none; }
    .ticker-list + .ticker-list { display: none; }
    .ticker::before, .ticker::after { display: none; }
}

@media (max-width: 560px) {
    .ticker { font-size: 0.8rem; }
    .ticker-item { padding: 0.45rem var(--space-3); gap: 0.3rem; }
    .ticker::before, .ticker::after { width: 24px; }
}

.header-inner {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    min-height: 60px;
    padding-block: var(--space-3);
    flex-wrap: wrap;
}

.brand {
    display: inline-flex; align-items: center;
    color: var(--text); flex: 0 0 auto;
    /* The logo is the only child; no gap and no type metrics to reserve. */
}
.brand:hover { color: var(--text); text-decoration: none; }

/* Brand logo ---------------------------------------------------------------

   Two files, swapped by theme. Same three states as the colour palette, and
   guarded the same way — the media query has to yield to an explicit light
   choice, or a visitor on a dark OS who picks light gets the dark logo on a
   white header.

   Height drives the size and width is auto: the lockup is 1.765:1 and hard
   coding both would squash it the moment the artwork is re-exported.
-------------------------------------------------------------------------- */

.brand-logo {
    height: 38px; width: auto; max-width: 100%;
    display: block;
}

/* Light is the default state, so the dark file starts hidden. */
.brand-logo--dark { display: none; }

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .brand-logo--light { display: none; }
    :root:not([data-theme="light"]) .brand-logo--dark { display: block; }
}

:root[data-theme="dark"] .brand-logo--light { display: none; }
:root[data-theme="dark"] .brand-logo--dark { display: block; }

/* The wordmark is inside the artwork now, so the flex gap has nothing left to
   separate — and a phone header needs the width back. */
@media (max-width: 560px) {
    .brand-logo { height: 32px; }
}

/* Search ------------------------------------------------------------------- */

.search { display: flex; align-items: center; gap: var(--space-2); flex: 1 1 240px; min-width: 190px; }

.search-field { position: relative; display: flex; flex: 1; }

.search-icon {
    position: absolute; left: 0.65rem; top: 50%; transform: translateY(-50%);
    width: 16px; height: 16px; pointer-events: none;
    fill: none; stroke: var(--text-muted); stroke-width: 1.7; stroke-linecap: round;
}

.search input {
    flex: 1; width: 100%;
    padding: 0.5rem 0.75rem 0.5rem 2.1rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-pill);
    background: var(--surface-2);
    color: var(--text);
    font: inherit; font-size: 0.9rem;
    transition: border-color 0.15s var(--ease), box-shadow 0.15s var(--ease), background 0.15s var(--ease);
}
.search input::placeholder { color: var(--text-muted); }
.search input:hover { border-color: var(--border-strong); }
.search input:focus {
    outline: none;
    background: var(--surface);
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-ring);
}
.search input::-webkit-search-cancel-button { cursor: pointer; }

/* Buttons ------------------------------------------------------------------ */

.button {
    display: inline-flex; align-items: center; justify-content: center;
    border: 1px solid transparent;
    background: var(--accent);
    color: var(--accent-contrast);
    border-radius: var(--radius-sm);
    padding: 0.5rem 0.95rem;
    font: inherit; font-size: 0.9rem; font-weight: 600;
    line-height: 1.3;
    cursor: pointer; white-space: nowrap;
    transition: background 0.15s var(--ease), box-shadow 0.15s var(--ease), transform 0.08s var(--ease);
}
.button:hover { background: var(--accent-hover); color: var(--accent-contrast); text-decoration: none; }
.button:active { transform: translateY(1px); }

.button--small { padding: 0.42rem 0.8rem; font-size: 0.85rem; }

.button--ghost {
    background: transparent; border-color: var(--border-strong); color: var(--text);
}
.button--ghost:hover { background: var(--surface-2); color: var(--text); }

.icon-button {
    display: inline-flex; align-items: center; justify-content: center;
    width: 34px; height: 34px; padding: 0;
    border: 1px solid var(--border); border-radius: var(--radius-sm);
    background: var(--surface-2); color: var(--text-secondary);
    cursor: pointer;
    transition: background 0.15s var(--ease), color 0.15s var(--ease), border-color 0.15s var(--ease);
}
.icon-button:hover { background: var(--surface-3); color: var(--text); border-color: var(--border-strong); }
.icon-button svg {
    width: 17px; height: 17px;
    fill: none; stroke: currentColor; stroke-width: 1.7;
    stroke-linecap: round; stroke-linejoin: round;
}

/* One icon at a time: sun while light, moon while dark. */
.icon-moon { display: none; }
:root[data-theme="dark"] .icon-sun { display: none; }
:root[data-theme="dark"] .icon-moon { display: block; }
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .icon-sun { display: none; }
    :root:not([data-theme="light"]) .icon-moon { display: block; }
    :root[data-theme="light"] .icon-sun { display: block; }
    :root[data-theme="light"] .icon-moon { display: none; }
}

/* Nav ---------------------------------------------------------------------- */

.nav { display: flex; align-items: center; gap: var(--space-3); font-size: 0.9rem; flex: 0 0 auto; }

.nav-link {
    position: relative; color: var(--text-secondary); font-weight: 550;
    padding-block: 0.15rem;
    transition: color 0.15s var(--ease);
}
.nav-link:hover { color: var(--text); text-decoration: none; }
.nav-link.active { color: var(--text); font-weight: 620; }
.nav-link.active::after {
    content: ""; position: absolute; left: 0; right: 0; bottom: -0.35rem;
    height: 2px; border-radius: 2px; background: var(--accent);
}

.inline-form { display: inline-flex; margin: 0; }

.link-button {
    background: none; border: 0; padding: 0; font: inherit; font-size: 0.9rem;
    font-weight: 550; color: var(--text-secondary); cursor: pointer;
    transition: color 0.15s var(--ease);
}
.link-button:hover { color: var(--text); }
.link-button--danger:hover { color: var(--down); }

/* Layout ------------------------------------------------------------------- */

main { flex: 1; padding: var(--space-6) 0 var(--space-7); }

.page-head {
    display: flex; justify-content: space-between; align-items: flex-end;
    gap: var(--space-4); flex-wrap: wrap; margin-bottom: var(--space-5);
}

.eyebrow {
    font-size: 0.72rem; font-weight: 620; text-transform: uppercase;
    letter-spacing: 0.09em; color: var(--text-muted); margin: 0 0 0.3rem;
}

.status {
    display: inline-flex; align-items: center; gap: 0.5rem;
    font-size: 0.85rem;
    padding: 0.4rem 0.8rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-pill);
    box-shadow: var(--shadow-sm);
}
.dot { width: 7px; height: 7px; border-radius: 50%; flex: 0 0 auto; }
.dot--open { background: var(--up); box-shadow: 0 0 0 3px var(--up-soft); }
.dot--closed { background: var(--text-muted); box-shadow: 0 0 0 3px var(--surface-3); }

.panel {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: var(--space-4) var(--space-5) var(--space-5);
    margin-bottom: var(--space-5);
}

.panel-head {
    display: flex; align-items: center; justify-content: space-between;
    gap: var(--space-3); flex-wrap: wrap; margin-bottom: var(--space-3);
}
.panel-head .more { font-size: 0.85rem; font-weight: 550; }
.panel-head .muted { font-size: 0.82rem; }

.two-col { display: grid; gap: var(--space-5); grid-template-columns: 1fr 1fr; align-items: start; }
.two-col--wide-left { grid-template-columns: 1.65fr 1fr; }
.two-col > .panel { margin-bottom: 0; }

@media (max-width: 900px) {
    .two-col, .two-col--wide-left { grid-template-columns: 1fr; }
}

/* Index cards -------------------------------------------------------------- */

.cards {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(196px, 1fr));
    gap: var(--space-3);
    /* The "All indices" link below owns the gap that follows. */
    margin-bottom: 0;
}

.card {
    position: relative; overflow: hidden;
    display: flex; flex-direction: column;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: var(--space-4) var(--space-4) 0.6rem;
    box-shadow: var(--shadow-sm);
    color: var(--text);
    transition: box-shadow 0.18s var(--ease), border-color 0.18s var(--ease), transform 0.18s var(--ease);
}
.card:hover {
    text-decoration: none; color: var(--text);
    transform: translateY(-2px);
    border-color: var(--border-strong);
    box-shadow: var(--shadow-lg);
}

/* A hairline of trend colour along the top edge, revealed on hover. */
.card::before {
    content: ""; position: absolute; inset: 0 0 auto; height: 2px;
    background: var(--border); opacity: 0;
    transition: opacity 0.18s var(--ease);
}
.card--up::before { background: var(--up); }
.card--down::before { background: var(--down); }
.card:hover::before { opacity: 1; }

.card h2 {
    font-size: 0.72rem; font-weight: 620; text-transform: uppercase;
    letter-spacing: 0.07em; color: var(--text-muted);
}
.card-price {
    font-size: 1.5rem; font-weight: 660; margin: 0.35rem 0 0.3rem;
    font-variant-numeric: tabular-nums; letter-spacing: -0.025em;
}
.card-spark { margin-top: auto; padding-top: 0.55rem; }

/* Tables ------------------------------------------------------------------- */

.quote-table { width: 100%; border-collapse: collapse; font-size: 0.92rem; }

.quote-table th, .quote-table td { padding: 0.6rem 0.5rem; text-align: left; }
.quote-table th:first-child, .quote-table td:first-child { padding-left: 0; }
.quote-table th:last-child, .quote-table td:last-child { padding-right: 0; }

.quote-table thead th {
    font-size: 0.68rem; font-weight: 620; text-transform: uppercase;
    letter-spacing: 0.07em; color: var(--text-muted);
    border-bottom: 1px solid var(--border);
    padding-bottom: 0.45rem;
}

.quote-table tbody tr {
    border-bottom: 1px solid var(--border);
    transition: background 0.12s var(--ease);
}
.quote-table tbody tr:last-child { border-bottom: 0; }
.quote-table tbody tr:hover { background: var(--surface-2); }

/* Bleed the hover tint into the panel padding so full rows highlight. */
.quote-table tbody tr:hover td:first-child,
.quote-table tbody tr:hover th:first-child {
    box-shadow: -0.75rem 0 0 var(--surface-2);
}
.quote-table tbody tr:hover td:last-child {
    box-shadow: 0.75rem 0 0 var(--surface-2);
}

.quote-table .num { text-align: right; font-variant-numeric: tabular-nums; }
.quote-table .price { font-weight: 620; }

.symbol-cell { font-weight: 500; }
.symbol-cell a { color: var(--text); display: block; }
.symbol-cell a:hover { text-decoration: none; }
.symbol-cell a:hover .ticker { color: var(--accent); }
.ticker { display: block; font-weight: 640; letter-spacing: -0.012em; }
.company {
    display: block; font-size: 0.78rem; color: var(--text-muted); font-weight: 400;
    max-width: 28ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

@media (max-width: 900px) {
    .hide-md { display: none; }
}

@media (max-width: 640px) {
    .hide-sm { display: none; }
}

/* Index board ------------------------------------------------------------- */

/* A long table gets the panel's frame but not its padding, so group rows and
   the header can run edge to edge. */
.panel--flush { padding: 0; overflow: hidden; }
.panel--flush .table-scroll { overflow-x: auto; }
.panel--flush .quote-table th:first-child,
.panel--flush .quote-table td:first-child { padding-left: var(--space-5); }
.panel--flush .quote-table th:last-child,
.panel--flush .quote-table td:last-child { padding-right: var(--space-5); }

/* Deliberately not sticky: the header lives inside .table-scroll, so a sticky
   offset would pin it to that scroll container and drop it over the first row
   rather than tracking the page. */
.quote-table--indices thead th {
    background: var(--surface);
    padding-top: var(--space-4);
}

.quote-table--indices tbody tr:last-child { border-bottom: 1px solid var(--border); }
.quote-table--indices tbody:last-child tr:last-child { border-bottom: 0; }

.group-row th {
    font-size: 0.68rem; font-weight: 620; text-transform: uppercase;
    letter-spacing: 0.08em; color: var(--text-muted);
    background: var(--surface-2);
    padding-top: 0.5rem; padding-bottom: 0.5rem;
    border-top: 1px solid var(--border);
}
.group-row:hover { background: var(--surface-2); }

/* Group headers are labels, not data — the row hover treatment does not apply. */
.quote-table--indices tbody tr.group-row:hover th { box-shadow: none; }

/* Section head ------------------------------------------------------------ */

/* A titled band above a group of panels, with its controls on the right. */
.section-head {
    display: flex; align-items: center; justify-content: space-between;
    gap: var(--space-3); flex-wrap: wrap;
    margin-bottom: var(--space-3);
}
.section-head > .muted { margin: 0; }

.section-title {
    font-size: 1.15rem; font-weight: 660; letter-spacing: -0.02em;
}

/* Segment picker ---------------------------------------------------------- */

.segment-picker { display: flex; align-items: center; gap: var(--space-2); margin: 0; }

.segment-picker select {
    appearance: none; -webkit-appearance: none;
    padding: 0.42rem 2rem 0.42rem 0.75rem;
    border: 1px solid var(--border); border-radius: var(--radius-sm);
    background-color: var(--surface); color: var(--text);
    font: inherit; font-size: 0.88rem; font-weight: 550;
    cursor: pointer;
    /* Chevron drawn inline so the control needs no image request. */
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%236b7688' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 6.5 8 10.5l4-4'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.6rem center;
    background-size: 14px 14px;
    transition: border-color 0.15s var(--ease), box-shadow 0.15s var(--ease);
}
.segment-picker select:hover { border-color: var(--border-strong); }
.segment-picker select:focus {
    outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-ring);
}

:root[data-theme="dark"] .segment-picker select {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%238592a6' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 6.5 8 10.5l4-4'/%3E%3C/svg%3E");
}
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .segment-picker select {
        background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%238592a6' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 6.5 8 10.5l4-4'/%3E%3C/svg%3E");
    }
}

.more-link {
    display: inline-flex; align-items: center; gap: 0.35rem;
    font-size: 0.88rem; font-weight: 600;
    padding: 0.3rem 0;
    /* Owns the gap on both sides so it reads the same after a card grid and
       after a pair of panels. Whatever precedes it contributes nothing. */
    margin: var(--space-4) 0 var(--space-5);
}
.more-link svg {
    width: 15px; height: 15px;
    fill: none; stroke: currentColor; stroke-width: 2;
    stroke-linecap: round; stroke-linejoin: round;
    transition: transform 0.15s var(--ease);
}
.more-link:hover { text-decoration: none; }
.more-link:hover svg { transform: translateX(3px); }

/* Market statistics board --------------------------------------------------

   Two rows of one idea. The top four partition the market and get cards; the
   bottom four are small tallies and share a single strip, which keeps them
   visibly subordinate without a second heading saying so.

   Every tile is an <a>. The tone classes only ever set --tone, so the rules
   below stay colour-agnostic and the whole board follows the theme tokens.
-------------------------------------------------------------------------- */

.stat-cards {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(168px, 1fr));
    gap: var(--space-3);
    margin-bottom: var(--space-3);
}

.stat-card {
    --tone: var(--accent);
    --tone-soft: var(--accent-soft);
    position: relative; overflow: hidden;
    display: flex; flex-direction: column; gap: 0.15rem;
    padding: var(--space-4) var(--space-4) var(--space-4) calc(var(--space-4) + 3px);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
    color: var(--text);
    transition: box-shadow 0.18s var(--ease), border-color 0.18s var(--ease), transform 0.18s var(--ease);
}

/* A solid edge of tone, rather than the index cards' hairline-on-hover: this
   board is read at a glance and the colour is doing the sorting. */
.stat-card::before {
    content: ""; position: absolute; inset: 0 auto 0 0; width: 3px;
    background: var(--tone);
}

.stat-card--accent { --tone: var(--accent); --tone-soft: var(--accent-soft); }
.stat-card--up { --tone: var(--up); --tone-soft: var(--up-soft); }
.stat-card--down { --tone: var(--down); --tone-soft: var(--down-soft); }
.stat-card--flat { --tone: var(--flat); --tone-soft: var(--flat-soft); }

.stat-card:hover {
    text-decoration: none; color: var(--text);
    transform: translateY(-2px);
    border-color: var(--border-strong);
    box-shadow: var(--shadow-lg);
}
.stat-card:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--accent-ring); }
.stat-card.is-active { border-color: var(--tone); background: var(--tone-soft); }

.stat-card-label {
    font-size: 0.78rem; font-weight: 560; color: var(--text-secondary);
}
.stat-card-value {
    font-size: 1.75rem; font-weight: 680; line-height: 1.1;
    letter-spacing: -0.03em; font-variant-numeric: tabular-nums;
    color: var(--tone);
}

.stat-strip {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
    overflow: hidden;
}

.stat-strip-item {
    display: flex; flex-direction: column; gap: 0.3rem;
    padding: var(--space-4);
    color: var(--text);
    /* Dividers drawn as borders on the item, so they follow the grid however
       it reflows — no separate rule per breakpoint. */
    border-left: 1px solid var(--border);
    transition: background 0.15s var(--ease);
}
.stat-strip-item:first-child { border-left: 0; }
.stat-strip-item:hover { text-decoration: none; color: var(--text); background: var(--surface-2); }
.stat-strip-item:focus-visible { outline: none; box-shadow: inset 0 0 0 2px var(--accent-ring); }
.stat-strip-item.is-active { background: var(--surface-2); }

.stat-strip-label {
    font-size: 0.8rem; color: var(--text-muted); line-height: 1.45;
}
.stat-strip-label strong { display: block; color: var(--text); font-weight: 600; }

.stat-strip-value {
    display: flex; align-items: center; gap: 0.4rem;
    font-size: 1.4rem; font-weight: 680; letter-spacing: -0.025em;
    font-variant-numeric: tabular-nums;
}
.stat-strip-value--up { color: var(--up); }
.stat-strip-value--down { color: var(--down); }

.stat-caret { width: 11px; height: 9px; flex: none; fill: currentColor; }

.stat-note { margin: var(--space-3) 0 var(--space-5); }

/* Pagination --------------------------------------------------------------- */

.pager {
    display: flex; align-items: center; justify-content: center;
    gap: var(--space-4);
    margin: var(--space-5) 0;
}
.pager-link {
    padding: 0.45rem 0.9rem;
    border: 1px solid var(--border); border-radius: var(--radius-sm);
    background: var(--surface); color: var(--text);
    font-size: 0.88rem; font-weight: 560;
}
.pager-link:hover { text-decoration: none; border-color: var(--border-strong); background: var(--surface-2); }
.pager-link.is-disabled { color: var(--text-muted); background: var(--surface-2); pointer-events: none; }
.pager-status { white-space: nowrap; }

.breadth-panel { margin-top: var(--space-4); }

/* Four across needs ~700px before the labels start wrapping mid-word. */
@media (max-width: 760px) {
    .stat-strip { grid-template-columns: 1fr 1fr; }
    .stat-strip-item:nth-child(odd) { border-left: 0; }
    .stat-strip-item:nth-child(n + 3) { border-top: 1px solid var(--border); }
}

@media (max-width: 480px) {
    .stat-cards { grid-template-columns: 1fr 1fr; }
    .stat-card { padding: var(--space-3) var(--space-3) var(--space-3) calc(var(--space-3) + 3px); }
    .stat-card-value { font-size: 1.45rem; }
    .stat-strip-item { padding: var(--space-3); }
    .stat-strip-value { font-size: 1.2rem; }
    .pager { gap: var(--space-3); }
}

/* Three columns is the most a phone fits. Below that the absolute change is
   dropped and the percentage badge carries the story, rather than leaving the
   column half cut off at the edge of a scroll container. */
@media (max-width: 560px) {
    .panel--flush .quote-table th:first-child,
    .panel--flush .quote-table td:first-child { padding-left: var(--space-3); }
    .panel--flush .quote-table th:last-child,
    .panel--flush .quote-table td:last-child { padding-right: var(--space-3); }
    .quote-table--indices .company { display: none; }

    /*
     | Three things buy back the width a phone does not have, in the order it
     | costs least to lose:
     |
     | 1. the absolute change, since the percentage beside it says the same
     |    thing proportionally (the stock page still shows both);
     | 2. long company names — "Cholamandalam Financial Holdings" against
     |    "HDFC Bank" — truncated, with the ticker above always whole;
     | 3. a slightly smaller table face.
     |
     | Without these the change column fell off the right of the screen once
     | the mid and small cap segments brought longer names in.
     */
    .quote-table .change-abs { display: none; }
    .company { max-width: 15ch; }
    .quote-table { font-size: 0.88rem; }
}

/* Change badges ------------------------------------------------------------ */

.change {
    display: inline-flex; align-items: baseline; gap: 0.4rem;
    font-variant-numeric: tabular-nums; font-weight: 600; font-size: 0.88rem;
}
.change--up { color: var(--up); }
.change--down { color: var(--down); }
.change--flat { color: var(--text-muted); }

.change-pct {
    font-size: 0.78rem; font-weight: 620;
    padding: 0.1rem 0.4rem; border-radius: var(--radius-xs);
}
.change--up .change-pct { background: var(--up-soft); }
.change--down .change-pct { background: var(--down-soft); }
.change--flat .change-pct { background: var(--surface-3); }

/* Stock page --------------------------------------------------------------- */

.page-head--stock { align-items: flex-start; }
.price-block { text-align: right; }
.big-price {
    font-size: clamp(2rem, 1.6rem + 1.6vw, 2.5rem); font-weight: 680; margin: 0;
    font-variant-numeric: tabular-nums; letter-spacing: -0.032em; line-height: 1.1;
}
.price-block--up .big-price { color: var(--up); }
.price-block--down .big-price { color: var(--down); }
.price-block .change { justify-content: flex-end; }

.range-picker {
    display: inline-flex; gap: 0.15rem; flex-wrap: wrap;
    padding: 3px; background: var(--surface-2);
    border: 1px solid var(--border); border-radius: var(--radius-sm);
}
.range {
    font-size: 0.78rem; font-weight: 620; padding: 0.28rem 0.6rem;
    border-radius: var(--radius-xs); color: var(--text-muted);
    transition: background 0.15s var(--ease), color 0.15s var(--ease);
}
.range:hover { text-decoration: none; background: var(--surface); color: var(--text); }
.range--active,
.range--active:hover { background: var(--accent); color: var(--accent-contrast); box-shadow: var(--shadow-sm); }

.chart-wrap { width: 100%; }
.chart-summary { font-size: 0.85rem; margin-top: var(--space-3); }

.price-chart {
    width: 100%; height: auto;
    /* Horizontal drags scrub the chart, vertical ones still scroll the page.
       Without this the browser claims both axes and scrubbing is impossible;
       with `none` it claims neither and the page traps the reader. */
    touch-action: pan-y;
}
.price-chart--up { color: var(--up); }
.price-chart--down { color: var(--down); }
.price-chart .line {
    fill: none; stroke: currentColor; stroke-width: 2;
    stroke-linejoin: round; stroke-linecap: round; vector-effect: non-scaling-stroke;
}
.price-chart .area { stroke: none; }
.price-chart .grid { stroke: var(--border); stroke-width: 1; vector-effect: non-scaling-stroke; }
.price-chart .baseline {
    stroke: var(--text-muted); stroke-width: 1; stroke-dasharray: 3 4;
    opacity: 0.7; vector-effect: non-scaling-stroke;
}
.price-chart .last-point { fill: currentColor; }
.price-chart .axis-label { fill: var(--text-muted); font-size: 11px; font-family: var(--font); }

/* Chart hover readout ------------------------------------------------------

   The crosshair and tooltip ship with the page and are revealed by a class the
   script puts on .chart, rather than being built on first hover — so the first
   move is as smooth as the hundredth, and with JavaScript off none of it is
   ever shown.
-------------------------------------------------------------------------- */

.chart { position: relative; }

/* The SVG is focusable so the readout works from the keyboard; the default
   focus ring on a full-width element is ugly, so it gets a soft inset one. */
.price-chart:focus { outline: none; }
.price-chart:focus-visible {
    outline: 2px solid var(--accent); outline-offset: 2px; border-radius: var(--radius-sm);
}

.crosshair { opacity: 0; transition: opacity 0.12s var(--ease); pointer-events: none; }
.chart.is-active .crosshair { opacity: 1; }

.crosshair-line {
    stroke: var(--text-muted); stroke-width: 1; stroke-dasharray: 2 3;
    vector-effect: non-scaling-stroke;
}
.crosshair-dot {
    fill: var(--surface); stroke: currentColor; stroke-width: 2.5;
    vector-effect: non-scaling-stroke;
}

.chart-tip {
    position: absolute; top: 0; left: 0;
    display: flex; align-items: baseline; gap: 0.5rem;
    padding: 0.4rem 0.65rem;
    background: var(--surface); border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm); box-shadow: var(--shadow);
    font-size: 0.82rem; white-space: nowrap;
    /* Never intercept the pointer — the readout it belongs to is driven by
       pointermove on the SVG underneath it. */
    pointer-events: none;
    opacity: 0; transition: opacity 0.12s var(--ease);
    transform: translateX(10px);
    z-index: 2;
}
.chart.is-active .chart-tip { opacity: 1; }

/* Past the midpoint the tooltip sits to the left of the crosshair instead, so
   a reading near the last candle is not cut off by the panel edge. */
.chart-tip--flip { transform: translateX(calc(-100% - 10px)); }

.chart-tip-price { font-weight: 660; color: var(--text); font-variant-numeric: tabular-nums; }
.chart-tip-change { font-weight: 600; font-variant-numeric: tabular-nums; }
.chart-tip-change--up { color: var(--up); }
.chart-tip-change--down { color: var(--down); }
.chart-tip-time { color: var(--text-muted); }

@media (max-width: 560px) {
    .chart-tip { font-size: 0.76rem; gap: 0.35rem; padding: 0.3rem 0.5rem; }
    /* Three columns of text will not fit beside a finger on a phone, and the
       date is the part a tap is least likely to be asking about. */
    .chart-tip-change { display: none; }
}

.chart-empty {
    padding: var(--space-7) var(--space-4); text-align: center; color: var(--text-muted);
    background: var(--surface-2); border: 1px dashed var(--border);
    border-radius: var(--radius-sm); font-size: 0.9rem;
}

.sparkline { width: 100%; height: 42px; }
.sparkline path { fill: none; stroke-width: 1.6; vector-effect: non-scaling-stroke; }
.sparkline--up path { stroke: var(--up); }
.sparkline--down path { stroke: var(--down); }
.sparkline--flat path { stroke: var(--text-muted); }
.sparkline--empty { display: block; height: 42px; }

/* Stats -------------------------------------------------------------------- */

.stats {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(132px, 1fr));
    gap: var(--space-3) var(--space-4); margin: 0;
}
.stats div { border-bottom: 1px solid var(--border); padding-bottom: 0.45rem; }
.stats dt {
    font-size: 0.68rem; font-weight: 620; color: var(--text-muted);
    text-transform: uppercase; letter-spacing: 0.07em;
}
.stats dd {
    margin: 0.2rem 0 0; font-weight: 620; font-size: 1rem;
    font-variant-numeric: tabular-nums; letter-spacing: -0.015em;
}
.stats dd .change { margin-left: 0.35rem; font-size: 0.78rem; }
.stats dd .small { margin-left: 0.35rem; font-weight: 500; }

/* The fundamentals grid runs the full width of the page rather than sharing a
   column, so it can afford wider cells and fewer cramped wraps. */
.stats--wide { grid-template-columns: repeat(auto-fit, minmax(158px, 1fr)); }

.subhead {
    font-size: 0.8rem; font-weight: 640; text-transform: uppercase;
    letter-spacing: 0.07em; color: var(--text-muted);
    margin: var(--space-5) 0 var(--space-3);
    padding-top: var(--space-4); border-top: 1px solid var(--border);
}

/* Financial performance -----------------------------------------------------

   Plain HTML bars, not SVG. Heights are percentages of the plot, which CSS
   resolves natively and which reflows on a phone without any of the viewBox
   arithmetic an SVG would need.

   Revenue and profit share one scale on purpose. Profit is a fraction of
   revenue; giving each its own axis would draw them the same height and imply
   a company earns what it turns over.
-------------------------------------------------------------------------- */

.fin-chart { margin-top: var(--space-2); }

.fin-legend {
    display: flex; align-items: center; gap: var(--space-4);
    flex-wrap: wrap; margin-bottom: var(--space-4);
    font-size: 0.78rem; font-weight: 560;
}
.fin-key { display: inline-flex; align-items: center; gap: 0.4rem; color: var(--text-secondary); }
.fin-key::before {
    content: ""; width: 10px; height: 10px; border-radius: 3px; background: var(--tone);
}
.fin-key--revenue { --tone: var(--accent); }
.fin-key--profit { --tone: var(--up); }

.fin-plot {
    position: relative;
    display: flex; align-items: stretch; justify-content: space-around;
    gap: var(--space-2);
    height: 260px;
    /* A loss hangs below the axis and must not be clipped by the plot box. */
    overflow: visible;
}

/* One line across the whole plot rather than a segment per column, so it reads
   as an axis instead of a dashed row of ticks. */
.fin-axis {
    position: absolute; left: 0; right: 0; bottom: var(--fin-zero, 0%);
    border-top: 1px dashed var(--border-strong);
}

/* The column is the bars' positioning context and is exactly as tall as the
   plot, so a percentage means the same thing to a bar as it does to the axis.
   Labels live in their own row below for that reason. */
.fin-col { position: relative; flex: 1 1 0; min-width: 0; }

.fin-labels { display: flex; justify-content: space-around; gap: var(--space-2); }
.fin-labels .fin-label { flex: 1 1 0; min-width: 0; }

.fin-bar {
    position: absolute; bottom: var(--fin-zero, 0%);
    width: 26px; max-width: 40%;
    height: var(--fin-height, 0%);
    background: var(--tone);
    border-radius: 3px 3px 0 0;
    transition: filter 0.15s var(--ease);
}
.fin-bar:hover { filter: brightness(1.08); }

/* A loss hangs below the axis, so it grows downwards and its corners round the
   other way.

   The base rule's `bottom: var(--fin-zero)` is kept, not overridden: the bar is
   still anchored to the axis, and translateY(100%) shifts it down by its own
   height so its *top* edge sits on the line. Setting `bottom: auto` here would
   unanchor it entirely and float it at the top of the column. */
.fin-bar--negative {
    transform: translateY(100%);
    border-radius: 0 0 3px 3px;
}

.fin-bar--revenue { --tone: var(--accent); right: calc(50% + 3px); }
.fin-bar--profit { --tone: var(--up); left: calc(50% + 3px); }
.fin-bar--profit.fin-bar--negative { --tone: var(--down); }

.fin-label {
    padding-top: var(--space-3); text-align: center;
    font-size: 0.75rem; color: var(--text-muted); white-space: nowrap;
    overflow: hidden; text-overflow: ellipsis;
}

.fin-table-toggle { margin-top: var(--space-5); }
.fin-table-toggle summary {
    cursor: pointer; font-size: 0.85rem; font-weight: 560; color: var(--accent);
    padding: 0.2rem 0;
}
.fin-table-toggle summary:hover { color: var(--accent-hover); }
.fin-table-toggle[open] summary { margin-bottom: var(--space-3); }

@media (max-width: 560px) {
    .fin-plot { height: 200px; }
    .fin-bar { width: 16px; }
    /* Eight quarters across a phone leaves ~40px a column. At 0.68rem
       "Sep '25" ellipsises to "Sep…" and the year — the half that tells you
       which September — is the half that gets dropped. */
    .fin-label { font-size: 0.6rem; letter-spacing: -0.02em; }
    /* The inter-column gap is worth more than the whitespace here: eight gaps
       at 8px is 56px of the 350px available, which is the difference between
       the label fitting and not. */
    .fin-plot, .fin-labels { gap: 2px; }
    .fin-bar--revenue { right: calc(50% + 2px); }
    .fin-bar--profit { left: calc(50% + 2px); }
}

.range-bar { margin-top: var(--space-5); }
.range-bar-track {
    position: relative; height: 7px; border-radius: var(--radius-pill);
    background: linear-gradient(90deg, var(--down-soft), var(--surface-3) 50%, var(--up-soft));
    border: 1px solid var(--border);
}
.range-bar-marker {
    position: absolute; top: 50%; width: 12px; height: 12px; border-radius: 50%;
    background: var(--accent); transform: translate(-50%, -50%);
    border: 2px solid var(--surface); box-shadow: 0 0 0 2px var(--accent-soft);
}
.range-bar-labels {
    display: flex; justify-content: space-between; font-size: 0.75rem;
    color: var(--text-muted); margin-top: 0.45rem; font-variant-numeric: tabular-nums;
}

/* Forms -------------------------------------------------------------------- */

.stacked-form { display: grid; gap: 0.3rem; margin-top: var(--space-1); }
.stacked-form label {
    font-size: 0.78rem; font-weight: 620; color: var(--text-secondary);
    margin-top: var(--space-3);
}
.stacked-form input[type="text"],
.stacked-form input[type="email"],
.stacked-form input[type="password"] {
    padding: 0.55rem 0.7rem;
    border: 1px solid var(--border); border-radius: var(--radius-sm);
    background: var(--surface-2); color: var(--text);
    font: inherit; font-size: 0.92rem;
    transition: border-color 0.15s var(--ease), box-shadow 0.15s var(--ease), background 0.15s var(--ease);
}
.stacked-form input:hover { border-color: var(--border-strong); }
.stacked-form input[type="text"]:focus,
.stacked-form input[type="email"]:focus,
.stacked-form input[type="password"]:focus {
    outline: none; background: var(--surface);
    border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-ring);
}
.stacked-form .button { margin-top: var(--space-4); justify-self: start; }
.stacked-form .checkbox {
    display: flex; align-items: center; gap: 0.45rem;
    font-weight: 400; font-size: 0.9rem; color: var(--text);
    text-transform: none; letter-spacing: 0;
}
.stacked-form .checkbox input { accent-color: var(--accent); width: 15px; height: 15px; }

.field-error { color: var(--down); font-size: 0.8rem; font-weight: 500; }

.auth-card {
    background: var(--surface); border: 1px solid var(--border);
    border-radius: var(--radius); box-shadow: var(--shadow-lg);
    padding: var(--space-6); max-width: 420px; margin: var(--space-6) auto;
}
.auth-card h1 { font-size: 1.4rem; }
.auth-card > .muted:last-child { margin-top: var(--space-5); font-size: 0.88rem; }

/* Messages and empty states ------------------------------------------------ */

.flash {
    display: flex; align-items: flex-start; gap: 0.5rem;
    background: var(--up-soft); border: 1px solid var(--up); color: var(--up);
    padding: 0.65rem 0.9rem; border-radius: var(--radius-sm);
    font-size: 0.9rem; font-weight: 500; margin-bottom: var(--space-4);
}
.flash--error { background: var(--down-soft); border-color: var(--down); color: var(--down); }

.empty { color: var(--text-muted); padding: var(--space-3) 0; font-size: 0.9rem; }
.empty--warn {
    background: var(--surface); border: 1px dashed var(--border-strong);
    border-radius: var(--radius); padding: var(--space-4);
    margin-bottom: var(--space-5);
}

.notes {
    list-style: none; padding: var(--space-3) 0 0; margin: var(--space-3) 0 0;
    border-top: 1px solid var(--border); font-size: 0.85rem; color: var(--text-muted);
}
.notes li { padding: 0.2rem 0; }
.notes strong { color: var(--text); margin-right: 0.45rem; }

.hint { font-size: 0.8rem; margin-top: var(--space-4); line-height: 1.6; }

.api-hint {
    margin-top: var(--space-5); border-top: 1px solid var(--border);
    padding-top: var(--space-3); display: grid; gap: 0.35rem;
}
.api-hint code { display: block; font-size: 0.74rem; overflow-x: auto; }

.fx-strip {
    display: flex; gap: var(--space-5); flex-wrap: wrap; align-items: center;
    font-size: 0.85rem; color: var(--text-secondary);
    padding: 0.8rem var(--space-5);
    background: var(--surface); border: 1px solid var(--border);
    border-radius: var(--radius); box-shadow: var(--shadow-sm);
}
.fx-strip strong {
    font-weight: 620; margin-right: 0.35rem; color: var(--text);
    font-variant-numeric: tabular-nums;
}

/* Footer ------------------------------------------------------------------- */

.site-footer {
    border-top: 1px solid var(--border);
    background: var(--bg-accent);
    padding: var(--space-5) 0 var(--space-6);
    font-size: 0.8rem;
    color: var(--text-muted);
}
.footer-inner { display: grid; gap: 0.2rem; }
.site-footer p { margin: 0; max-width: 70ch; }

/* Live tick highlight (applied by public/js/app.js) ------------------------- */

@keyframes tick-up-flash {
    from { background: var(--up-soft); color: var(--up); }
    to { background: transparent; }
}
@keyframes tick-down-flash {
    from { background: var(--down-soft); color: var(--down); }
    to { background: transparent; }
}
.tick-up { animation: tick-up-flash 1.1s ease-out; border-radius: var(--radius-xs); }
.tick-down { animation: tick-down-flash 1.1s ease-out; border-radius: var(--radius-xs); }

/* Small screens ------------------------------------------------------------ */

@media (max-width: 720px) {
    .wrap { width: min(1200px, 100% - 1.75rem); }
    .header-inner { gap: var(--space-3) var(--space-2); }
    .brand-name { display: none; }
    .search { order: 3; flex-basis: 100%; }
    .nav { margin-left: auto; gap: var(--space-2); }
    .page-head { align-items: flex-start; }
    .price-block { text-align: left; }
    .price-block .change { justify-content: flex-start; }
    .panel { padding: var(--space-4); }
}

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
    .card:hover { transform: none; }
}

/* Reported results -----------------------------------------------------------

   The quarters as filed with NSE. A wide table on a narrow screen: it scrolls
   inside its own container rather than widening the page, and the quarter
   column stays put so a row never loses its label mid-scroll.
-------------------------------------------------------------------------- */

/* No bleed padding here, deliberately. A scroll container with horizontal
   padding puts the sticky column's `left: 0` inside that padding, so the
   scrolled columns pass through the gap to its left and the frozen cell looks
   broken rather than fixed. The panel's own padding does the insetting. */
.results-panel .table-scroll { overflow-x: auto; }

.results-table {
    width: 100%; border-collapse: collapse;
    font-size: 0.86rem; font-variant-numeric: tabular-nums;
}

.results-table th,
.results-table td {
    padding: 0.6rem 0.75rem;
    border-bottom: 1px solid var(--border);
    white-space: nowrap;
}

.results-table thead th {
    font-size: 0.7rem; font-weight: 620; text-transform: uppercase;
    letter-spacing: 0.06em; color: var(--text-muted);
    border-bottom: 1px solid var(--border-strong);
}

.results-table .num { text-align: right; }
.results-table tbody th { font-weight: 600; text-align: left; }

/* The quarter column is the row's label; it stays visible while the numbers
   scroll under it. Opaque background and a hairline on its right edge, so the
   columns disappearing beneath it read as intended rather than as clipping. */
.results-table th:first-child {
    position: sticky; left: 0; z-index: 1;
    background: var(--surface);
    padding-left: 0;
    box-shadow: 1px 0 0 var(--border);
}

.results-table tbody tr:hover { background: var(--surface-2); }
.results-table tbody tr:hover th:first-child { background: var(--surface-2); }

.results-table tfoot th,
.results-table tfoot td {
    border-bottom: 0; border-top: 1px solid var(--border-strong);
    font-weight: 620;
}

.results-table .trend--up { color: var(--up); }
.results-table .trend--down { color: var(--down); }
.results-table .trend--flat { color: var(--text-secondary); }

.source-note { margin-top: var(--space-4); }
.source-note strong { color: var(--text); font-weight: 620; }

@media (max-width: 560px) {
    .results-table { font-size: 0.8rem; }
    .results-table th,
    .results-table td { padding: 0.5rem 0.55rem; }
}

/* Muted stat block — identity rather than measurement (ISIN, face value). */
.stats--muted { margin-top: var(--space-3); }
.stats--muted dt,
.stats--muted dd { color: var(--text-secondary); }
.stats--muted dd { font-weight: 560; }

/* Screener -------------------------------------------------------------------

   A screen is a URL: every control is a GET parameter, so any filter set can be
   bookmarked, shared, or stepped back to with the browser button.
-------------------------------------------------------------------------- */

.preset-row {
    display: grid; gap: var(--space-3);
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    margin-bottom: var(--space-5);
}

.preset {
    display: block; padding: var(--space-3) var(--space-4);
    border: 1px solid var(--border); border-radius: var(--radius-sm);
    background: var(--surface-2); text-decoration: none;
    transition: border-color 0.15s var(--ease), background 0.15s var(--ease);
}
.preset:hover { border-color: var(--border-strong); background: var(--surface-3); }
.preset--active { border-color: var(--accent); background: var(--accent-ring); }
.preset strong { display: block; color: var(--text); font-size: 0.92rem; font-weight: 620; }
.preset span { display: block; margin-top: 0.25rem; color: var(--text-muted); font-size: 0.78rem; line-height: 1.45; }

.screen-search input {
    width: 100%; padding: 0.6rem 0.85rem;
    border: 1px solid var(--border); border-radius: var(--radius-sm);
    background: var(--surface); color: var(--text); font: inherit;
}
.screen-search input:focus {
    outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-ring);
}

.screen-grid {
    display: grid; gap: var(--space-3);
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    margin: var(--space-4) 0;
}

/* Min and max side by side: a range is one idea, so it reads as one control. */
.screen-field {
    border: 0; padding: 0; margin: 0;
    display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-2);
}
.screen-field legend {
    padding: 0; margin-bottom: 0.35rem;
    font-size: 0.74rem; font-weight: 620; text-transform: uppercase;
    letter-spacing: 0.05em; color: var(--text-muted);
}
.screen-field input {
    width: 100%; padding: 0.42rem 0.55rem;
    border: 1px solid var(--border); border-radius: var(--radius-sm);
    background: var(--surface); color: var(--text);
    font: inherit; font-size: 0.85rem;
    font-variant-numeric: tabular-nums;
}
.screen-field input:focus {
    outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-ring);
}

.screen-actions {
    display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap;
    padding-top: var(--space-3); border-top: 1px solid var(--border);
}
.screen-toggle {
    display: inline-flex; align-items: center; gap: 0.45rem;
    color: var(--text-secondary); font-size: 0.82rem;
}

/* Sortable headers. The arrow marks the column, not the direction — the
   direction is in aria-sort, and a second click reverses it. */
.sort-link {
    color: inherit; text-decoration: none;
    display: inline-block; white-space: nowrap;
}
.sort-link:hover { color: var(--accent); }
.sort-link--active { color: var(--accent); }
.sort-link--active::after { content: " ↓"; font-size: 0.8em; }
.sort-link--active[aria-sort="ascending"]::after { content: " ↑"; }

.symbol-link { text-decoration: none; display: block; }
.symbol-link .symbol { display: block; font-weight: 620; color: var(--text); }
.symbol-link:hover .symbol { color: var(--accent); }
.symbol-link .muted { display: block; }

.pagination-wrap { margin-top: var(--space-5); text-align: center; }

.pagination {
    display: flex; flex-wrap: wrap; justify-content: center;
    gap: 0.35rem; list-style: none; margin: 0 0 var(--space-2); padding: 0;
}
.pagination__item a,
.pagination__item span {
    display: inline-block; min-width: 2.2rem; padding: 0.4rem 0.65rem;
    border: 1px solid var(--border); border-radius: var(--radius-sm);
    color: var(--text-secondary); text-decoration: none; font-size: 0.86rem;
    font-variant-numeric: tabular-nums;
}
.pagination__item a:hover { border-color: var(--border-strong); color: var(--text); }
.pagination__item--current span {
    background: var(--accent); border-color: var(--accent); color: var(--accent-contrast);
    font-weight: 600;
}
/* A page you cannot go to should look like one, not like a live control. */
.pagination__item--disabled span { opacity: 0.45; }
.pagination__item--gap span { border-color: transparent; }

/* Candle chart ------------------------------------------------------------- */

.candle-chart { width: 100%; height: auto; overflow: visible; }

.chart-grid { stroke: var(--chart-gridline); stroke-width: 1; shape-rendering: crispEdges; }

.chart-axis {
    fill: var(--text-muted); font-family: var(--font); font-size: 10.5px;
    font-variant-numeric: tabular-nums;
}

/* The wick carries the body's colour, so a candle reads as one mark rather
   than a bar with a line through it. */
.candle--up .candle-wick, .candle--up .candle-body { stroke: var(--candle-up); }
.candle--down .candle-wick, .candle--down .candle-body { stroke: var(--candle-down); }
.candle--up .candle-body { fill: var(--candle-up); }
.candle--down .candle-body { fill: var(--candle-down); }
.candle-wick { stroke-width: 1; }
.candle-body { stroke-width: 0.5; }

.chart-ma { fill: none; stroke-width: 1.5; stroke-linejoin: round; stroke-linecap: round; }
.ma--fast { stroke: var(--chart-ma-fast); }
.ma--slow { stroke: var(--chart-ma-slow); }

.volume-bar--up { fill: var(--candle-up); opacity: 0.9; }
.volume-bar--down { fill: var(--candle-down); opacity: 0.9; }
.volume-ma { fill: none; stroke: var(--chart-ma-fast); stroke-width: 1.2; }

/* The current-value tag on each axis. Solid rather than outlined so it reads
   as "here, now" against a busy chart. */
.chart-marker rect { fill: var(--text); }
.chart-marker text {
    fill: var(--bg); font-family: var(--font); font-size: 10.5px; font-weight: 620;
    font-variant-numeric: tabular-nums;
}

.chart-extremes { font-family: var(--font); font-size: 11px; font-weight: 600; }
.chart-extremes--high { fill: var(--candle-down); }
.chart-extremes--low { fill: var(--candle-up); }

.chart-legend {
    display: flex; flex-wrap: wrap; gap: var(--space-4);
    color: var(--text-muted); font-size: 0.78rem; padding-top: var(--space-2);
}
.chart-legend span { display: inline-flex; align-items: center; gap: 0.4rem; }
.chart-legend i {
    width: 14px; height: 2.5px; border-radius: 2px; display: inline-block;
}
.legend-fast { background: var(--chart-ma-fast); }
.legend-slow { background: var(--chart-ma-slow); }
.legend-up { background: var(--candle-up); height: 10px; width: 5px; }
.legend-down { background: var(--candle-down); height: 10px; width: 5px; }

.timeframe-row {
    display: flex; gap: var(--space-2); flex-wrap: wrap; align-items: center;
}

/* Index overlay and relative strength. Thinner than the moving averages and
   drawn under the candles: both are context for the price, not rivals to it. */
.chart-overlay { fill: none; stroke-width: 1.2; stroke-linejoin: round; }
.overlay-index { stroke: var(--chart-index); }
.overlay-rs { stroke: var(--chart-rs); stroke-width: 1.4; }
.chart-strip-label { font-size: 9.5px; letter-spacing: 0.04em; text-transform: uppercase; }

.legend-index { background: var(--chart-index); }
.legend-rs { background: var(--chart-rs); }

/* Pivot and volume labels. Small and quiet: they annotate the chart, they are
   not the chart. A provisional pivot — the leg still running — is dimmed,
   because next week's bar can still take it further. */
.pivot-label, .volume-label {
    font-family: var(--font); font-size: 9.5px; font-weight: 620;
    font-variant-numeric: tabular-nums; paint-order: stroke fill;
    stroke: var(--surface); stroke-width: 2.6px; stroke-linejoin: round;
}
.pivot-label--high { fill: var(--text-secondary); }
.pivot-label--low { fill: var(--text-secondary); }
.pivot-label--provisional { opacity: 0.62; }
.volume-label { fill: var(--text-muted); font-size: 9px; }

/* The RS rating badge on the strength strip. A rank, not a reading off the
   line beside it, so it is written as a label with a number. */
.rs-rating { fill: var(--chart-rs); font-weight: 700; letter-spacing: 0.02em; }


/* ---------------------------------------------------------------------------
   CANSLIM

   The whole visual problem on this page is that there are three states, not
   two. A criterion that could not be evaluated has to be distinguishable from
   one that failed — at a glance, in a dense table, and without relying on
   colour alone, because roughly one man in twelve cannot separate the red from
   the green. So each state carries a different glyph as well as a different
   colour, and the unknown state is deliberately the quietest of the three: it
   is an absence of evidence, and it should not shout like a verdict.
--------------------------------------------------------------------------- */

.canslim-market .panel-head h2 { margin: 0; }

.badge {
    display: inline-flex; align-items: center;
    padding: 0.3rem 0.7rem; border-radius: var(--radius-pill);
    font-size: 0.78rem; font-weight: 640; letter-spacing: 0.01em;
    border: 1px solid var(--border);
}
.badge--up { color: var(--up); background: var(--up-soft); border-color: transparent; }
.badge--down { color: var(--down); background: var(--down-soft); border-color: transparent; }
.badge--flat { color: var(--flat); background: var(--surface-3); border-color: transparent; }

/* A left edge in the market's own colour, so the reading registers before any
   of the words do — this is the letter that overrules the other six. */
.canslim-market { border-left: 3px solid var(--border-strong); }
.canslim-market--uptrend { border-left-color: var(--up); }
.canslim-market--pressure { border-left-color: var(--flat); }
.canslim-market--correction { border-left-color: var(--down); }
.canslim-market p { margin: 0 0 var(--space-4); color: var(--text-muted); font-size: 0.9rem; }

.canslim-letters {
    display: grid; gap: var(--space-3);
    grid-template-columns: repeat(auto-fit, minmax(215px, 1fr));
    margin: var(--space-4) 0;
}

.canslim-letter {
    display: grid; grid-template-columns: auto auto 1fr; align-items: baseline;
    gap: 0.5rem; padding: var(--space-3);
    border: 1px solid var(--border); border-radius: var(--radius-sm);
    background: var(--surface-2); cursor: pointer;
    transition: border-color 0.15s var(--ease), background 0.15s var(--ease);
}
.canslim-letter:hover { border-color: var(--border-strong); background: var(--surface-3); }
.canslim-letter--on { border-color: var(--accent); background: var(--accent-ring); }
.canslim-letter strong { font-size: 1rem; font-weight: 700; color: var(--text); }
.canslim-letter span { color: var(--text-muted); font-size: 0.76rem; line-height: 1.4; }

.canslim-mark {
    display: inline-flex; align-items: center; justify-content: center;
    width: 1.4rem; height: 1.4rem; border-radius: 50%;
    font-size: 0.8rem; font-weight: 700; line-height: 1;
}
.canslim-mark--pass { color: var(--up); background: var(--up-soft); }
.canslim-mark--fail { color: var(--down); background: var(--down-soft); }
/* Quietest of the three on purpose: an absence of evidence, not a verdict. */
.canslim-mark--unknown { color: var(--text-muted); background: var(--surface-3); font-weight: 600; }

/* The per-letter breakdown on a stock page. One row per criterion, the mark on
   the left so the column of verdicts reads down the page in one pass. */
.canslim-rows { display: grid; gap: var(--space-3); margin: 0; }
.canslim-row {
    display: grid; grid-template-columns: auto auto 1fr; gap: var(--space-3);
    align-items: start; padding-bottom: var(--space-3);
    border-bottom: 1px solid var(--border);
}
.canslim-row:last-child { border-bottom: 0; padding-bottom: 0; }
.canslim-row .canslim-row__letter {
    font-weight: 700; font-size: 0.95rem; width: 1.1rem; color: var(--text-muted);
}
.canslim-row dt { font-weight: 620; font-size: 0.9rem; color: var(--text); }
.canslim-row dd { margin: 0.2rem 0 0; color: var(--text-muted); font-size: 0.84rem; line-height: 1.5; }

.canslim-summary {
    display: flex; align-items: baseline; gap: 0.4rem;
    font-size: 0.85rem; color: var(--text-muted);
}
.canslim-summary strong { font-size: 1.5rem; font-weight: 700; color: var(--text); }

/* The market's own verdict, stated rather than used to empty the table. */
.canslim-verdict {
    margin: 0 0 var(--space-4); padding: var(--space-3);
    border-radius: var(--radius-sm); background: var(--surface-2);
    color: var(--text); font-size: 0.86rem; line-height: 1.55;
}

/* A letter with no data behind it for most of the market. Muted rather than
   alarming — it is a gap in the archive, not a fault. */
.canslim-blind { color: var(--text-muted); }
.canslim-coverage .notes { margin-top: var(--space-4); }

/* "M" on a stock page: below the six, separated, because it is not a fact
   about that company. */
.canslim-market-row {
    display: grid; grid-template-columns: auto auto 1fr; gap: var(--space-3);
    align-items: start; margin-top: var(--space-4);
    padding-top: var(--space-4); border-top: 1px solid var(--border);
}
.canslim-market-row dt { font-weight: 620; font-size: 0.9rem; color: var(--text); }
.canslim-market-row dd { margin: 0.2rem 0 0; color: var(--text-muted); font-size: 0.84rem; line-height: 1.5; }
