/* Adanos 2026 redesign: the system sheet of every 2026 page (public/*-2026.html): tokens, base and every kit component. Each page links it first, then the sheet of its page type. Filed by scripts/kit/split.py. */
/* Inter never swaps late: Arial wraps some lines differently, so a late swap would move the text below it. A phone on a
   slow line keeps the fallback for its first visit. The file holds only the weights the pages use (400 to 600), so it
   arrives in time more often. JetBrains Mono swaps in when it arrives: its fallback has the same advance and line box,
   so the swap moves no line (measured in Chromium and WebKit). */
@font-face {
    font-family: 'Inter';
    font-style: normal;
    font-weight: 400 600;
    font-display: optional;
    src: url('fonts/inter-latin.woff2') format('woff2');
}
@font-face {
    font-family: 'JetBrains Mono';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('fonts/jetbrains-mono-latin.woff2') format('woff2');
}
/* Arial (Roboto on Android) set to Inter's width at 16px and to its line box (ascent 1984, descent 494 of 2048 units,
   measured in Chromium) */
@font-face {
    font-family: 'Inter Fallback';
    src: local('Arial'), local('Roboto');
    ascent-override: 91.39%;
    descent-override: 22.76%;
    line-gap-override: 0%;
    size-adjust: 106%;
}
/* a system mono with JetBrains Mono's advance of 0.6em, set to its line box (ascent 1020, descent 300 of 1000) */
@font-face {
    font-family: 'JetBrains Mono Fallback';
    src: local('Courier New'), local('Droid Sans Mono'), local('Liberation Mono');
    ascent-override: 102%;
    descent-override: 30%;
    line-gap-override: 0%;
}

/* ---------- Design tokens ----------
   Every repeated detail takes its value from here: the same detail gets the same token on every page. If a new
   value seems needed, add a token instead of a literal. Brand palette unchanged; copper/gold always means the
   Adanos signal. */
:root {
    /* Colour: palette. The colours of the brand (/brand): the logo's greys, the signal and its golds. A component never
       paints text with a grey of the palette: text takes a role below, which .on-dark switches, so every component reads
       on light and on dark. scripts/kit/split.py fails a `color` on --graphite, --graphite-2, --slate or --silver. */
    --graphite: #2d3438;
    --graphite-2: #454e54;
    --slate: #727f87;
    --silver: #c7c7c7; /* the logo silver; also the reading text on dark (.on-dark --ink-2), at least 7.5:1 on --graphite panels */
    --signal: #c76745;
    --gold: #dea35f;
    --gold-light: #f8dda1;
    --code-gold: #edc57d; /* methods, strings and the retail crowd on dark */
    --gold-gradient: linear-gradient(90deg, var(--gold) 0%, var(--code-gold) 48%, var(--gold-light) 100%);
    /* Colour: surfaces and lines */
    --bg: #f8f7f3;
    --bg-2: #f0efec; /* lower end of the hero and closing gradients */
    --paper: #fff; /* boxes on light; on dark the text of headings, figures and emphasis */
    --line: #e6e1d7; /* dividers inside a box */
    --line-2: #d8d2c8; /* box edges, rules under table heads */
    --line-soft: var(--bg-2); /* chart grid lines, skeleton shimmer, gold meter track */
    --sunk: var(--bg); /* a band a step under its box: the box foot */
    --hover: rgb(26 26 26 / 0.04); /* hover tint of light buttons and links */
    --press: rgb(26 26 26 / 0.06); /* pressed and open state of light buttons */
    --gold-edge: #c9a64a; /* the edge of a picked card in the live page's gold, as the register's chosen plan */
    --gold-card: linear-gradient(135deg, #fbf8f2 0%, #f4ecd5 52%, #ecdfb6 100%); /* the fill of a picked card */
    /* Colour: text roles. --ink headings and key figures, --ink-2 everything meant to be read
       (leads, fact lines, labels in sentences), --muted only for meta (timestamps, axis, table heads, breadcrumbs),
       --signal-ink the signal as text and --fill-ink text on a light fill that stays light on dark.
       Meta on its own line or as a label is --text-xs; inside a sentence or a table cell it keeps the size around it. */
    --ink: #1a1a1a;
    --ink-2: var(--graphite); /* body text, leads: dark enough for long reading (11:1 on --bg) */
    --muted: var(--graphite-2); /* meta, labels, table heads, field notes: the graphite's second step, 8.5:1 on paper and at least 6.3:1 on every light surface (7.2:1 on the gold and red tints, 6.4:1 at the far end of a picked card's gold); no text on a light surface is lighter */
    --signal-ink: #a14e30; /* the signal colour as text on light surfaces: at least 4.9:1, the full colour stays under 4.5:1 */
    --fill-ink: var(--graphite); /* text on a fill that stays light on a dark band too, as a gold chip or a paper button; .on-dark leaves it */
    /* Colour: status. Text in --bull/--bear, words marked inside text in the darker -ink, chips and marks on a tint */
    --bull: #2e7d32;
    --bear: #c62828;
    --bull-ink: #1f5e23;
    --bear-ink: #9d1f1f;
    --neutral-ink: var(--graphite-2); /* text of a neutral tag */
    --gold-ink: var(--graphite); /* text on the gold tint: the PRO tag */
    --marker: var(--slate); /* fill of a neutral marker on a scale; paper on dark */
    --chip-bg: var(--paper); /* fill of a chip; the code panel's dark inside .on-dark */
    --raised: var(--paper); /* the pressed option of a segmented control, a step above its tray */
    --raised-edge: var(--line-2); /* its hairline; none on dark */
    --wire: var(--line-2); /* the dots of a window bar */
    --tint-bull: color-mix(in srgb, var(--bull) 10%, transparent);
    --tint-bear: color-mix(in srgb, var(--bear) 10%, transparent);
    --tint-neutral: color-mix(in srgb, var(--slate) 12%, transparent);
    --tint-gold: color-mix(in srgb, var(--gold) 22%, transparent);
    /* Colour: code. A JSON body takes its keys in --ink-2, its strings in --code-string and its numbers in --signal-ink,
       so .on-dark turns them grey, gold and coral */
    --code-body: var(--ink-2); /* the text of a JSON body or a code block; the code panel's --dark-body inside .on-dark */
    --code-string: var(--code-brown); /* a string in JSON; code gold inside .on-dark */
    --code-comment: #3b6e35; /* a comment in code (a // note, a # line) in an editor's green: 5.6:1 on --bg; --dark-comment inside .on-dark */
    --src-reddit: #ff4500; /* source brand colours: the product page's mark (--brand) */
    --snoo-gold-0: #ffe289; /* the gold Snoo of the Reddit crypto page, as on adanos.com: its radial disc from light to deep */
    --snoo-gold-1: #f7b733;
    --snoo-gold-2: #e39a12;
    --snoo-gold-pupil: #c9830a;
    --src-news: #12a150; /* the News tile */
    --code-brown: #8a5a2b; /* strings of a JSON body on light surfaces, through --code-string */
    --code-coral: #e9a07a; /* the signal colour as text on dark (.on-dark --signal-ink): JSON numbers, the fear end of a scale */
    /* Colour: dark surfaces (code panels, agent session, dark bands, footer); .on-dark switches the roles above */
    --dark: #1f2427;
    --dark-deep: var(--ink); /* footer, one step darker than the bands; it holds the light ink, which .on-dark turns to paper */
    --dark-body: var(--line-2); /* base text of code panels; it holds the light value, which .on-dark switches */
    --dark-muted: #99a0a4; /* at least 4.7:1 on --graphite panels, still a step under --silver */
    --dark-comment: #7fb069; /* comments in code on dark (.on-dark --code-comment): 6.2:1 on --dark, 5.0:1 on --graphite */
    --dark-line: rgb(255 255 255 / 0.08); /* dividers, chips, bubbles and hover */
    --dark-edge: rgb(255 255 255 / 0.12); /* box edges, pressed and lit fills, connector lines */
    --dark-line-2: rgb(255 255 255 / 0.3); /* underlines, the chosen tab's edge */
    --dark-fill-soft: rgb(255 255 255 / 0.05); /* cards and tracks */
    --dark-bull: color-mix(in srgb, var(--bull) 50%, #fff); /* gains and confirmations on dark */
    --dark-tint-bull: color-mix(in srgb, var(--bull) 22%, transparent); /* gain chips on dark */
    --dark-sunk: rgb(0 0 0 / 0.18); /* footer band of a dark panel */
    --dark-bear: color-mix(in srgb, var(--bear) 45%, #fff);
    --dark-tint-bear: color-mix(in srgb, var(--bear) 26%, transparent); /* loss chips on dark */
    --logo-ring: rgb(0 0 0 / 0.08); /* hairline around white logo tiles; none on dark */
    /* Colour: glass and the background grid */
    --glass-bar: rgb(255 255 255 / 0.86); /* the floating header bar */
    --glass-tag: rgb(255 255 255 / 0.66); /* source labels and callouts over data */
    --grid-line: rgb(0 0 0 / 0.03); /* the 80px activity grid, as on adanos.org */

    /* Type: one scale, nothing below 13px. Inter for all text, JetBrains Mono only for code, JSON and paths. */
    --sans: 'Inter', 'Inter Fallback', ui-sans-serif, system-ui, -apple-system, sans-serif;
    --mono: 'JetBrains Mono', 'JetBrains Mono Fallback', ui-monospace, SFMono-Regular, Menlo, monospace;
    --text-xs: 13px; /* meta, chips, axis labels, code */
    --text-sm: 14px; /* box body, tables, notes */
    --text-md: 15px; /* UI text: nav, tabs, card copy */
    --text-base: 16px; /* body, buttons */
    --text-lg: 18px; /* leads */
    --text-xl: 20px; /* card titles, stat values */
    --text-2xl: 24px; /* feature card title */
    --text-3xl: 32px; /* h2 on phones */
    --text-4xl: 40px; /* h2, page title */
    --text-5xl: 48px; /* closing headline, figures */
    --text-6xl: 64px; /* big figures */
    --text-7xl: 96px; /* headline figure */
    --text-hero: clamp(40px, 5.2vw, 74px);
    --fw-regular: 400;
    --fw-display: 450; /* big figures */
    --fw-medium: 500; /* headings, labels, emphasis */
    --lh-tight: 1; /* one-line labels inside graphics */
    --lh-figure: 0.9;
    --lh-heading: 1.1;
    --lh-title: 1.3;
    --lh-body: 1.55;
    --lh-code: 1.7;
    --tracking-title: -0.015em; /* card titles, 17 to 24px */
    --tracking-heading: -0.03em; /* h2 */
    --tracking-display: -0.04em; /* h1 */
    --tracking-figure: -0.045em; /* big figures */

    /* Space: a 4px scale for layout; the 1 to 3px and odd insets are only used inside chips and controls */
    --space-0-5: 2px;
    --space-1: 4px;
    --space-1-5: 6px;
    --space-2: 8px;
    --space-2-5: 10px;
    --space-3: 12px;
    --space-3-5: 14px;
    --space-4: 16px;
    --space-5: 20px;
    --space-6: 24px;
    --space-7: 28px;
    --space-8: 32px;
    --space-10: 40px;
    --space-12: 48px;
    --space-14: 56px;
    --space-16: 64px;
    --inset-tag: 1px 7px; /* filled tags: 22px tall on a 13px line */
    --inset-glass: 3px 9px; /* glass tags */
    --section-y: 104px; /* section padding, the same above and below */
    --pad: var(--space-5); /* inner padding of boxes and panels */
    --pad-lg: var(--space-7); /* inner padding of large boxes: cards, plans, forms and bands; --pad on phones */
    --inset-code: 18px; /* above and below the code in a code panel */
    --max: 1200px;
    --gutter: var(--space-8);
    --measure: 42rem; /* longest line of running text */

    /* Size: controls, icons, logos and marks */
    --h-btn: 46px; /* full-size buttons */
    --h-control: 38px; /* small buttons, search fields, icon buttons */
    --h-control-sm: 32px; /* segmented controls, copy buttons in bars */
    --icon-sm: 14px;
    --icon: 16px; /* inline Lucide icons */
    --icon-lg: 20px; /* icons in icon buttons */
    --logo-xs: 20px; /* stock logos and source tiles, from tables to the hero */
    --logo-sm: 24px;
    --logo-md: 28px;
    --logo-lg: 36px;
    --logo-xl: 44px;
    --logo-2xl: 56px;
    --logo-3xl: 64px;
    --dot-sm: 6px; /* live dots, list bullets */
    --dot: 8px; /* markers, window dots */
    --bar: 6px; /* every data bar: meters, splits, the stem of a reading and a range on a scale */
    --bar-lg: 10px; /* the register's plan bar and the volume key */
    --spark: 80px; /* sparkline width, drawn at 5:2 */
    --label-col: 8.5rem; /* the label column of key-value rows and of the SDK rows */
    --label-col-text: 14em; /* the term column of key-value rows in running text */
    --tr-head: 40px; /* a board's head row */
    --tr-row: 52px; /* a board's row */
    --tip-w: 360px; /* widest tip: three sentiment keys on one line */
    --search-fill-min: 280px; /* the narrowest a search that fills its row gets before the row wraps */
    --tip-ink: var(--ink); /* the light ink, held here so the light tip keeps it inside .on-dark */
    --grid-cell: 80px;

    /* Shape: box edges. Every card, panel, tile, bar and menu draws --border with --r-box (floating bars --r-float);
       dividers inside a box use var(--line) */
    --border: 1px solid var(--line-2);
    --divider: 1px solid var(--line); /* between rows and columns; switches on dark */
    --dashed: 1px dashed var(--line-2); /* what stands in or guides: an empty source, a cut of a scale, a midpoint, a placeholder; switches on dark */
    --dots: radial-gradient(circle closest-side, color-mix(in srgb, var(--muted) 75%, transparent) 72%, transparent) 0 100% / 4px 2px space no-repeat; /* the underline of a word that explains itself: round 2px dots every 4px as a background, so they stay round at any zoom and never end in half a dot; switches on dark */
    --rule: 1px solid var(--ink); /* the ink rule under a page head and over editorial lists */
    --indicator: 2px; /* the line that marks the chosen tab or the progress of a step */
    --tab-x: var(--space-3); /* the side inset of a tab; its line spans the label */
    --r-2xs: 2px; /* the bars and slots of a small figure */
    --r-xs: 4px; /* chips, scores, kbd, text marks */
    --r: 6px; /* controls, segmented controls, chips, tips and small cards */
    --r-field: calc(var(--r) + var(--space-1)); /* text fields and read-only values; a --r button sits --space-1 inside */
    --r-box: 10px;
    --r-float: 14px;
    --r-pill: 999px; /* bars and meters with round ends */
    --r-round: 50%; /* dots and discs */
    --r-logo: 22%; /* stock logos, as on adanos.org/stocks */
    /* Elevation */
    --shadow-xs: 0 1px 2px rgb(26 26 26 / 0.04); /* cards in motion */
    --shadow-card: var(--shadow-xs), 0 10px 28px rgb(26 26 26 / 0.07); /* stacked cards */
    --shadow-bar: 0 8px 24px -16px rgb(26 26 26 / 0.25); /* the floating header bar: it rests on the page, so it casts less than a menu */
    --shadow-pop: 0 16px 32px -16px rgb(26 26 26 / 0.3); /* what floats over the page: menus, dropdowns and tips */
    --shadow-float: 0 10px 30px -10px rgb(26 26 26 / 0.45); /* the dark sticky bar on phones */
    --shadow-glass: inset 0 1px 0 rgb(255 255 255 / 0.8), 0 0 0 1px rgb(26 26 26 / 0.07), 0 1px 2px -1px rgb(26 26 26 / 0.1), 0 6px 14px -6px rgb(26 26 26 / 0.2);
    --shadow-tile: 0 1px 2px rgb(26 26 26 / 0.14); /* drop shadow of an app tile (filter) */
    --shadow-dot: 0 0 0 1px rgb(26 26 26 / 0.12), 0 2px 6px -2px rgb(26 26 26 / 0.35); /* a marker on a scale */
    --shadow-pick: 0 0 0 0.5px var(--gold-edge); /* half a pixel more of a picked card's gold edge */
    --glow-gold: drop-shadow(0 0 8px color-mix(in srgb, var(--gold) 40%, transparent)); /* the request packets, the gauge fill and the lit signal (filter) */

    /* Motion: hover, press and tab switches take --dur-fast with ease-out; reveals and cross-fades --dur;
       glides (rows, bars, stacks) --dur-slow and data morphs --dur-glide, both with --ease-out-expo */
    --dur-fast: 150ms;
    --dur: 300ms;
    --dur-slow: 600ms;
    --dur-glide: 900ms;
    --ease-out-expo: cubic-bezier(0.2, 0, 0, 1);
    --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1); /* travel from one point to the next (the pipeline packet) */
    --stagger: 100ms; /* between items that enter one after the other */

    /* Layers */
    --z-tip: 3; /* tips over the rows and code they explain */
    --z-nav: 40;
    --z-float: 50;
    /* floating header bar: offset from the top and height (smaller on phones) */
    --nav-top: var(--space-3);
    --nav-h: 60px;
    --nav-space: calc(var(--nav-top) + var(--nav-h)); /* room the header bar takes at the top */
    /* Lucide arrow-right for the CTA arrow (a mask, so it takes the text colour) */
    --lc-arrow-right: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14'/%3E%3Cpath d='m12 5 7 7-7 7'/%3E%3C/svg%3E");
}

* { margin: 0; padding: 0; box-sizing: border-box; }
.vh { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
/* hidden always hides: any display a component sets would beat the browser's own [hidden] rule. The one place that
   keeps a hidden child's space beats this with its own !important (the tool views) */
[hidden] { display: none !important; }
html { -webkit-text-size-adjust: 100%; scroll-padding-top: calc(var(--nav-top) + var(--nav-h) + 8px); }
body {
    background: var(--bg);
    color: var(--ink);
    font-family: var(--sans);
    font-size: var(--text-base);
    line-height: var(--lh-body);
    font-feature-settings: 'cv11', 'ss01';
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    overflow-x: clip;
}
a { color: inherit; text-decoration: none; -webkit-tap-highlight-color: transparent; }
img, svg { display: block; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; -webkit-tap-highlight-color: transparent; }
b, strong { font-weight: var(--fw-medium); }
ul, ol { list-style: none; }
pre { font-family: var(--mono); font-size: var(--text-xs); line-height: var(--lh-code); }
/* the browser gives <code> its own monospace, which would beat the mono set on a <pre> or a bar around it */
code { font-family: var(--mono); }
/* a name marked in a text: the gold tint with its text in --gold-ink; is-match marks the part of a word that matches a
   search, flush with the letters around it and in their colour */
mark { padding: 0 var(--space-0-5); margin: 0 calc(-1 * var(--space-0-5)); border-radius: var(--r-xs); background: var(--tint-gold); color: var(--gold-ink); }
mark.is-match { padding: 0; margin: 0; color: inherit; }
.wrap { max-width: var(--max); margin: 0 auto; padding: 0 var(--gutter); }
/* UI icons are Lucide (same set as app.adanos.org): stroke 2, round caps and joins; 16px inline, 20px in icon buttons */
.lc { width: var(--icon); height: var(--icon); flex: none; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.lc--sm { width: var(--icon-sm); height: var(--icon-sm); }
:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

h1, h2, h3 { font-weight: var(--fw-medium); letter-spacing: var(--tracking-heading); text-wrap: balance; }
h2 { font-size: var(--text-4xl); line-height: var(--lh-heading); }
.lead { font-size: var(--text-lg); color: var(--ink-2); max-width: 36em; text-wrap: pretty; }

/* ---------- Type roles ----------
   Each heading, label and kicker carries one of five role classes, and the rule of its component sets none of these
   properties. Running text styles its headings by element (.prose h2 and h3). A title steps up to --text-2xl only where
   it leads a content section, a part of a form or the wide card of a row (.prose h2, .art-more h2, .bt-cli h3, the wide
   study, the register's plan headings). */
/* title: card titles */
.type-title, .prose h2 { font-size: var(--text-xl); font-weight: var(--fw-medium); line-height: var(--lh-title); letter-spacing: var(--tracking-title); color: var(--ink); }
/* subtitle: the head of a panel, a step or a list item */
.type-subtitle, .prose h3 { font-size: var(--text-lg); font-weight: var(--fw-medium); line-height: var(--lh-title); letter-spacing: var(--tracking-title); color: var(--ink); }
/* small title: a head inside a panel */
.type-small-title { font-size: var(--text-md); font-weight: var(--fw-medium); line-height: var(--lh-title); letter-spacing: var(--tracking-title); color: var(--ink); }
/* label: meta on its own line (column heads, table heads, the contents toggle) */
.type-label { font-size: var(--text-xs); font-weight: var(--fw-medium); line-height: var(--lh-body); letter-spacing: 0; color: var(--muted); }
/* meta: the small grey text of a reading, a date, a source, a count or a hint, on its own line or beside a figure */
.type-meta { font-size: var(--text-xs); font-weight: var(--fw-regular); color: var(--muted); }
/* kicker: the line over a heading (bento cards, article sections), at UI text size so it reads beside the heading */
.type-kicker { font-size: var(--text-md); font-weight: var(--fw-medium); color: var(--muted); }

/* ---------- Buttons ----------
   .btn primary (one main action per view), .btn--secondary outlined (beside a primary),
   .btn--light primary on dark surfaces, .textlink tertiary. .btn--sm for bars and tables.
   Hover changes colour only (150ms), press scales to 0.96.
   Full-size primary buttons carry a trailing arrow (as on adanos.org) that nudges on hover and focus. */
.btn {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    height: var(--h-btn);
    padding: 0 var(--space-5);
    border-radius: var(--r);
    border: 1px solid transparent;
    background: var(--ink);
    color: var(--paper);
    font-size: var(--text-base);
    font-weight: var(--fw-medium);
    white-space: nowrap;
    transition-property: background-color, border-color, scale;
    transition-duration: var(--dur-fast);
    transition-timing-function: ease-out;
}
.btn--sm { height: var(--h-control); padding: 0 var(--space-4); font-size: var(--text-md); }
.btn--secondary { background: transparent; color: var(--ink); border-color: var(--line-2); }
/* fixed dark text: inside .on-dark the --ink token turns white */
.btn--light { background: var(--paper); color: var(--fill-ink); }
:is(.btn, .copy, .search-toggle, .menu-mobile):not(:disabled):active { scale: 0.96; }
.btn:not(.btn--secondary, .btn--sm)::after { content: ""; width: var(--icon); height: var(--icon); background: currentColor; -webkit-mask: var(--lc-arrow-right) center / contain no-repeat; mask: var(--lc-arrow-right) center / contain no-repeat; transition: translate var(--dur-fast) ease-out; }
@media (prefers-reduced-motion: no-preference) {
    .btn:focus-visible::after { translate: 3px 0; }
}
/* a button that cannot act right now: grey fill and text, no arrow; the secondary keeps a light edge */
.btn:disabled { background: var(--line); border-color: transparent; color: var(--muted); cursor: not-allowed; }
.btn:disabled::after { content: none; }
.btn--secondary:disabled { background: transparent; border-color: var(--line); }
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
    .btn:not(:disabled):hover::after { translate: 3px 0; }
}
.textlink { display: inline-flex; align-items: center; gap: var(--space-1-5); font-weight: var(--fw-medium); border-bottom: 1px solid var(--line-2); padding-bottom: 1px; transition: border-color var(--dur-fast) ease-out; }
/* --foot: the link drops to the foot of a card or a point that stacks its content, keeps its own width and reads in ink */
.textlink--foot { margin-top: auto; padding-top: var(--space-2-5); align-self: flex-start; color: var(--ink); }
/* in a paragraph, as a lead or an FAQ answer, the link wraps with its sentence and keeps its underline under each
   line; a comma after it never lands alone on the next line */
p > .textlink { display: inline; }
@media (hover: hover) {
    .btn:not(:disabled):hover { background: var(--graphite); }
    .btn--secondary:not(:disabled):hover { background: var(--hover); border-color: var(--ink-2); }
    .btn--light:not(:disabled):hover { background: var(--bg-2); }
    .textlink:hover { border-color: currentColor; }
}

/* ---------- Nav ---------- */
/* Floating header bar: no full-width rule, a rounded bar inset from the edges */
.nav { position: sticky; top: 0; z-index: var(--z-nav); padding-top: var(--nav-top); }
.nav-inner { position: relative; display: flex; align-items: center; gap: var(--space-8); width: min(calc(var(--max) - 16px), calc(100% - 2 * var(--nav-top))); height: var(--nav-h); margin: 0 auto; padding: 0 var(--space-3) 0 var(--space-6); border-radius: var(--r-float); border: var(--border); background: var(--glass-bar); backdrop-filter: saturate(1.4) blur(12px); -webkit-backdrop-filter: saturate(1.4) blur(12px); box-shadow: var(--shadow-bar); }
.nav-logo img { height: 32px; width: auto; }
.nav-links { display: flex; align-items: center; gap: var(--space-1); font-size: var(--text-md); color: var(--ink-2); }
.nav-links > a, .menu-btn { display: inline-flex; align-items: center; gap: var(--space-1-5); height: var(--h-control); padding: 0 var(--space-2-5); border-radius: var(--r); transition: color var(--dur-fast) ease-out, background-color var(--dur-fast) ease-out; }
.menu-btn svg, .toc summary .lc { transition: rotate var(--dur-fast) ease-out; }
.menu-btn[aria-expanded="true"] { color: var(--ink); background: var(--press); }
.menu-btn[aria-expanded="true"] svg, .toc[open] summary .lc { rotate: 180deg; }
@media (hover: hover) { .nav-links > a:hover, .menu-btn:hover { color: var(--ink); background: var(--hover); } }

/* Products panel hangs below the bar, aligned to its outer (border) edges. It follows the Products button inside the
   nav, so the keyboard reaches its links next, and takes back the page's type from the nav links around it */
.mega { position: absolute; left: -1px; right: -1px; top: calc(100% + 8px); border-radius: var(--r-float); border: var(--border); background: var(--paper); box-shadow: var(--shadow-pop); font-size: var(--text-base); color: var(--ink); }
.mega-inner { padding: var(--space-7) var(--space-6); display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)) minmax(0, 1.1fr); gap: var(--space-8); }
.mega-col > .type-label { padding-bottom: var(--space-3); margin-bottom: var(--space-1-5); border-bottom: var(--divider); }
.mega-col a { display: block; padding: var(--space-2) 0; }
.mega-col b { display: block; font-size: var(--text-md); color: var(--ink); }
.mega-col span { display: block; margin-top: 1px; }
@media (hover: hover) { .mega-col a b { transition: color var(--dur-fast) ease-out; } .mega-col a:hover b { color: var(--signal-ink); } }
.mega-feature { align-self: start; display: flex; flex-direction: column; gap: var(--space-2); padding: var(--space-5); border-radius: var(--r-box); background: var(--bg); border: var(--border); }
.mega-feature span:where(:not(.type-meta)) { font-size: var(--text-sm); color: var(--ink-2); }
.mega-feature .mf-go { margin-top: auto; padding-top: var(--space-2); font-weight: var(--fw-medium); color: var(--ink); }
/* the gauge of the Fear and Greed page in small: beige zones, the lit one in the logo's gold, the needle in ink */
.mega-feature svg { margin-bottom: var(--space-1); }
.mega-feature path { fill: none; stroke: var(--line); stroke-width: 7; }
.mega-feature path.is-on { stroke: url(#mf-lit); }
.mega-feature stop { stop-color: var(--gold); }
.mega-feature stop + stop { stop-color: var(--signal); }
.mega-feature line { stroke: var(--ink); stroke-width: 2.5; stroke-linecap: round; }
.mega-feature circle { fill: var(--ink); }

.nav-right { margin-left: auto; display: flex; align-items: center; gap: var(--space-3-5); }
/* Icon buttons in the bar (smaller screens): borderless, a light tint on hover and press */
.search-toggle, .menu-mobile { display: none; place-items: center; width: var(--h-control); height: var(--h-control); border-radius: var(--r); color: var(--ink); transition-property: background-color, scale; transition-duration: var(--dur-fast); transition-timing-function: ease-out; }
.search-toggle:active, .menu-mobile:active { background: var(--press); }
@media (hover: hover) { .search-toggle:hover, .menu-mobile:hover { background: var(--hover); } }
.menu-mobile { order: 3; }
/* Search and menu toggles: the icon cross-fades to a close icon while the field or menu is open */
.icons { display: grid; }
.icons > .lc { grid-area: 1 / 1; transition-property: opacity, scale, filter; transition-duration: var(--dur); transition-timing-function: var(--ease-out-expo); }
.icons > :is(.i-close, .i-check), [aria-expanded="true"] > .icons > .i-idle, .is-copied > .icons > .i-copy { opacity: 0; scale: 0.25; filter: blur(4px); }
[aria-expanded="true"] > .icons > .i-close, .is-copied > .icons > .i-check { opacity: 1; scale: 1; filter: blur(0); }
.search-toggle .lc, .menu-mobile .lc { width: var(--icon-lg); height: var(--icon-lg); }
.mega-more { display: none; }
/* the header search, in the field look of the select, the text input and the read-only values (control height,
   field radius and field fill) */
.search { position: relative; display: flex; align-items: center; width: 232px; height: var(--h-control); padding: 0 var(--space-2) 0 34px; border: var(--border); border-radius: var(--r-field); background: var(--bg); transition: border-color var(--dur-fast) ease-out; }
/* --fill: the search fills the row it sits in, as the filter field in the head of the directory board */
.search--fill { flex: 1 1 var(--search-fill-min); width: auto; }
.search:focus-within { border-color: var(--ink); }
@media (hover: hover) { .search:hover:not(:focus-within) { border-color: color-mix(in srgb, var(--ink) 30%, var(--line-2)); } }
.search-ico { position: absolute; left: 11px; color: var(--muted); }
.search input { flex: 1; min-width: 0; height: 100%; border: 0; outline: 0; background: transparent; font: inherit; font-size: var(--text-md); color: var(--ink); }
.search input::placeholder { color: var(--muted); }
.search input::-webkit-search-cancel-button { display: none; }
.search kbd { font-family: var(--sans); border: var(--border); border-radius: var(--r-xs); padding: 0 var(--space-1-5); line-height: 20px; }
.search:focus-within kbd { display: none; }
.search-list { position: absolute; top: calc(100% + 6px); left: 0; right: 0; z-index: var(--z-float); padding: var(--space-1); box-shadow: var(--shadow-pop); max-height: 320px; overflow: auto; overscroll-behavior: contain; }
.search-list li { display: flex; align-items: baseline; gap: var(--space-2-5); padding: var(--space-2) var(--space-2-5); border-radius: var(--r); cursor: pointer; font-size: var(--text-sm); }
.search-list li b { min-width: 52px; color: var(--ink); }
.search-list li span { color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.search-list li[aria-selected="true"] { background: var(--bg); }
.search-list .empty { cursor: default; color: var(--muted); }

/* ---------- Hero background: same as adanos.org (gradient + 80px activity grid) ---------- */
.hero-shell, .closing-band { position: relative; overflow: hidden; background: linear-gradient(180deg, var(--bg) 0%, var(--bg-2) 100%); }
/* the hero clips, not hides: a sticky part inside, as the register's plan picture, stays sticky (the band keeps hidden,
   which holds the margin of its last block inside) */
.hero-shell { overflow: clip; }
.hero-shell > .wrap, .closing-band > .wrap { position: relative; z-index: 1; }
.hero-shell { margin-top: calc(-1 * (var(--nav-top) + var(--nav-h))); padding-top: var(--nav-space); }
/* --end: the hero is all of the page above the closing band, as on the register page. It ends on the band's first tone
   and its grid fades out before the band's grid fades in, so no edge shows between them */
.hero-shell--end { background: var(--bg); }
.hero-shell--end .hero { padding-bottom: var(--section-y); }
.hero-shell--end > .hero-grid { -webkit-mask-image: linear-gradient(180deg, #000 70%, transparent); mask-image: linear-gradient(180deg, #000 70%, transparent); }
/* desktop: the homepage's hero (--fill) fills the first view up to 1040px, its content centred in it (as on adanos.org);
   taller windows already show the start of section 2, short windows let the hero grow with its content. Product and
   listing heroes start at the top whatever their height */
@media (min-width: 1025px) {
    .hero-shell--fill { display: flex; flex-direction: column; min-height: min(100vh, 1040px); min-height: min(100svh, 1040px); }
    .hero-shell--fill > .wrap { flex: 1; display: flex; flex-direction: column; justify-content: center; width: 100%; }
}
.hero-grid {
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    overflow: hidden;
    background-image:
        linear-gradient(to right, var(--grid-line) 1px, transparent 1px),
        linear-gradient(to bottom, var(--grid-line) 1px, transparent 1px);
    background-size: var(--grid-cell) var(--grid-cell);
}
.hero-grid-highlight { position: absolute; width: var(--grid-cell); height: var(--grid-cell); background: color-mix(in srgb, var(--gold) 12%, transparent); opacity: 0; animation: heroGridHighlightPulse 18s ease-in-out infinite; }
.hero-grid.is-paused .hero-grid-highlight { animation-play-state: paused; }
@keyframes heroGridHighlightPulse {
    0%, 90%, 100% { opacity: 0; }
    95% { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) { .hero-grid-highlight { animation: none; } }

/* ---------- Hero ---------- */
.hero { padding: var(--space-16) 0 var(--space-10); }
.hero-top { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: var(--space-14); align-items: start; }
/* the first block under the hero's text (its "below" slot: a board, the home demo, a tool, the plans) stands 56px below
   it on every page, 32px on phones; the block's own margin applies where it sits elsewhere */
.hero .hero-top + * { margin-top: var(--space-14); }
/* the plans under a billing switch stand closer, since the switch belongs to them */
.hero[data-billing] .hero-top + * { margin-top: var(--space-8); }
.hero h1 { font-size: var(--text-hero); line-height: var(--lh-tight); letter-spacing: var(--tracking-display); }
/* Fact line above the headline (figures from pricing.html) */
.hero-facts { margin-bottom: var(--space-2); font-size: var(--text-md); color: var(--ink-2); text-wrap: balance; }
.hero .lead { line-height: var(--lh-body); }
/* desktop: the fact line reads like the lead beside it (same size, colour and line height), and both columns start at the top */
@media (min-width: 1025px) {
    .hero-facts { font-size: var(--text-lg); line-height: var(--lh-body); }
}
.hero-actions { display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-3-5) var(--space-6); margin-top: 26px; }
/* Frosted glass tag: the source labels in the feed, the callouts in the use-case views and the recommended plan */
.viz-tag {
    padding: var(--inset-glass);
    border-radius: var(--r);
    font-size: var(--text-xs);
    font-weight: var(--fw-medium);
    color: var(--ink);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    border: 1px solid transparent;
    background: var(--glass-tag);
    -webkit-backdrop-filter: blur(10px) saturate(1.6);
    backdrop-filter: blur(10px) saturate(1.6);
    box-shadow: var(--shadow-glass);
}

/* the post card: the source's tile or the stock's logo, a body with the source and the text, the lean. The hero feed
   flies it (its own feed-post places it), post--static quotes it on a page */
.post {
    display: flex;
    align-items: center;
    gap: var(--space-2-5);
    padding: 7px var(--space-3) 7px 7px;
    box-shadow: var(--shadow-xs);
    font-size: var(--text-sm);
    color: var(--ink-2);
}
/* Stock logo, as on adanos.org/stocks/<ticker>/: the brand icon fills a square with 22% rounded corners,
   an inset hairline keeps white icons visible; the letter fallback shows when the logo cannot load */
.plogo { flex: none; display: grid; place-items: center; width: var(--s, var(--logo-lg)); height: var(--s, var(--logo-lg)); border-radius: var(--r-logo); overflow: hidden; outline: 1px solid transparent; outline-offset: -1px; font-size: max(var(--text-xs), calc(var(--s, var(--logo-lg)) * 0.38)); font-weight: var(--fw-medium); color: var(--ink-2); }
.plogo img { width: 100%; height: 100%; object-fit: contain; }
[data-logo]:empty { flex: none; display: grid; width: var(--s, var(--logo-lg)); height: var(--s, var(--logo-lg)); } /* a logo's placeholder holds the logo's size until the script puts it in */
/* tile-card: a logo or a source tile as a card of its own, square on paper with the card shadow, as the logo tiles of
   the movers hero and the source tiles of the register hero; the logo or the tile inside fills it */
.tile-card { display: grid; aspect-ratio: 1; border-radius: var(--r-logo); overflow: hidden; background: var(--paper); box-shadow: var(--shadow-card); }
.tile-card > .tile { display: block; width: 100%; height: 100%; }
/* app tiles (sprite symbols) take the same sizes as the logos */
.tile { width: var(--s, var(--logo-sm)); height: var(--s, var(--logo-sm)); flex: none; }
/* a size modifier sets --s from the logo scale and --s-step to the next size down, which --step takes on phones */
.plogo--xs, .tile--xs { --s: var(--logo-xs); --s-step: var(--logo-xs); }
.plogo--sm { --s: var(--logo-sm); --s-step: var(--logo-xs); }
.tile--md { --s: var(--logo-md); --s-step: var(--logo-sm); }
.tile--lg { --s: var(--logo-lg); --s-step: var(--logo-md); }
.plogo--xl, .tile--xl { --s: var(--logo-xl); --s-step: var(--logo-lg); }
.plogo--3xl { --s: var(--logo-3xl); --s-step: var(--logo-2xl); }
/* set by the pixel check in site-2026.js: white or see-through icons sit on a white plate with a hairline */
.plogo.is-plate, .plogo.is-fallback { outline-color: var(--logo-ring); }
.plogo.is-plate { background: var(--paper); }
.plogo.is-fallback { background: var(--bg); }
/* disc-shaped icons on a white square (Dell) are cut round, without the hairline */
.plogo.is-round { border-radius: var(--r-round); }
/* ticker identity: the logo, then the ticker over the company name. The :where() parts leave the ticker size to a
   page's type role, as in the article's stock card */
.ident { display: flex; align-items: center; gap: var(--space-2-5); min-width: 0; --s: var(--logo-md); }
.ident > :where(:has(b)) { display: grid; min-width: 0; line-height: var(--lh-title); }
:where(.ident) b { font-size: var(--text-sm); color: var(--ink); }
.ident > * > :where(small, b + span:last-child) { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ident--lg { gap: var(--space-3); --s: var(--logo-lg); }
.ident--lg .plogo { font-size: var(--text-xs); } /* the fallback letter on the scale, not 0.38 of the tile */
.post .pbody { display: flex; flex-direction: column; gap: 1px; line-height: var(--lh-title); }
.post .pmeta b { color: var(--ink); margin-right: var(--space-1-5); }
.post .score { opacity: 0; transition: opacity var(--dur) ease-out; }
.post.scanned .score { opacity: 1; }
/* --static: a quoted post or headline standing still on a page, with its source and its lean */
.post--static { align-items: flex-start; gap: var(--space-3); padding: var(--space-4) var(--space-4) var(--space-4) var(--space-3-5); }
.post--static .pbody { flex: 1; min-width: 0; gap: var(--space-1-5); }
.post--static .pmeta cite { font-style: normal; }
.post--static blockquote { font-size: var(--text-md); line-height: var(--lh-body); color: var(--ink); }
.post--static .score { flex: none; opacity: 1; }
/* --clamp: the source on one line and the quote on three, as at the foot of a source card */
.post--clamp .pmeta { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.post--clamp blockquote { display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; min-height: 3lh; }
.seg { display: inline-flex; padding: 3px; gap: var(--space-0-5); background: var(--bg); border: var(--border); border-radius: var(--r); }
.seg button {
    height: var(--h-control-sm);
    padding: 0 var(--space-2-5);
    white-space: nowrap;
    border-radius: calc(var(--r) - 3px); /* concentric with the 3px inset */
    font-size: var(--text-xs);
    color: var(--ink-2);
    transition: background-color var(--dur-fast) ease-out;
}
.seg button[aria-pressed="true"] { background: var(--raised); color: var(--ink); box-shadow: 0 0 0 1px var(--raised-edge); }
@media (hover: hover) { .seg button:hover { color: var(--ink); } }
/* seg--field: a tray in a row of fields, as tall as the search and the selects beside it, with their radius and the
   selects' text size (owner, 2026-10-29); the buttons fill the height inside the 3px inset and the border, their radius
   concentric with the tray's */
.seg--field { border-radius: var(--r-field); }
.seg--field button { height: calc(var(--h-control) - 2 * (3px + 1px)); border-radius: calc(var(--r-field) - 3px - 1px); font-size: var(--text-sm); }
/* big figures: display weight, tight figure spacing; the gold ones clip the brand gradient */
/* big figures: the count or score a band, a card or a panel leads with; xl and lg step down one size on phones */
.fig { font-size: var(--text-5xl); font-weight: var(--fw-display); line-height: var(--lh-figure); letter-spacing: var(--tracking-figure); font-variant-numeric: tabular-nums; color: var(--ink); }
.fig--xl { font-size: var(--text-7xl); }
.fig--lg { font-size: var(--text-6xl); }
.fig--sm { font-size: var(--text-3xl); }
.fig--gold { background: var(--gold-gradient); -webkit-background-clip: text; background-clip: text; color: transparent; }

/* stats: a label over a figure in equal columns, three unless the page sets --cols */
.stats { display: grid; grid-template-columns: repeat(var(--cols, 3), minmax(0, 1fr)); gap: var(--space-4); }
.stats dd { margin-top: var(--space-0-5); font-size: var(--text-xl); font-weight: var(--fw-medium); letter-spacing: var(--tracking-title); color: var(--ink); font-variant-numeric: tabular-nums; }
/* key-value rows: a label and its value on each row, a hairline between the rows. --split sets a figure at the end of
   its label; --cols puts the term in a column beside a value that runs as text, and on phones the text under it;
   --text sets the rows in the size and rhythm of the running text around them */
.kv > * { padding-block: var(--space-1-5); font-size: var(--text-sm); line-height: var(--lh-body); color: var(--ink-2); }
.kv > * + * { border-top: var(--divider); }
/* the figure: a b in any row, the dd of a split row, which wraps flush right */
.kv :is(b, .kv--split dd) { color: var(--ink); font-variant-numeric: tabular-nums; }
.kv--split > * { display: flex; justify-content: space-between; gap: var(--space-3); }
.kv--split dd { text-align: right; }
.kv--cols > * { display: grid; grid-template-columns: minmax(0, var(--label-col)) minmax(0, 1fr); gap: var(--space-1) var(--space-3); }
.kv--cols dt { font-weight: var(--fw-medium); color: var(--ink); }
.kv--text { --label-col: var(--label-col-text); }
.kv--text > * { padding-block: var(--space-4); column-gap: var(--space-6); font-size: inherit; line-height: inherit; color: inherit; }
.kv--text dt { line-height: var(--lh-title); }

/* JSON views (response card and endpoint explorer) */
.ep-json { padding: var(--inset-code) var(--pad); overflow: auto; overscroll-behavior: contain; white-space: pre-wrap; overflow-wrap: anywhere; color: var(--code-body); }

/* Customer logos: an endless row beside the use-case headline, over the stage column.
   The track holds the set twice and slides by half its width, so the loop is seamless;
   each logo carries its gap as a right margin. */
/* endless rows (logos, coverage river, ticker tape): the track holds the set twice and slides by half its width */
.sub-track { display: flex; width: max-content; }
.sub-track > .plogo { margin-right: var(--space-3); }
.sub-track > .chip { margin-right: var(--space-2); }
.sub-river { -webkit-mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent); mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent); }
@keyframes marquee { to { translate: -50% 0; } }
/* heights balance each logo to roughly the same visual area */
img[data-brand="openai"] { height: calc(26px * var(--logo-scale)); }
img[data-brand="google"] { height: calc(30px * var(--logo-scale)); }
img[data-brand="alibaba"] { height: calc(17px * var(--logo-scale)); }
img[data-brand="mit"] { height: calc(30px * var(--logo-scale)); }
img[data-brand="harvard"] { height: calc(29px * var(--logo-scale)); }
img[data-brand="columbia"] { height: calc(24px * var(--logo-scale)); }
@media (prefers-reduced-motion: no-preference) {
    .sub-track { animation: marquee var(--loop) linear infinite; }
    .is-paused .sub-track { animation-play-state: paused; }
}
/* the logo row: --logo-scale sizes the whole row, the heights above keep the logos balanced to each other; grey
   until the pointer is on one */
.logo-marquee { --logo-scale: 1.4; min-width: 0; overflow: hidden; }
.logo-set { display: flex; align-items: center; height: calc(var(--space-10) * var(--logo-scale)); }
.logo-set img { flex: none; width: auto; margin-right: calc(var(--space-14) * var(--logo-scale)); filter: grayscale(1); opacity: 0.7; transition: filter var(--dur-fast) ease-out, opacity var(--dur-fast) ease-out; }
@media (hover: hover) { .logo-set img:hover { filter: grayscale(0); opacity: 1; } }
@media (prefers-reduced-motion: no-preference) {
    .logo-track { --loop: 36s; }
    @media (hover: hover) { .logo-marquee:hover .logo-track { animation-play-state: paused; } }
}
/* reduced motion: one static set that wraps */
@media (prefers-reduced-motion: reduce) {
    .logo-marquee { -webkit-mask-image: none; mask-image: none; }
    .logo-track, .logo-set { width: auto; height: auto; flex-wrap: wrap; row-gap: var(--space-4); }
    .logo-set[aria-hidden] { display: none; }
}

/* ---------- Sections ---------- */
section.block { padding: var(--section-y) 0; border-top: var(--divider); }
.block-head { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); gap: var(--space-14); align-items: end; margin-bottom: var(--space-12); }
/* the padding is the same above and below; the space a heading's line box keeps above its capitals
   would make the top look larger, so the first heading starts at its cap height */
.block-head h2 { text-box: trim-start cap alphabetic; }
.block-head > .textlink { justify-self: end; } /* the link to the whole series, where other heads have their lead */

/* Chart parts shared by the use-case views and the stock dashboard */
/* legend: one key per series, its mark before its label. A line by default, .dot or .bar for the other marks, a tone
   or the series' own class for its colour; --sm is the key under a graphic, set like its axis */
.legend { display: flex; gap: var(--space-2) var(--space-5); flex-wrap: wrap; }
/* the type of a key beside its graphic; :where() lets the meta role of a key under a graphic win */
:where(.legend) { font-size: var(--text-sm); color: var(--ink-2); }
.legend--sm { margin-top: var(--space-2); }
.legend span { display: inline-flex; align-items: center; gap: var(--space-2); }
.legend i { width: var(--space-4); height: var(--indicator); background: var(--signal); }
.legend i.dot { width: var(--dot); height: var(--dot); border-radius: var(--r-round); }
.legend i.bar { width: var(--dot); height: var(--bar-lg); background: var(--line-2); }
.legend i.pos { background: var(--bull); }
.legend i.neu { background: var(--line-2); }
.legend i.neg { background: var(--bear); }
.legend i.gold { background: var(--code-gold); }
.legend i.mixed { background: var(--marker); }
/* axis: the labels under a chart or a scale, the first at the left edge and the last at the right; --ticks puts each
   label at its value (--x from 0 to 1) */
.axis { display: flex; justify-content: space-between; margin-top: var(--space-2); font-variant-numeric: tabular-nums; }
.axis--ticks { position: relative; display: block; height: calc(var(--text-xs) * var(--lh-body)); }
.axis--ticks span { position: absolute; left: calc(var(--x) * 100%); translate: -50% 0; white-space: nowrap; }
.axis--ticks span:first-child { translate: 0 0; }
.axis--ticks span:last-child { translate: -100% 0; }
/* a figure in a key or in an axis label stands out in ink */
:is(.legend span, .axis) b { color: var(--ink); }
/* Marks drawn by the SVG builders (buzz chart, sparkline, DELL chart) */
.ch-grid { stroke: var(--line-soft); }
.ch-base { stroke: var(--line-2); }
.ch-area stop { stop-color: var(--code-gold); stop-opacity: 0; }
.ch-area stop:first-child { stop-opacity: 0.34; }
.ch-buzz { stroke: var(--signal); stroke-width: 2.25; stroke-linejoin: round; stroke-linecap: round; }
.ch-dot { fill: var(--signal); }
/* Buzz meter: a 6px track, the reading drawn as a --w wide signal bar */
.meter { display: block; height: var(--bar); border-radius: var(--r-pill); background: var(--line); overflow: hidden; }
.meter i { display: block; width: var(--w); height: 100%; border-radius: inherit; background: var(--signal); transform-origin: 0 50%; }
/* gold variant for rankings: the bar glides to the new reading */
.meter--gold { background: var(--line-soft); }
.meter--gold i { background: var(--gold-gradient); transition: width var(--dur-slow) var(--ease-out-expo); }
/* center: a signed value from the middle of the track in the colour of the meter's trend class, a tick at zero; --x is
   where it starts */
.meter--center { position: relative; overflow: visible; }
.meter--center::before { content: ""; position: absolute; left: 50%; top: 50%; width: 1px; height: calc(2 * var(--bar)); translate: 0 -50%; background: var(--line-2); }
.meter--center i { position: absolute; top: 0; left: var(--x); background: currentColor; }
/* split: the shares of one whole side by side, a tone or the source's class per part; --center grows the bearish
   share left of the middle and the bullish share right, the bare track neutral */
.split { display: flex; height: var(--bar); border-radius: var(--r-xs); overflow: hidden; background: var(--line); }
.split i { transition: width var(--dur) ease-out; }
.split .pos { background: var(--bull); }
.split .neu { flex: 1; }
.split .neg { background: var(--bear); }
.split--center { position: relative; display: block; }
.split--center i { position: absolute; top: 0; bottom: 0; width: var(--w); }
.split--center .neg { right: 50%; border-radius: var(--r-xs) 0 0 var(--r-xs); transform-origin: 100% 50%; }
.split--center .pos { left: 50%; border-radius: 0 var(--r-xs) var(--r-xs) 0; transform-origin: 0 50%; }
.split--center::after { content: ""; position: absolute; top: 0; bottom: 0; left: 50%; width: 1px; background: var(--line-2); }
/* marker: a reading on a scale, centred at --v percent along its parent; slate, or the tone of a bullish or bearish
   reading; a b inside sets the figure above it */
.sp-dot { position: absolute; z-index: 1; top: 50%; left: calc(var(--v) * 1%); width: var(--space-3-5); height: var(--space-3-5); translate: -50% -50%; border-radius: var(--r-round); border: 2px solid var(--paper); background: var(--marker); box-shadow: var(--shadow-dot); }
.sp-dot.pos { background: var(--bull); }
.sp-dot.pos-soft, .legend i.pos-soft { background: color-mix(in srgb, var(--bull) 55%, var(--paper)); }
.sp-dot.neg { background: var(--bear); }
.sp-dot b { position: absolute; left: 50%; bottom: 100%; translate: -50% -5px; font-size: var(--text-xs); font-style: normal; color: var(--ink); font-variant-numeric: tabular-nums; white-space: nowrap; }

/* ---------- Use cases: tabs left, one stage with four live views right ---------- */
@property --v { syntax: '<number>'; inherits: true; initial-value: 50; }
@property --lo { syntax: '<number>'; inherits: true; initial-value: 50; }
@property --hi { syntax: '<number>'; inherits: true; initial-value: 50; }
/* the use-case header shares the case grid, so the logos line up with the stage below */
.block-head--cases { display: grid; grid-template-columns: minmax(0, 4fr) minmax(0, 7fr); gap: var(--space-10); }
/* the logos sit centred beside the headline, as proof of who builds with the data */
.block-head--cases .logo-marquee { align-self: center; }

/* ---------- Case tabs: tabs in a column beside one stage of views ---------- */
.cases { display: grid; grid-template-columns: minmax(0, 4fr) minmax(0, 7fr); gap: var(--space-10); }
.case-list { display: flex; flex-direction: column; border-top: var(--border); }
.case-tab { position: relative; display: grid; gap: var(--space-1); padding: var(--space-5) 0 22px; text-align: left; border-bottom: var(--divider); }
/* text roles as everywhere else: --ink-2 for everything that is read, --ink marks the chosen tab */
.case-who { font-size: var(--text-xs); color: var(--ink-2); }
.case-tab b { color: var(--ink-2); transition: color var(--dur-fast) ease-out; }
.case-tab[aria-selected="true"] b { color: var(--ink); }
@media (hover: hover) { .case-tab:hover b { color: var(--ink); } }
/* every text stays in view, so a switch never shifts the list */
.case-more { font-size: var(--text-md); color: var(--ink-2); }
/* the progress of the tour under the chosen tab; a full line once the visitor takes over */
.case-progress { position: absolute; left: 0; right: 0; bottom: -1px; height: var(--indicator); background: var(--ink); transform-origin: 0 50%; scale: var(--p, 0) 1; opacity: 0; }
.case-tab[aria-selected="true"] .case-progress { opacity: 1; }
.cases.is-manual .case-tab[aria-selected="true"] .case-progress { scale: 1 1; }

.case-stage { display: grid; grid-template-columns: minmax(0, 1fr); grid-template-rows: minmax(0, 1fr); min-width: 0; overflow: hidden; }
/* side by side, the list sets the height: the stage ignores its own content size and every view fits inside */
@media (min-width: 1025px) { .case-stage { contain: size; } }
/* views longer than the list (cases--fit, the CLI shell's sessions) set the stage's height beside it too */
@media (min-width: 1025px) { .cases--fit .case-stage { contain: none; } }
.case-panel { --pad: var(--pad-lg); grid-area: 1 / 1; display: flex; min-width: 0; min-height: 0; padding: var(--pad); visibility: hidden; opacity: 0; transition: opacity var(--dur-fast) ease-out, visibility 0s linear var(--dur-fast); }
.case-panel.is-active { visibility: visible; opacity: 1; transition: opacity var(--dur-fast) ease-out; }
.case-panel > * { flex: 1; min-width: 0; min-height: 0; display: flex; flex-direction: column; }
/* a code panel as the view is dark to the edges and pads its own parts with --pad */
.case-panel:has(> .ep-out) { padding: 0; }
/* a view's caption is the box foot: it reaches out of the padded view to the edges of the stage */
.viz-note { margin: auto calc(-1 * var(--pad)) calc(-1 * var(--pad)); }
.viz-note b { color: var(--ink); }

/* boxes: paper, the box edge and the box radius */
.panel { background: var(--paper); border: var(--border); border-radius: var(--r-box); }
/* a box on a dark band takes the band's card fill; its edge and its text switch with on-dark. The fill lifts the
   ground, so muted text steps up to --ink-2 to keep 4.5:1 (--dark-muted reaches 4.1:1 on it) */
.on-dark .panel { --muted: var(--ink-2); background: var(--dark-fill-soft); }
/* a body fills the rest of its box and stacks its content, so boxes of one row fill the row's height to their foot;
   a box whose component sets its own direction (the why card) keeps it */
:where(.panel):has(> .box-body) { display: flex; flex-direction: column; }
.panel > .box-body { display: flex; flex-direction: column; flex: 1; }
/* box head: a band over the content of a box, edge to edge, with a rule under it: a title or a pick on the left,
   more picks on the right */
.box-head { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: var(--space-3); padding: var(--space-2-5) var(--space-2-5) var(--space-2-5) var(--pad); border-bottom: var(--divider); }
/* a window's title bar: three dots and a name on the box edge */
.box-head--chrome { justify-content: flex-start; gap: var(--space-1-5); padding: var(--space-2) var(--space-2-5); border-bottom: var(--border); }
.box-head--chrome > i { width: var(--dot); height: var(--dot); border-radius: var(--r-round); background: var(--wire); }
.box-head--chrome > span { margin-left: var(--space-1-5); }
/* box foot: a band under the content of a box, edge to edge, with a rule on top and the sunk fill: a status, the call
   behind the box or a note on the left, a link or a button on the right */
.box-foot { display: flex; justify-content: space-between; align-items: center; gap: var(--space-3); padding: var(--space-2-5) var(--pad); border-top: var(--divider); background: var(--sunk); }
.box-foot > :is(p, span) { font-variant-numeric: tabular-nums; }
/* a data view without an API answer: one line in place of its data, with the way to ask again */
.box-err { display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-2) var(--space-3); padding: var(--space-6) var(--pad); font-size: var(--text-md); color: var(--ink-2); }
.box-err .lc { color: var(--muted); }
.box-err .textlink { margin-left: auto; }
/* a grey placeholder in the shape of data that is still loading; text inside keeps its line but does not show.
   An empty one is a bar as wide as --w */
.skel { border-radius: var(--r); background: linear-gradient(90deg, var(--line) 0%, var(--line-soft) 50%, var(--line) 100%); background-size: 200% 100%; color: transparent; }
.skel:empty { display: block; width: var(--w, 100%); max-width: 100%; height: var(--space-3); }
.kv--split .skel:empty { display: inline-block; vertical-align: middle; } /* a waiting row of a list keeps the height of its line */
@media (prefers-reduced-motion: no-preference) { .skel { animation: shimmer 1.4s linear infinite; } @keyframes shimmer { to { background-position: -200% 0; } } }
.box-foot > code { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--text-xs); color: var(--ink-2); }
.box-foot > code b { margin-right: var(--space-2); font-weight: var(--fw-regular); color: var(--signal-ink); }
.box-foot .textlink { flex: none; font-size: var(--text-sm); }
.board-more { flex: none; font-size: var(--text-sm); color: var(--ink-2); } /* "See more:" before the link to the full ranking */
.box-foot--note { display: block; font-size: var(--text-sm); color: var(--ink-2); text-wrap: pretty; }
/* the board draws no clip, so its foot rounds its own corners */
/* the foot band closes its box with the box's own corners */
.board > .box-foot, .panel > .box-foot:last-child { border-radius: 0 0 calc(var(--r-box) - 1px) calc(var(--r-box) - 1px); }
/* title row: a title at the start of a box, a view or a section, a tag right beside it and a note, a key, a pick
   or a link at the end */
.viz-head { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: var(--space-3) var(--space-4); }
.viz-head > .tag { margin-right: auto; }
.viz-head > .textlink { font-size: var(--text-sm); }
/* label row: a tag beside a short text on one line */
.tip-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
/* list foot: the same row outside a band, under a list, a card or a view: a rule on top, a status or a text on the
   left, a link, a button or a pick on the right */
.list-foot { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: var(--space-3); margin-top: var(--space-6); padding-top: var(--space-4); border-top: var(--divider); }
.list-foot > :is(p, span) { font-variant-numeric: tabular-nums; }
.list-foot .textlink { flex: none; font-size: var(--text-sm); }
.list-foot p > .textlink { font-size: inherit; } /* a link inside a sentence of the foot keeps its size */
/* notice: a note the reader must not miss, its icon before its text: gold for a caution (the personal use of Hobby, the
   key that shows once), --bull green for a good fact (Professional's commercial license) */
.notice { display: flex; align-items: flex-start; gap: var(--space-3); padding: var(--space-4); border: 1px solid color-mix(in srgb, var(--gold) 45%, transparent); border-radius: var(--r-box); background: color-mix(in srgb, var(--gold-light) 30%, var(--paper)); font-size: var(--text-sm); line-height: var(--lh-body); color: var(--ink-2); }
.notice > .lc { flex: none; width: var(--icon-lg); height: var(--icon-lg); color: var(--signal-ink); }
.notice strong { color: var(--ink); }
.notice--bull { border-color: color-mix(in srgb, var(--bull) 30%, transparent); background: color-mix(in srgb, var(--bull) 6%, var(--paper)); }
.notice--bull > .lc { color: var(--bull-ink); }
/* sent state: what a form shows once it is sent; a letter drops into its envelope, then the green check turns up */
.sent-state { display: grid; justify-items: start; gap: var(--space-4); }
.sent-state:focus { outline: none; } /* focused by the script so a screen reader reads it, not by the reader */
.sent-art { width: 120px; height: 100px; overflow: visible; }
.sent-env, .sent-letter rect, .sent-front { stroke: var(--line-2); stroke-width: 1.5; stroke-linejoin: round; }
.sent-env { fill: var(--bg); }
.sent-letter rect, .sent-front { fill: var(--paper); }
.sent-letter path { fill: none; stroke: var(--line-2); stroke-width: 3; stroke-linecap: round; }
.sent-ok circle { fill: var(--bull); }
.sent-ok path { fill: none; stroke: var(--paper); stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; }
.sent-ok { transform-box: fill-box; transform-origin: center; }
@media (prefers-reduced-motion: no-preference) {
    .sent-state:not([hidden]) .sent-letter { animation: sent-letter var(--dur-slow) var(--ease-out-expo) both; }
    .sent-state:not([hidden]) .sent-ok { animation: sent-ok var(--dur) var(--ease-out-expo) var(--dur-slow) both; }
}
@keyframes sent-letter { from { opacity: 0; translate: 0 -40px; } }
@keyframes sent-ok { from { opacity: 0; scale: 0.25; filter: blur(4px); } }
/* the track is the size container of its dot and stem, so both move by translate and scale in cqw and a reading that
   glides needs no layout in each frame */
.sp-track { position: relative; container-type: inline-size; }
.sp-track > .sp-dot { left: 0; translate: calc(var(--v) * 1cqw - 50%) -50%; }
.sp-track::before { content: ''; position: absolute; left: 0; right: 0; top: 50%; height: 1px; background: var(--line); }
/* stem from the start of the scale to the reading: the neutral middle by default, --from where the scale starts
   elsewhere (the column guide's field sets 0 for a score) */
.sp-track::after { content: ''; position: absolute; top: 50%; left: 0; width: 100%; height: var(--bar); margin-top: calc(var(--bar) / -2); transform-origin: 0 50%; translate: calc(min(var(--v), var(--from, 50)) * 1cqw) 0; scale: calc((max(var(--v), var(--from, 50)) - min(var(--v), var(--from, 50))) / 100) 1; background: var(--line-2); }
.sp-track.is-soon::before { background: none; border-top: var(--dashed); }
.sp-track.is-soon::after { content: none; }

/* code panel: the dark panel of a response, a request, a terminal or a file, with a box head on top and the code
   under it (the agent session of the use cases, the explorer, the question figures, the bento and the article) */
.ep-out { display: flex; flex-direction: column; min-width: 0; background: var(--dark); color: var(--dark-body); }
.trend-up { color: var(--bull); }
.trend-down { color: var(--bear); }

/* Motion runs once per view; without it every view shows its final state */
.no-tx, .no-tx * { transition: none !important; }
@media (prefers-reduced-motion: no-preference) {
    .sp-track { transition: --v var(--dur-glide) var(--ease-out-expo); }
    .sp-dot { transition: background-color var(--dur) ease-out; }
    @keyframes lv-ring { from { opacity: 0.8; scale: 1; } to { opacity: 0; scale: 3.2; } }
}

/* Sources and endpoints: a source bar over the endpoint list and the dark response panel */
.explorer { display: grid; grid-template-columns: minmax(0, 4fr) minmax(0, 7fr); overflow: clip; } /* clip keeps a sticky part inside sticky */
/* tabs: a row of labels over the view they switch; the chosen one (aria-selected, or aria-pressed where the row is
   a group of toggles) reads in ink with the indicator under its label; --lg for the 15px sources with their tiles */
.tabs { display: flex; min-width: 0; overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: none; }
.tabs button { position: relative; flex: none; display: inline-flex; align-items: center; gap: var(--space-2); padding: var(--space-3) var(--tab-x); font-size: var(--text-sm); color: var(--ink-2); white-space: nowrap; transition: color var(--dur-fast) ease-out; }
.tabs button:is([aria-selected="true"], [aria-pressed="true"]) { color: var(--ink); }
.tabs button:is([aria-selected="true"], [aria-pressed="true"])::after, .ep[aria-selected="true"]::after { content: ""; position: absolute; left: var(--tab-x); right: var(--tab-x); bottom: 0; height: var(--indicator); background: var(--ink); }
@media (min-width: 1025px) { .ep[aria-selected="true"]::after { content: none; } }
@media (hover: hover) { .tabs button:not(:disabled):hover, .ep:hover .p { color: var(--ink); } }
.tabs button:disabled { cursor: default; color: var(--muted); }
.tabs button:disabled .tile { opacity: 0.5; }
.tabs--lg button { gap: var(--space-2-5); padding-block: var(--space-4); font-size: var(--text-md); font-weight: var(--fw-medium); }
.src-tabs { grid-column: 1 / -1; padding-inline: calc(var(--pad) - var(--tab-x)); border-bottom: var(--divider); }
.src-tabs .tile { --s: var(--logo-sm); }
/* our own text model is not a source, so it sits apart at the end of the row */
.src-tabs .src-own { margin-left: auto; }
/* small status tags: "Soon" on a source, "PRO" on an endpoint */
/* filled tags: a status, a tone or a count beside a name or a figure; neutral by default, dark inside .on-dark */
.tag { padding: var(--inset-tag); border-radius: var(--r-xs); font-size: var(--text-xs); font-weight: var(--fw-regular); line-height: var(--lh-body); font-variant-numeric: tabular-nums; white-space: nowrap; background: var(--tint-neutral); color: var(--neutral-ink); }
.tag--bull { background: var(--tint-bull); color: var(--bull-ink); }
.tag--bear { background: var(--tint-bear); color: var(--bear-ink); }
.tag--gold { background: var(--tint-gold); color: var(--gold-ink); }
.tag--lg { padding: var(--space-1) var(--space-2-5); font-size: var(--text-md); font-weight: var(--fw-medium); }
/* a badge on a card's edge: 24px tall with its text centred by the box, not the line (1px lower for Inter's high
   centre), and the body's tracking even inside a title. It rests on the edge with the tile shadow; the transparent
   border keeps an edge in forced colours */
.tag--ink { display: inline-flex; align-items: center; height: var(--space-6); padding: 1px var(--space-2-5) 0; border: 1px solid transparent; border-radius: var(--r-pill); background: var(--ink); box-shadow: var(--shadow-tile); color: var(--paper); font-weight: var(--fw-medium); line-height: 1; letter-spacing: normal; }
.tag--edge { position: absolute; top: 0; left: 50%; translate: -50% -50%; } /* the ink tag on the middle of a positioned card's top edge */
.ep-side { display: flex; flex-direction: column; min-width: 0; border-right: var(--divider); }
.ep-list { padding-inline: var(--pad); }
/* what the chosen source reads */
.src-info { display: grid; margin-top: auto; padding: 18px var(--pad); border-top: var(--divider); font-size: var(--text-md); color: var(--ink-2); }
.src-info > div { grid-area: 1 / 1; }
.src-info > div:not(.is-current) { visibility: hidden; }
.src-info p { margin-bottom: var(--space-2-5); }
/* dividers across the text column, --ink-2 text, the chosen endpoint in --ink; on desktop a gold › appears in front
   of it like a cursor and the path moves in to make room (the tab row below 1025px keeps an underline) */
.ep { position: relative; display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); width: 100%; text-align: left; padding: var(--space-2-5) 0; border-bottom: var(--divider); }
/* no divider under the last endpoint the tab shows */
.ep-list li:not(:has(~ li:not([hidden]))) .ep { border-bottom: 0; }
.ep .p { font-family: var(--mono); font-size: var(--text-md); line-height: var(--lh-title); color: var(--ink-2); transition: color var(--dur-fast) ease-out; }
.ep .p span { color: var(--muted); }
.ep[aria-selected="true"] .p { color: var(--ink); }
/* the chosen item of a vertical list (endpoints, contents, the filters beside a board): a gold ›; the endpoint path
   moves in to make room */
.ep::before, .toc a::before, .board-side li > button::before { content: "\203A"; content: "\203A" / ""; position: absolute; top: 50%; left: 0; translate: 0 -50%; font-family: var(--mono); font-size: var(--text-md); color: var(--gold); opacity: 0; transition: opacity var(--dur-fast) ease-out; }
.toc a::before { left: calc(-1 * var(--space-4)); font-family: var(--sans); } /* Inter has the glyph: content pages need no mono for one character */
.board-side li > button::before { left: calc(-1 * var(--space-3)); font-family: var(--sans); font-size: inherit; }
.ep[aria-selected="true"]::before, .toc a[aria-current]::before, .board-side li > button[aria-pressed="true"]::before { opacity: 1; }
.ep[aria-selected="true"] .p { translate: var(--space-4) 0; }
@media (prefers-reduced-motion: no-preference) {
    .ep::before, .toc a::before, .board-side li > button::before { translate: calc(-1 * var(--space-1-5)) -50%; transition-property: opacity, translate; }
    .ep[aria-selected="true"]::before, .toc a[aria-current]::before, .board-side li > button[aria-pressed="true"]::before { translate: 0 -50%; }
    .ep .p { transition-property: color, translate; }
}
/* the request line of a code panel: the call in mono with its method in gold */
.ep-req { font-family: var(--mono); font-size: var(--text-xs); }
.ep-req code { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--paper); }
.ep-req .m { color: var(--code-gold); margin-right: var(--space-2); }
/* buttons in the dark bars are labels: Inter, also inside the mono request bar */
.ep-out .copy { flex: none; display: inline-flex; font-family: var(--sans); align-items: center; gap: var(--space-2); height: var(--h-control-sm); padding: 0 var(--space-2-5); border-radius: var(--r); font-size: var(--text-xs); color: var(--ink-2); transition-property: background-color, color, scale; transition-duration: var(--dur-fast); transition-timing-function: ease-out; }
@media (hover: hover) { .ep-out .copy:hover { background: var(--dark-line); color: var(--paper); } }
.copy .i-check { color: var(--signal); }
.ep-out .copy .i-check { color: var(--code-gold); }
/* side by side, the panel keeps one height for every tab; the response scrolls inside */
@media (min-width: 1025px) {
    .explorer { grid-template-rows: auto 512px; } /* room for the list and a three-line source note at 1025px */
    .explorer > .ep-out { contain: size; }
}
.ep-out .ep-json { flex: 1; min-height: 0; }
:is(.ep-json, .ep-code) .k { color: var(--ink-2); }
:is(.ep-json, .ep-code) .s { color: var(--code-string); }
:is(.ep-json, .ep-code) .n { color: var(--signal-ink); }
.ep-json .b { color: var(--bull-ink); }

/* ---------- Agent session (dark): an agent asks, calls adanos, reads the output and answers with a card ----------
   the home page's use cases and the CLI page's hero; src/scripts/agent-session.ts renders and plays it */
/* both sessions share one cell, so the body always has the height of the longer one */
.ag-body { flex: 1; min-width: 0; min-height: 0; display: grid; grid-template-columns: minmax(0, 1fr); padding: var(--space-4) var(--pad); overflow-y: auto; overscroll-behavior: contain; }
.ag-session { grid-area: 1 / 1; display: grid; gap: var(--space-2-5); align-content: start; min-width: 0; }
.ag-session:not(.is-current) { visibility: hidden; }
.ag-user { justify-self: end; max-width: 80%; padding: var(--space-2) var(--space-3); border-radius: var(--r); background: var(--dark-line); font-size: var(--text-md); color: var(--paper); }
.ag-who { display: block; margin-bottom: var(--space-1); font-size: var(--text-xs); color: var(--muted); }
.ag-call code { font-family: var(--mono); font-size: var(--text-xs); color: var(--code-gold); }
.ag-out { min-width: 0; overflow-x: auto; overscroll-behavior-x: contain; color: var(--ink-2); }
.ag-out span { display: block; }
.ag-reply { font-size: var(--text-md); color: var(--paper); }
/* the answer as a small card: one row per stock or per source */
/* the rows share the card's columns (subgrid), so a long name widens its column in every row and the meters start level */
.ag-card { display: grid; grid-template-columns: minmax(122px, auto) minmax(0, 1fr) 40px 92px; column-gap: var(--space-3); padding: var(--space-0-5) var(--space-3-5); border: var(--border); border-radius: var(--r-box); background: var(--bg); }
.ag-row { grid-column: 1 / -1; display: grid; grid-template-columns: subgrid; align-items: center; padding: 5px 0; }
.ag-row + .ag-row { border-top: 1px solid var(--dark-line); }
.ag-num { text-align: right; font-size: var(--text-sm); color: var(--paper); font-variant-numeric: tabular-nums; }
.ag-row > :last-child { justify-self: end; }
@media (prefers-reduced-motion: no-preference) {
    .ag .ag-line { opacity: 0; translate: 0 12px; filter: blur(4px); }
    .ag.is-playing .ag-line { opacity: 1; translate: none; filter: none; transition-property: opacity, translate, filter; transition-duration: var(--dur); transition-timing-function: ease-out; transition-delay: var(--t); }
    .ag .meter i { scale: 0 1; }
    .ag.is-playing .meter i { scale: 1 1; transition: scale var(--dur-slow) var(--ease-out-expo) var(--t); }
}
@media (max-width: 768px) {
    .ag-card { grid-template-columns: minmax(0, 1fr) 36px auto; column-gap: var(--space-2-5); }
    .ag-row .meter { display: none; }
}

/* ---------- Agent wires (dark): agent chips wired into the session under them ----------
   the home page's CLI tile and the CLI page's agents band; src/scripts/agent-wires.ts draws the wires */
.cli-agents { position: relative; display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--space-2-5); margin-top: var(--space-1-5); padding-bottom: 30px; }
.cli-agent { position: relative; z-index: 1; }
.cli-ic { display: grid; place-items: center; width: var(--s); height: var(--s); border-radius: var(--r-logo); background: var(--dark-line); }
.cli-wires { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
.cli-wires path { fill: none; stroke: var(--dark-edge); stroke-width: 1; }
.cli-wires path.flow { stroke: var(--code-gold); stroke-dasharray: 3 11; }
@media (prefers-reduced-motion: no-preference) {
    .cli-wires path.flow { animation: cli-flow 1.1s linear infinite; }
    .is-paused .cli-wires path.flow { animation-play-state: paused; }
}
@keyframes cli-flow { to { stroke-dashoffset: -14; } }

/* ---------- Mood band (dark): retail crowd and smart money on one fear-greed scale ---------- */
/* the smart money key in the silver of its marker */
.legend i.smart { background: var(--silver); }

/* ---------- Tools bento: CLI for agents, ticker database, widgets, rankings, insights ---------- */
.trend-flat { color: var(--muted); }
.points--grid > li > b a { transition: color var(--dur-fast) ease-out; }
@media (hover: hover) { .points--grid > li > b a:hover { color: var(--signal-ink); } }

/* ---------- Closing + footer ---------- */
/* the dark context of bands, tiles and panels: every role token switches to its dark value, so leads, links, lines,
   tints, status inks, focus rings and logo rings follow without a dark twin. It paints graphite only where the element
   paints nothing itself (a code panel keeps --dark, the footer --dark-deep) */
.on-dark { --border: 1px solid var(--dark-edge); --divider: 1px solid var(--line); --dashed: 1px dashed var(--line-2); --dots: radial-gradient(circle closest-side, color-mix(in srgb, var(--dark-muted) 80%, transparent) 72%, transparent) 0 100% / 4px 2px space no-repeat; --ink: var(--paper); --ink-2: var(--silver); --muted: var(--dark-muted); --line: var(--dark-line); --line-soft: var(--dark-line); --line-2: var(--dark-line-2); --bg: var(--dark-fill-soft); --hover: var(--dark-line); --press: var(--dark-edge); --signal-ink: var(--code-coral); --bull: var(--dark-bull); --bear: var(--dark-bear); --bull-ink: var(--dark-bull); --bear-ink: var(--dark-bear); --tint-bull: var(--dark-tint-bull); --tint-bear: var(--dark-tint-bear); --tint-neutral: var(--dark-line); --neutral-ink: var(--silver); --gold-ink: var(--code-gold); --marker: var(--paper); --chip-bg: var(--dark); --code-body: var(--dark-body); --code-string: var(--code-gold); --code-comment: var(--dark-comment); --sunk: var(--dark-sunk); --raised: var(--dark-edge); --raised-edge: transparent; --wire: var(--dark-edge); --logo-ring: transparent; }
:where(.on-dark) { background: var(--graphite); color: var(--paper); }
.on-dark :is(h2, h3) { color: var(--ink); }
.block.on-dark { border-top: 0; }
/* Closing CTA: calm, on the page background; the dark footer below carries the gold edge */
/* no rule above: the gradient and the grid fade in from the page background */
.closing-band > .hero-grid { -webkit-mask-image: linear-gradient(180deg, transparent, #000 55%); mask-image: linear-gradient(180deg, transparent, #000 55%); }
/* a content section on the same grid (pricing on the product pages): plain lines edge to edge, no fade, no pulse */
.block--grid { position: relative; overflow: hidden; }
.block--grid > .wrap { position: relative; z-index: 1; }
/* no padding of its own on top: the section above ends with the section padding, so the band starts one --section-y
   under the last content, like every section */
.closing { padding: 0 0 var(--space-12); display: grid; grid-template-columns: minmax(0, 1fr) 260px; align-items: center; gap: var(--space-12); }
.closing h2 { font-size: var(--text-5xl); max-width: 13em; }
.closing .lead { margin-top: var(--space-4); }
.closing-cta { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); margin-top: var(--space-8); }
/* a text link after the button keeps the hero's distance to it */
.closing-cta:has(> .textlink) { gap: var(--space-5) var(--space-6); } /* wrapped under the button on a phone, the link keeps 20px to it */
/* the product pages close with a band for teams: what Enterprise adds as a short list with gold checks; with no points
   under it, the band keeps the section spacing to the footer */
.closing--end { padding-bottom: var(--section-y); }
.closing-list { display: grid; gap: var(--space-2-5); margin-top: var(--space-6); font-size: var(--text-md); color: var(--ink-2); }
.closing-list li { display: flex; align-items: flex-start; gap: var(--space-3); }
.closing-list .lc { flex: none; width: var(--icon-lg); height: var(--icon-lg); stroke-width: 2.5; color: var(--gold); }
/* enterprise, reliability and company under the call to action, set like the other editorial lists:
   an ink rule on top, hairlines between the columns, no boxes */
.closing-points, .points { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); border-top: var(--rule); }
.points--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
:is(.closing-points, .points) li { display: flex; flex-direction: column; gap: var(--space-1-5); padding: var(--space-5) var(--space-7) 0 0; font-size: var(--text-md); color: var(--ink-2); }
:is(.closing-points, .points) li + li { padding-left: var(--space-7); border-left: var(--divider); }
/* more points than columns run on in rows: each row starts without the hairline, 28px under the row above */
.points:not(.points--grid) { row-gap: var(--space-7); }
.points:not(.points--2, .points--grid) > li:nth-child(3n + 1), .points--2 > li:nth-child(2n + 1) { padding-left: 0; border-left: 0; }
:is(.closing-points, .points) b { color: var(--ink); }
.closing-points { margin-bottom: var(--section-y); }
.mark { overflow: visible; }
.closing .mark { width: 230px; justify-self: center; filter: drop-shadow(0 8px 18px rgb(0 0 0 / 0.07)); }
.mark-base { fill: var(--slate); } .mark-bottom { fill: var(--silver); } .mark-mid { fill: var(--graphite-2); } .mark-top { fill: url(#markGold); }
/* built as on /about: the layers rise from below one after the other, bottom first; each lower layer arrives as a
   full plate that fades once it lands, so at rest the bands and the gaps between them form the logo. A mark inside a
   block that fades in (.rv) waits for it and starts with its fade */
.mark-full { opacity: 0; }
@media (prefers-reduced-motion: no-preference) {
    .reveal-on .mark .layer { opacity: 0; translate: 0 44px; }
    .reveal-on .mark .mark-full { opacity: 1; }
    .reveal-on .mark.is-built .layer { animation: mark-build 580ms var(--ease-out-expo) calc(var(--d, 0) * var(--stagger) + var(--i) * 130ms) forwards; }
    .reveal-on .mark.is-built .mark-full { animation: mark-full-fade 200ms ease-out calc(var(--d, 0) * var(--stagger) + var(--i) * 130ms + var(--dur-fast)) forwards; }
    .reveal-on .rv:not(.in) .mark :is(.layer, .mark-full) { animation: none; }
}
@keyframes mark-build { to { opacity: 1; translate: 0 0; } }
@keyframes mark-full-fade { to { opacity: 0; } }
/* the parts of a plan the pricing's plans and the register's plan picker share (scopes.json shared): the plan's mark
   with one, two or four plates (src/lib/mark.ts), its price over the suffix, the line for whom and the marks of a
   yes or a no */
.plan-mark { flex: none; width: var(--logo-xl); height: var(--logo-xl); }
.plan-price { display: flex; align-items: baseline; gap: var(--space-2); color: var(--muted); font-size: var(--text-sm); }
.plan-price b { display: flex; }
/* the small words beside a price ("/mo", "a month") take no more height than the figure, so the billing switch moves nothing */
.plan-price > span { line-height: 1; }
.plan-price > .has-tip { align-self: flex-start; margin-left: calc(-1 * var(--space-1)); padding-right: var(--space-1); font-size: var(--text-xl); line-height: 1; }
.plan-for { font-size: var(--text-md); color: var(--ink-2); }
.plan-yes, .plan-no { display: inline-flex; align-items: center; gap: var(--space-1); }
.plan-yes .lc, .plan-no .lc { width: var(--icon-sm); height: var(--icon-sm); }
.plan-yes .lc { color: var(--bull-ink); }
.plan-no .lc { color: var(--muted); }
/* Footer: one step darker than the bands, gold edge on top as on adanos.org */
.foot-shell { border-top: 4px solid transparent; border-image: var(--gold-gradient) 1; background: var(--dark-deep); }
.foot-brand address { margin-top: var(--space-4); font-style: normal; line-height: var(--lh-body); color: var(--muted); }
.foot { display: grid; grid-template-columns: 2fr repeat(4, minmax(0, 1fr)); gap: var(--space-8); padding: var(--space-16) 0 var(--space-12); font-size: var(--text-sm); color: var(--ink-2); }
.foot-brand img { height: 40px; width: auto; }
.foot-brand p { margin-top: var(--space-4); max-width: 22em; line-height: var(--lh-body); }
/* a column's title is plain text that names its list; site chrome holds no heading */
.foot > div:not(.foot-brand) > p { font-weight: var(--fw-medium); color: var(--ink); margin-bottom: var(--space-3-5); }
.foot ul { display: grid; gap: 9px; }
.legal { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--space-6) var(--space-12); align-items: start; padding: var(--space-6) 0 36px; border-top: var(--divider); line-height: var(--lh-body); }
.legal p { max-width: 62em; }
.legal nav { display: flex; gap: var(--space-5); flex-wrap: wrap; white-space: nowrap; }
@media (hover: hover) { .foot a, .legal a, .crumbs a { transition: color var(--dur-fast) ease-out; } .foot a:hover, .legal a:hover, .crumbs a:hover, .toc a:hover { color: var(--ink); } }

/* ---------- Content pages (privacy, terms, imprint) ----------
   Page head as on the stock dashboard (an ink rule under it), then a contents list beside the text.
   The text runs at most 42rem wide; sections part with a hairline, lists of terms become label and text rows. */
.doc, .dash { padding-block: var(--space-7) var(--section-y); }
.doc-head { padding-bottom: var(--space-6); border-bottom: var(--rule); }
.crumbs { display: flex; gap: var(--space-2); }
.doc-head h1 { margin-top: var(--space-5); font-size: var(--text-5xl); line-height: var(--lh-heading); letter-spacing: var(--tracking-display); }
.doc-head .lead { max-width: none; margin-top: var(--space-4); }
.doc-meta { display: flex; flex-wrap: wrap; gap: var(--space-1) var(--space-6); margin-top: var(--space-4); }
.doc-body { display: grid; grid-template-columns: 232px minmax(0, 1fr); gap: var(--space-16); align-items: start; margin-top: var(--space-14); }
.doc-toc { position: sticky; top: calc(var(--nav-top) + var(--nav-h) + var(--space-6)); }
.toc summary { display: flex; align-items: center; justify-content: space-between; padding-bottom: var(--space-3); border-bottom: var(--divider); list-style: none; }
.toc summary::-webkit-details-marker { display: none; }
.toc summary .lc { display: none; }
.toc ol { padding-top: var(--space-2); }
/* the section being read: ink text and the gold cursor of the endpoint list, here in the gutter */
.toc a { position: relative; display: flex; padding: var(--space-1-5) 0; font-size: var(--text-sm); line-height: var(--lh-title); color: var(--ink-2); transition: color var(--dur-fast) ease-out; }
.toc a[aria-current] { color: var(--ink); }
.prose { max-width: var(--measure); line-height: var(--lh-body); color: var(--ink-2); }
.prose section + section { margin-top: var(--space-12); padding-top: var(--space-12); border-top: var(--divider); }
.prose h2 { margin-bottom: var(--space-4); font-size: var(--text-2xl); }
.prose h3 { margin: var(--space-8) 0 var(--space-2); }
.prose h2 + h3 { margin-top: var(--space-5); }
/* section numbers lead the title as in a contract: "1. Scope", "2.1 Billing", same colour, size and weight */
.prose .n { margin-right: 0.3em; font-variant-numeric: tabular-nums; }
.prose :is(p, ul, dl, address) + :is(p, ul, dl, address) { margin-top: var(--space-4); }
.prose strong { color: var(--ink); }
:is(.prose, .faq-a) a:not(.textlink) { color: var(--ink); text-decoration: underline 1px var(--line-2); text-underline-offset: 3px; transition: text-decoration-color var(--dur-fast) ease-out; }
@media (hover: hover) { :is(.prose, .faq-a) a:not(.textlink):hover { text-decoration-color: currentColor; } }
.prose ul:not([class]) li { position: relative; padding-left: var(--space-5); }
.prose ul:not([class]) li + li { margin-top: var(--space-1); }
.prose ul:not([class]) li::before { content: ""; position: absolute; left: 2px; top: calc(0.8em - var(--dot-sm) / 2); width: var(--dot-sm); height: var(--dot-sm); border-radius: var(--r-round); background: var(--muted); }
/* a list of terms opens with a rule; the legal reference sits under its term */
.defs { border-top: var(--divider); }
.defs .ref { display: block; margin-top: var(--space-0-5); }
.doc-card { padding: var(--pad); font-style: normal; }

/* ---------- Articles (insights: weekly reports, blog, data in action) ----------
   A content page (head, contents list, prose) plus the blocks articles carry. article-2026.html is built from a live
   article (scratchpad article/build.py); the chart and the stock card read recorded API data. */
.avatar { flex: none; display: grid; place-items: center; width: var(--logo-lg); height: var(--logo-lg); border-radius: var(--r-round); overflow: hidden; background: var(--bg-2); font-size: var(--text-xs); font-weight: var(--fw-medium); color: var(--ink-2); }
.avatar img { width: 100%; height: 100%; object-fit: cover; }
/* figures, tables, quotes, the stock card and code sit a step apart from the text around them */
.prose :is(.art-fig, .art-table, .post--static, .art-stock, .art-code, .faq) { margin-block: var(--space-6); }
.faq { border-top: var(--divider); }
.faq details { border-bottom: var(--divider); }
.faq summary { padding: var(--space-4) 0; font-size: var(--text-md); font-weight: var(--fw-medium); line-height: var(--lh-title); color: var(--ink); }
.faq-a { padding-bottom: var(--space-4); line-height: var(--lh-body); color: var(--ink-2); }
.faq-a p + p { margin-top: var(--space-3); }
/* a question of the FAQ and any other details with fold open in place: the summary's text, then the chevron, which
   turns over while it is open; without reduced motion the content slides open */
:is(.faq details, .fold) > summary { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); list-style: none; cursor: pointer; }
:is(.faq details, .fold) > summary::-webkit-details-marker { display: none; }
:is(.faq details, .fold) > summary .lc { flex: none; color: var(--muted); transition: rotate var(--dur-fast) ease-out; }
:is(.faq details, .fold)[open] > summary .lc { rotate: 180deg; }
@media (hover: hover) { :is(.faq details, .fold) > summary:hover .lc { color: var(--ink); } }
@media (prefers-reduced-motion: no-preference) {
    :is(.faq details, .fold) { interpolate-size: allow-keywords; }
    :is(.faq details, .fold)::details-content { block-size: 0; overflow: clip; transition: block-size var(--dur) var(--ease-out-expo), content-visibility var(--dur) allow-discrete; }
    :is(.faq details, .fold)[open]::details-content { block-size: auto; }
}

/* ---------- Product pages (one API per source) ----------
   Hero as on the homepage with a live trending board in place of the machine, then why, how (dark), endpoints with a
   real response for each, pricing and questions. */
/* trending board: window switch on top, the ranking left, sectors and countries right, the call that returns it below */
.board { margin-top: var(--space-14); }
.board-ctl { display: flex; flex-wrap: wrap; gap: var(--space-2); }
/* the window of a trending board as a select, for phones only; it stands in for the window switch beside it */
.board--rank .board-ctl > .select { display: none; }
.board-title { display: flex; align-items: baseline; gap: var(--space-3); flex-wrap: wrap; min-width: 0; }
.board-title #board-date:empty::before { content: "\a0"; } /* the window's dates keep their line before the script writes them */
/* a switch's call: the rows and side lists on screen dim until their own arrive */
.board--rank :is(.tr-rows, .kv) > * { transition: opacity 150ms ease-out; }
.board--rank :is(.tr-rows, .kv)[aria-busy="true"] > :not([aria-hidden]) { opacity: 0.5; }
.board-body { display: grid; grid-template-columns: minmax(0, 1fr) 280px; }
.board-side { display: grid; grid-template-columns: minmax(0, 1fr); align-content: start; gap: var(--space-6); padding: var(--space-5) var(--pad); border-left: var(--divider); background: var(--bg); }
.board-side h3 { margin-bottom: var(--space-2); }
/* each side list opens with a rule: beside the rows, the first one continues the line under the head row */
.board-side ol { border-top: var(--divider); }
/* beside the rows, the side column's first heading takes the head row: the same height and line, its list starts on the head's rule */
@media (min-width: 1025px) {
    .board-side { padding-top: 0; }
    .board-side > :first-child > h3 { display: flex; align-items: center; min-height: var(--tr-head); margin-bottom: 0; }
}
/* a board variant sets the columns of its rows in --tr-cols; without one a row takes the six columns of the ranking */
.tr-row { display: grid; grid-template-columns: var(--tr-cols, 24px minmax(0, 1.7fr) 64px 96px minmax(0, 1fr) var(--spark)); align-items: center; gap: var(--space-4); min-height: var(--tr-row); padding: 0 var(--pad); border-bottom: var(--divider); font-size: var(--text-sm); font-variant-numeric: tabular-nums; }
.tr-rows .tr-row:last-child { border-bottom: 0; }
.tr-rows .tr-row:nth-child(odd) { background: var(--bg); }
.tr-head { min-height: var(--tr-head); }
/* a word that explains itself takes the dots 2px under its text: a head or a row label with a tip and the plans' switch
   to yearly billing. A JSON key with a field note keeps its code clean and shows its note on hover only */
.tr-head .has-tip { justify-self: start; margin-bottom: -2px; padding-bottom: 2px; background: var(--dots); cursor: help; } /* the margin takes back the dots, so the label keeps its place in the row */
.kv .has-tip { padding-bottom: 2px; background: var(--dots); cursor: help; } /* a row label with a tip, as the plans' "Historical data" */
.tr-head .tr-num { justify-self: end; }
.tr-n { color: var(--muted); }
.tr-stock { display: flex; align-items: center; min-width: 0; }
/* a tag after the ticker keeps a small gap; every row is its own grid, so the columns have fixed widths and a tag
   alone in a cell ends in an ellipsis */
.tr-stock .tag { margin-left: var(--space-1); }
.tr-row > [role="cell"] > .tag { display: inline-block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: middle; }
.tr-num small { display: block; }
/* a row with a stock page opens it on click; the hover fill (as on light buttons) shows which rows do */
.tr-row.is-link { cursor: pointer; transition: background-color var(--dur-fast) ease-out; }
@media (hover: hover) { .tr-rows .tr-row.is-link:hover { background: var(--bg-2); } }
/* the columns of the table on adanos.org: buzz with the trend's arrow, mentions with their subreddits, the sentiment lean, the daily buzz */
.tr-buzz { display: flex; align-items: baseline; gap: var(--space-1); }
.tr-buzz [role="img"] { font-weight: var(--fw-medium); }
.tr-num { text-align: right; }
.tr-lean, .tr-trend { align-self: stretch; display: flex; align-items: center; }
.tr-lean { --mark: var(--bar); }
.tr-trend { --mark: calc(var(--spark) * 2 / 5); }
.tr-rows .tip { top: calc(50% + var(--mark) / 2 + var(--space-1-5)); }
/* the last row's tip opens over its mark, as does a tip that scrolling rows would cut off (is-up, the stocks hub) */
.tr-rows :is(.tr-row:last-child, .is-up) .tip { top: auto; bottom: calc(50% + var(--mark) / 2 + var(--space-1-5)); }
.tr-lean .split { flex: 1; }
/* Sparkline: the buzz chart's marks in the trend's colour (A26.spark in site-2026.js); --fluid fills its box */
.spark { display: block; width: var(--spark); aspect-ratio: 5 / 2; overflow: visible; }
.spark--fluid { width: 100%; height: 100%; aspect-ratio: auto; }
.spark .ch-area stop { stop-color: currentColor; }
.spark .ch-buzz { stroke: currentColor; }
.spark .ch-dot { fill: currentColor; }
/* hero: the copy left, the source's mark right; on Reddit the Snoo's eyes follow the pointer */
.hero-top--product { grid-template-columns: minmax(0, 1fr) auto; align-items: center; }
.hero-top--product .hero-head { align-self: start; } /* the title at the same height on every product hero, the mark centred */
.hero-top--product .lead { margin-top: var(--space-6); }
/* --center (with --product): one centred column without a mark, the actions under the lead, as the pricing page */
.hero-top--center { grid-template-columns: minmax(0, 1fr); justify-items: center; text-align: center; }
.hero-top--center .lead { max-width: 60ch; margin-inline: auto; }
.hero-top--center .hero-actions { justify-content: center; }
/* a little smaller than on adanos.org (five grid cells); it reaches into the hero's padding so the board stays close */
.hero-mark { container-type: inline-size; width: calc(5 * var(--grid-cell)); aspect-ratio: 1; margin-block: calc(-1 * var(--space-10)); }
/* a --fit mark (the directory's flap strip) is no square: the box takes its height */
.hero-mark--fit { aspect-ratio: auto; }
/* every hero mark is a disc: the Snoo is one, a source tile is cut to the same circle */
.snoo { display: block; width: 100%; height: 100%; clip-path: circle(50%); }
.snoo-disc { fill: var(--brand); }
.snoo-face { fill: var(--paper); }
/* the crypto page's Snoo: the disc takes the gold gradient the svg defines, the pupils a deeper gold */
.snoo--gold .snoo-disc { fill: url(#snoo-gold); }
.snoo--gold .snoo-pupil { fill: var(--snoo-gold-pupil); }
.snoo-gold-0 { stop-color: var(--snoo-gold-0); }
.snoo-gold-1 { stop-color: var(--snoo-gold-1); }
.snoo-gold-2 { stop-color: var(--snoo-gold-2); }
/* why: three cards, each opens with a small picture of the problem above its icon, title and text */
.why-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-4); }
.why-card { display: flex; flex-direction: column; overflow: hidden; }
.why-art { position: relative; display: grid; align-items: center; height: 152px; border-bottom: var(--divider); background: var(--bg); overflow: hidden; }
.why-text { display: grid; align-content: start; gap: var(--space-2-5); padding: var(--space-6); }
.why-text h3 { display: flex; align-items: center; gap: var(--space-3); }
.why-text p { font-size: var(--text-md); color: var(--ink-2); text-wrap: pretty; }
/* a card that opens a page is the link itself (a.why-card): its title takes the signal ink on hover, as a link card's */
a.why-card h3 { transition: color var(--dur-fast) ease-out; }
@media (hover: hover) { a.why-card:hover h3 { color: var(--signal-ink); } }
/* --bento: five cards, two wide over three narrow */
.why-grid--bento { grid-template-columns: repeat(6, minmax(0, 1fr)); }
.why-grid--bento > * { grid-column: span 2; }
.why-grid--bento > :nth-child(-n + 2) { grid-column: span 3; }
/* --2: two cards side by side on wide screens, as the typefaces of the brand page; from 1024px down they stack as every
   why grid does */
@media (min-width: 1025px) { .why-grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
/* a file as a card's picture, centred on a ground that shows it as it is: a faint checkerboard on paper for a file with
   a transparent ground, the dark band for a reversed one (the logo files of the brand page) */
:is(.why-art--check, .why-art--dark) { justify-items: center; }
.why-art--check { background: repeating-conic-gradient(color-mix(in srgb, var(--line) 60%, transparent) 0 25%, var(--paper) 0 50%) 0 0 / var(--space-4) var(--space-4); }
.why-art--dark { background: var(--dark); }
.ic-tile { flex: none; display: grid; place-items: center; width: var(--logo-lg); height: var(--logo-lg); border-radius: var(--r); background: var(--bg); color: var(--ink-2); }
.ic-tile .lc { width: var(--icon-lg); height: var(--icon-lg); }
/* 1 · the 59 subreddits drift by in three rows */
.why-art > .sub-river { display: grid; gap: var(--space-2); }
/* a search with its first hits (why-db) and the head of a ranking (why-rank) as a card's picture, as the ticker
   database and the rankings of the about page and the Fear and Greed page */
.why-db { display: grid; gap: var(--space-2); padding: 0 var(--space-6); font-size: var(--text-xs); }
.why-db ul { display: grid; gap: var(--space-1); }
.why-db li { display: grid; grid-template-columns: 48px minmax(0, 1fr) auto; gap: var(--space-2); color: var(--ink-2); }
.why-db li b { font-weight: var(--fw-medium); color: var(--ink); }
.why-db li span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.why-db li em { font-style: normal; color: var(--muted); }
.why-rank { display: grid; gap: var(--space-2-5); padding: 0 var(--space-6); font-size: var(--text-xs); --s: var(--logo-xs); }
.why-rank li { display: grid; grid-template-columns: 12px auto 44px minmax(0, 1fr) auto; align-items: center; gap: var(--space-2); }
.why-rank b { font-weight: var(--fw-medium); color: var(--ink); }
.why-rank em { font-style: normal; font-variant-numeric: tabular-nums; color: var(--ink); }
.sub-row { overflow: hidden; }
.sub-set { display: flex; gap: var(--space-2); padding-right: var(--space-2); }
.sub-set span { padding: var(--space-0-5) var(--space-2); border: var(--border); border-radius: var(--r-xs); background: var(--paper); font-size: var(--text-xs); color: var(--ink-2); white-space: nowrap; }
.sub-row .sub-track { --loop: 90s; }
.sub-row:nth-child(2) .sub-track { --loop: 110s; animation-direction: reverse; }
.sub-row:nth-child(3) .sub-track { --loop: 100s; }
/* 2 · raw counts jump around, the checked signal draws a calm line through them */
.why-waves { position: absolute; inset: var(--space-4) 0; width: 100%; height: calc(100% - 2 * var(--space-4)); }
.why-waves polyline { fill: none; stroke-linecap: round; stroke-linejoin: round; }
.why-waves .raw { stroke: var(--silver); stroke-width: 1.5; transition: opacity var(--dur-slow) ease-out var(--dur-glide); }
.why-waves .sig { stroke: var(--gold); stroke-width: 2.5; }
.why-waves.sig-layer { clip-path: inset(0 0 0 0); }
/* 3 · two stocks on the buzz scale */
.why-scale { padding: var(--space-10) var(--space-6) 0; }
/* the low marks hang under the track, so its axis keeps their room */
.why-track { position: relative; height: var(--bar); margin-bottom: var(--space-10); border-radius: var(--r-pill); background: var(--line); }
.why-track::before { content: ""; position: absolute; inset: 0; border-radius: inherit; background: var(--gold-gradient); opacity: 0.35; }
/* chip: a name, a word or a figure in an outlined box; the edge and the fill come from the context, so the same chip
   reads on a dark surface. A logo or an icon tile goes first and sits 4px from the edge */
.why-mark, .chip { display: inline-flex; align-items: center; gap: var(--space-1-5); padding: var(--space-1) var(--space-2); border: var(--border); border-radius: var(--r); background: var(--chip-bg); font-size: var(--text-xs); white-space: nowrap; --s: var(--logo-xs); }
:is(.why-mark, .chip):has(> :not(b):first-child) { padding-left: var(--space-1); }
.chip b { color: var(--ink); }
.why-mark { position: absolute; left: var(--x); bottom: calc(100% + var(--space-3)); translate: calc(-100% * var(--ax, 0.5)) 0; }
.why-mark::after { content: ""; position: absolute; left: calc(var(--ax, 0.5) * 100%); top: 100%; width: 1px; height: calc(var(--space-3) + var(--bar)); background: var(--ink); }
.why-mark.is-low { bottom: auto; top: calc(100% + var(--space-3)); }
.why-mark.is-low::after { top: auto; bottom: 100%; }
.why-mark b { color: var(--ink); }
:is(.why-mark, .chip) em { font-style: normal; color: var(--muted); font-variant-numeric: tabular-nums; }
@media (prefers-reduced-motion: no-preference) {
    .reveal-on .why-waves.sig-layer { clip-path: inset(0 100% 0 0); transition: clip-path calc(2 * var(--dur-glide)) var(--ease-out-expo) var(--dur); }
    .reveal-on .why-card.in .why-waves.sig-layer { clip-path: inset(0 0 0 0); }
    .reveal-on .why-mark { left: 0; transition: left calc(2 * var(--dur-glide)) var(--ease-out-expo) var(--dur); }
    .reveal-on .why-card.in .why-mark { left: var(--x); }
}
.why-card.in .why-waves .raw { opacity: 0.6; }
/* why cards: one headline scored for two companies, the names marked, a chip with each score under it */
.why-pair { display: grid; gap: var(--space-3); padding: var(--space-5) var(--space-6); }
.why-pair p { font-size: var(--text-sm); line-height: var(--lh-title); color: var(--ink); }
.why-pair div { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.why-pair .why-mark { position: static; translate: none; }
.why-pair .why-mark::after { content: none; }
.why-mark em.pos { color: var(--bull-ink); }
.why-mark em.neg { color: var(--bear-ink); }
/* a track split into the bearish, neutral and bullish zones of the label scale */
.why-track--zones { background: linear-gradient(90deg, color-mix(in srgb, var(--bear) 35%, transparent) calc(50% - var(--neu) / 2), var(--line-2) 0 calc(50% + var(--neu) / 2), color-mix(in srgb, var(--bull) 35%, transparent) 0); }
.why-track--zones::before { content: none; }
/* the request stays on one line; a long one runs out under a fade at the right and scrolls sideways */
.ep-req code { flex: 1; min-width: 0; overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: none; white-space: nowrap; mask-image: linear-gradient(90deg, #000 calc(100% - var(--space-8)), transparent); color: var(--ink-2); }
.ep-req code .pv { color: var(--paper); }
.ep-bar { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); padding: 0 var(--space-2-5) 0 calc(var(--pad) - var(--tab-x)); border-bottom: var(--divider); }
.ep-view { position: relative; display: flex; flex-direction: column; flex: 1; min-height: 0; }
.ep-json, .ep-code { position: relative; font-family: var(--mono); font-size: var(--text-xs); line-height: var(--lh-code); }
.ep-code { flex: 1; min-height: 0; margin: 0; padding: var(--inset-code) var(--pad); overflow: auto; overscroll-behavior: contain; white-space: pre; color: var(--code-body); }
.ep-code .m { color: var(--muted); }
.ep-progress { position: absolute; z-index: 2; inset: 0 0 auto; height: var(--indicator); background: var(--code-gold); transform-origin: 0 50%; scale: 0 1; opacity: 0; }
.ep-progress.is-run { opacity: 1; scale: 1 1; transition: scale var(--t, 300ms) linear; }
.ep-progress.is-done { scale: 1 1; opacity: 0; transition: opacity var(--dur) ease-out; }
.ep-json.is-swap { opacity: 0; }
.ep-out .ep-json { transition: opacity var(--dur-fast) ease-out; }
@media (hover: hover) { .k.has-d:hover { color: var(--paper); } }
.k.has-d { cursor: help; }
.k.is-hl { border-radius: var(--r-xs); background: var(--tint-gold); color: var(--code-gold); }
/* Tips: a small card that says what a field or column means or gives the exact figures behind a mark. It inverts the
   surface it sits on: dark with .on-dark over the page, tip--light over a dark panel. Inside .has-tip it opens under
   its anchor on hover and focus; tip--float is placed by its script (left, top) and shown with hidden */
.tip { position: absolute; z-index: var(--z-tip); top: calc(100% + var(--space-1-5)); left: 50%; width: max-content; max-width: var(--tip-w); padding: var(--space-2) var(--space-3); border: var(--border); border-radius: var(--r); background: var(--dark); box-shadow: var(--shadow-pop); font-size: var(--text-xs); font-weight: var(--fw-regular); line-height: var(--lh-title); color: var(--paper); translate: -50% 0; opacity: 0; transition: opacity var(--dur-fast) ease-out; pointer-events: none; }
.tip :is(b, code) { color: var(--ink); }
.tip b { font-weight: var(--fw-medium); }
.tip code { display: block; margin-bottom: var(--space-0-5); font-family: var(--mono); }
/* the light tip inverts the dark panel, so it takes the light roles back */
.tip--light { --ink: var(--tip-ink); --ink-2: var(--graphite); max-width: min(var(--tip-w), 80%); border: 0; background: var(--paper); color: var(--ink-2); }
.tip--float { translate: none; opacity: 1; transition: none; }
.tip--end { left: auto; right: 0; translate: none; }
.has-tip { position: relative; }
.has-tip:is(:focus-visible, .is-open) > .tip { opacity: 1; } /* is-open: a tap on a touch screen (site-2026.js) */
@media (hover: hover) { .has-tip:hover > .tip { opacity: 1; } }
/* the status runs its readings from the left and wraps */
.ep-status { flex-wrap: wrap; justify-content: flex-start; row-gap: var(--space-1); }
.ep-status .st { display: inline-flex; align-items: center; gap: var(--space-1-5); font-weight: var(--fw-medium); color: var(--bull); }
.ep-status .st i { width: var(--dot-sm); height: var(--dot-sm); border-radius: var(--r-round); background: currentColor; }
.ep-status .st.is-err { color: var(--bear); }
.ep-status .st.is-wait { color: var(--code-gold); }
.ep-status .sz { margin-left: auto; } /* the answer's size at the right end */
/* the line keeps its height before the first call answers, and the request of a waiting call stays on one line, so
   the panel never grows on a phone */
.ep-status:empty::before { content: "\a0"; font-size: var(--text-xs); }
.ep-status .is-wait + .type-meta { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (prefers-reduced-motion: no-preference) {
    .ep-status .st.is-wait i { animation: blink 1s ease-in-out infinite; }
}
@keyframes blink { 50% { opacity: 0.3; } }
/* the full API documentation and the BuzzScore whitepaper, under the text beside the SDKs */
.ep-links { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-6); margin-top: var(--space-5); font-size: var(--text-sm); }
/* under the playground: the docs links, the official SDKs and the CLI, one row each with its install line and a copy button */
.sdks { display: grid; grid-template-columns: minmax(0, 4fr) minmax(0, 7fr); gap: var(--space-6) var(--space-10); margin-top: var(--space-12); }
.sdks :is(h2, h3) + p { max-width: 40ch; margin-top: var(--space-2); font-size: var(--text-md); color: var(--ink-2); }
.sdk-list li { display: grid; grid-template-columns: minmax(0, var(--label-col)) minmax(0, 1fr) auto; align-items: center; column-gap: var(--space-4); padding: var(--space-2) var(--space-2) var(--space-2) var(--pad); font-size: var(--text-sm); }
.sdk-list li + li { border-top: var(--divider); }
/* --files: rows of files, as the CSV files of the ticker database and the logo files of the brand page. A link at the
   end in place of a copy button, so the row keeps its pad; on phones a file's text takes the row under its name */
.sdk-list--files li { padding-block: var(--space-3); padding-right: var(--pad); }
.sdk-n { color: var(--ink-2); }
.sdk-list code { min-width: 0; overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: none; white-space: nowrap; font-family: var(--mono); font-size: var(--text-xs); color: var(--ink); }
/* a field row points at its keys in the response above */
#ep-fields > div { cursor: pointer; }
#ep-fields > div.is-hl code { background: var(--tint-gold); color: var(--ink); }
.seg .tag { margin-left: var(--space-2); }
/* a tag with a short form shows it on the narrowest phones, as the yearly saving of the pricing page */
.seg-short { display: none; }
@media (max-width: 360px) {
    .seg-long { display: none; }
    .seg-short { display: inline; }
}
/* questions: the heading beside an accordion with hairlines between the answers */
/* Questions: the box of the sources explorer on the homepage (faq_part.py). The list runs through all questions under
   their topics, the contact line at its foot. The panel answers first: question and answer on paper, then a dark card
   to the edges with the piece of the API the question is about and its figure; the link to the next question sits
   under the answer. Every answer sits in the same cell, so the box keeps
   the height of the longest one; the card keeps one size at the foot, so only the text changes between questions. */
@media (min-width: 1025px) {
    .explorer--faq { grid-template-rows: auto; }
}
/* the first topic stands level with the answer's heading; the rows get a little more air than the endpoints */
.explorer--faq .ep-list { padding-top: calc(var(--space-6) - var(--space-3)); }
.explorer--faq .ep { padding-block: var(--space-3); }
.explorer--faq .ep .p { font-family: var(--sans); }
.explorer--faq .src-info p { margin: 0; }
.fx-group { padding: var(--space-5) 0 var(--space-1-5); }
.fx-group:first-child { padding-top: var(--space-3); }
.explorer--faq .ep-list li:has(+ .fx-group) .ep { border-bottom: 0; }
.fx-out { position: relative; display: flex; flex-direction: column; min-width: 0; scroll-margin-top: calc(var(--nav-top) + var(--nav-h) + var(--space-3)); }
.fx-next { margin-top: var(--space-4); }
.textlink .lc { width: var(--icon-sm); height: var(--icon-sm); }
.fx-next .lc { rotate: -90deg; }
.fx-panels { flex: 1; display: grid; }
.fx-panel { grid-area: 1 / 1; display: flex; flex-direction: column; gap: var(--space-6); min-width: 0; padding-top: var(--space-6); }
.fx-panel:not(.is-current) { visibility: hidden; }
.fx-text { padding-inline: var(--pad); color: var(--ink-2); }
/* with no figure under it the text closes the panel, so Next question keeps the panel's top space below it */
.fx-text:last-child { padding-bottom: var(--space-6); }
.fx-a { max-width: var(--measure); margin-top: var(--space-3); }
.fx-a p + p { margin-top: var(--space-3); }
.fx-a code { font-family: var(--mono); font-size: var(--text-xs); color: var(--ink); }
.fx-card { margin-top: auto; }
.fx-card .ep-req code { mask-image: none; } /* these lines fit; the fade is for requests that run out */
.fx-fig { display: grid; place-items: center; height: 340px; padding: var(--space-8); overflow: hidden; color: var(--paper); background-image: linear-gradient(var(--dark-line) 1px, transparent 1px), linear-gradient(90deg, var(--dark-line) 1px, transparent 1px); background-size: var(--space-10) var(--space-10); background-position: center; }

/* ---------- Tool pages (analyzer, sentiment index, widgets) ----------
   The product hero with the tool as its main object, where product pages show their board: the input on the light
   side, the playground's dark panel for the answer (result, response, the call), then how it works and the questions.
   tool-2026.html is built from the live analyzer (scratchpad tool/build.py); the draft answers from recorded calls. */
/* text fields: a filled field with the box edge; focus darkens the edge (no ring on top) and lifts the fill to paper */
.field { display: grid; gap: var(--space-2); }
.field-l { display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-3); font-size: var(--text-sm); font-weight: var(--fw-medium); color: var(--ink); }
.field-l > :not(:first-child) { font-variant-numeric: tabular-nums; }
.input { display: block; width: 100%; min-height: var(--h-btn); padding: var(--space-2-5) var(--space-3-5); border: var(--border); border-radius: var(--r-field); background: var(--bg); font: inherit; font-size: var(--text-base); line-height: var(--lh-body); color: var(--ink); transition: border-color var(--dur-fast) ease-out, background-color var(--dur-fast) ease-out; }
textarea.input { resize: vertical; }
.input::placeholder { color: var(--muted); }
@media (hover: hover) { .input:hover:not(:focus) { border-color: color-mix(in srgb, var(--ink) 30%, var(--line-2)); } }
.input:focus { outline: 0; border-color: var(--ink); background: var(--paper); }
.input[aria-invalid="true"] { border-color: var(--bear); }
.field-err { font-size: var(--text-xs); color: var(--bear-ink); }
.field-err:empty { display: none; }
.field .seg { justify-self: start; flex-wrap: wrap; }
/* the analyzer's mark in the hero: a text under a lens, as on the live page, in the brand colours */
.lens { display: block; width: 100%; height: 100%; }
.lens .l1 { color: var(--code-gold); }
.lens .l2 { color: var(--graphite-2); }
.lens .l3 { color: var(--slate); }
.lens .l4 { color: var(--silver); }
.lens-glass { fill: var(--paper); }
.lens-ring { fill: none; stroke: var(--graphite-2); stroke-width: 8; }
.lens-handle { fill: none; stroke: var(--graphite-2); stroke-width: 11; stroke-linecap: round; }
/* the bars of the listing's big lens (insights-2026.css) stay flat until their block fades in */
@media (prefers-reduced-motion: no-preference) {
    .reveal-on .rv:not(.in) .lens-bars.lens-big rect { scale: 1 0; }
}

/* ---------- Directory pages (ticker database, stocks hub) ----------
   The product hero with the product page's board as its main object: a search and filters in the board's head, the
   board's rows, the largest exchanges and countries in its side column (a click filters), more rows from its foot.
   directory-2026.html is built from the live ticker database (scratchpad dir/build.py) on the dataset the live page loads. */
/* board--dir: twelve and a half rows at a time that scroll under the head row, so the search, the column heads and the
   side column stay in view, and the next row always shows; on phones the filters fill the head's second line */
.board--dir { --tr-cols: minmax(0, 1.7fr) 96px minmax(0, 1fr) minmax(0, 1fr) 120px 96px; }
.board--dir .box-head { padding-left: var(--space-2-5); }
/* a title at the head's start (the stocks hub) lines up with the text of the rows */
.board--dir .board-title { padding-left: calc(var(--pad) - var(--space-2-5)); }
.board--dir .board-body > [role="table"] { display: flex; flex-direction: column; }
.board--dir .tr-rows { flex: 1 1 0; min-height: calc(12.5 * var(--tr-row)); overflow-y: auto; overscroll-behavior: contain; }
/* without a side list (the stocks hub) the table fills the board and its rows take exactly that height */
.board--dir > [role="table"] > .tr-rows { height: calc(12.5 * var(--tr-row)); }
.board--dir .tr-head > span { white-space: nowrap; }
.board--dir .tr-stock b { font-variant-numeric: normal; }
@media (max-width: 1024px) {
    /* the sector column goes; the side column moves under the rows as on every board */
    .board--dir { --tr-cols: minmax(0, 1.6fr) 96px minmax(0, 1fr) 120px 96px; }
    .board--dir .tr-row > :nth-child(4) { display: none; }
}
@media (max-width: 768px) {
    /* phones: ticker and company, the exchange and the mentions; the search takes the head's first line */
    .board--dir { --tr-cols: minmax(0, 1fr) 84px 72px; }
    .board--dir .tr-row { gap: var(--space-3); }
    .board--dir .tr-rows { min-height: calc(9.5 * var(--tr-row)); }
    .board--dir > [role="table"] > .tr-rows { height: calc(9.5 * var(--tr-row)); }
    .board--dir .tr-row > :is(:nth-child(3), :nth-child(5)) { display: none; }
    .board--dir .board-ctl { width: 100%; }
    .board--dir .select { flex: 1; }
    .board--dir .select select { max-width: none; width: 100%; }
}
/* a select: the text field's fill and edge with a chevron; the same height as the search beside it */
.select { position: relative; display: inline-flex; align-items: center; height: var(--h-control); border: var(--border); border-radius: var(--r-field); background: var(--bg); transition: border-color var(--dur-fast) ease-out; }
.select select { appearance: none; height: 100%; max-width: 13rem; padding: 0 calc(var(--space-3) + var(--icon) + var(--space-2)) 0 var(--space-3); border: 0; outline: 0; background: transparent; font: inherit; font-size: var(--text-sm); color: var(--ink); cursor: pointer; text-overflow: ellipsis; }
.select .lc { position: absolute; right: var(--space-3); color: var(--muted); pointer-events: none; }
.select:focus-within { border-color: var(--ink); }
@media (hover: hover) { .select:hover:not(:focus-within) { border-color: color-mix(in srgb, var(--ink) 30%, var(--line-2)); } }
/* select--field: the pick of a form field, as tall and as wide as the text input over it */
.select--field { display: flex; min-width: 0; height: var(--h-btn); }
.select--field select { flex: 1; min-width: 0; max-width: none; padding-left: var(--space-3-5); font-size: var(--text-base); }
/* the side column's rows filter: the row a filter is set on reads as chosen, with the gold cursor of the lists */
.board-side li > button { position: relative; display: flex; justify-content: space-between; gap: var(--space-3); width: 100%; text-align: left; color: inherit; transition: color var(--dur-fast) ease-out; }
.board-side li:has(> button) { padding: 0; }
.board-side li > button { padding: var(--space-1-5) 0; }
.board-side li > button[aria-pressed="true"] { color: var(--ink); font-weight: var(--fw-medium); }
@media (hover: hover) { .board-side li > button:hover { color: var(--ink); } }
.sdk-d { font-size: var(--text-sm); color: var(--ink-2); }
.sdk-d span { display: block; }

/* ---------- Listing pages (insights hub, series indexes) ---------- */
/* the weekly reports: board rows in the hero, under its head, as on the product page; the period with its date under
   it, the hot and weak tickers as chips */
.board--reports { --tr-cols: minmax(0, 1.2fr) minmax(0, 1.6fr) minmax(0, 1.6fr) 96px 120px; }
.board--reports .tr-row { padding-block: var(--space-2-5); }
.board--reports .tr-head { padding-block: 0; }
@media (max-width: 1024px) {
    .board--reports { --tr-cols: minmax(0, 1.2fr) minmax(0, 1.6fr) minmax(0, 1.6fr) 96px; }
    .board--reports .tr-row > :nth-child(5) { display: none; }
}
@media (max-width: 768px) {
    .board--reports { --tr-cols: minmax(0, 1fr) minmax(0, 1.3fr); }
    .board--reports .tr-row > :is(:nth-child(3), :nth-child(4)) { display: none; }
}
/* link cards: a grid of boxed links, each about one ticker or one study (link-cards.md); --lead runs the first card
   the full width with its summary beside its title, --compact keeps two short cards a row on phones */
.cards { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-4); }
.card { display: flex; flex-direction: column; gap: var(--space-3); height: 100%; padding: var(--pad); }
.card-title { text-wrap: pretty; transition: color var(--dur-fast) ease-out; }
@media (hover: hover) { .card:hover .card-title { color: var(--signal-ink); } }
.card-sum { display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; font-size: var(--text-md); color: var(--ink-2); }
.cards--lead > li:first-child { grid-column: 1 / -1; }
.cards--lead > li:first-child > .card { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); grid-template-rows: auto auto 1fr; column-gap: var(--space-12); }
.cards--lead > li:first-child .card-title { grid-column: 1; font-size: var(--text-2xl); }
.cards--lead > li:first-child .card-sum { display: block; grid-column: 2; grid-row: 1 / -1; align-self: center; font-size: var(--text-lg); }
@media (max-width: 1024px) {
    .cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 768px) {
    .cards, .cards--lead > li:first-child > .card { grid-template-columns: minmax(0, 1fr); }
    .cards--compact { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-2); }
    .cards--lead > li:first-child .card-sum { grid-column: 1; grid-row: auto; font-size: var(--text-md); }
}
/* the blog: the editorial points in rows, a hairline between the rows; a summary (and the quote of a source card on
   the stock dashboard) stops at three lines */
.points--grid li, .points--grid li + li { padding: var(--space-5) var(--space-7) var(--space-7); border-left: var(--divider); }
.points--grid > li > b { text-wrap: pretty; }
.pt-sum { display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
@media (min-width: 1025px) {
    .points--grid li:nth-child(3n + 1) { padding-left: 0; border-left: 0; }
    .points--grid li:nth-child(n + 4) { border-top: var(--divider); }
}
@media (min-width: 769px) and (max-width: 1024px) {
    .points--grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .points--grid li:nth-child(2n + 1) { padding-left: 0; border-left: 0; }
    .points--grid li:nth-child(n + 3) { border-top: var(--divider); }
}

/* Sticky CTA (phones) */
.sticky-cta { position: fixed; inset: auto var(--nav-top) var(--nav-top); z-index: var(--z-float); display: none; align-items: center; justify-content: space-between; gap: var(--space-3); padding: var(--space-2) var(--space-2) var(--space-2) var(--space-4); border-radius: var(--r-float); border: 1px solid transparent; background: var(--graphite); color: var(--paper); box-shadow: var(--shadow-float); font-size: var(--text-sm); white-space: nowrap; opacity: 0; visibility: hidden; transition-property: opacity, translate, visibility; transition-duration: var(--dur); transition-timing-function: ease-out; }
.sticky-cta.is-on { opacity: 1; visibility: visible; }

/* ---------- Motion ---------- */
/* Scroll reveals: hidden state only applies once JS has opted in */
.reveal-on .rv { opacity: 0; transition: opacity var(--dur) ease-out, filter var(--dur) ease-out, translate var(--dur) ease-out; transition-delay: calc(var(--d, 0) * var(--stagger)); }
.reveal-on .rv.in { opacity: 1; }
@media (prefers-reduced-motion: no-preference) {
    .reveal-on .rv { filter: blur(4px); translate: 0 12px; }
    .reveal-on .rv.in { filter: none; translate: none; }
    .sticky-cta { translate: 0 12px; }
    .sticky-cta.is-on { translate: 0 0; }
}
@media (prefers-reduced-motion: reduce) {
    :is(.icons, [aria-expanded] > .icons, .is-copied > .icons) > .lc { scale: 1; filter: none; }
}

/* ---------- Responsive ---------- */
@media (max-width: 1024px) {
    .cases { grid-template-columns: 1fr; gap: var(--space-6); }
    :root { --gutter: var(--space-6); --text-hero: var(--text-6xl); }
    /* the nav keeps no box of its own, so the panel inside it still hangs from the bar */
    .nav-links { display: contents; }
    .nav-links > :not(.mega) { display: none; }
    .menu-mobile { display: grid; }
    .mega { max-height: calc(100dvh - var(--nav-top) - var(--nav-h) - 20px); overflow-y: auto; overscroll-behavior: contain; }
    .mega-inner { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-6); padding-top: var(--space-5); }
    .mega-more { display: block; }
    .mega-feature { grid-column: 1 / -1; }
    .nav .search { width: 200px; }
    .hero-top { grid-template-columns: 1fr; gap: var(--space-7); }
    .block-head { grid-template-columns: 1fr; gap: var(--space-3-5); }
    .block-head > .textlink { justify-self: start; }
    .block-head--cases .logo-marquee { margin-top: var(--space-5); }
    .explorer { grid-template-columns: 1fr; }
    .ep-side { border-right: 0; }
    /* the endpoints become a second tab row like the sources: ink line under the chosen one */
    .ep-list { display: flex; padding-inline: calc(var(--pad) - var(--tab-x)); border-bottom: var(--divider); overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: none; }
    .ep-list > li { flex: none; }
    .ep { gap: var(--space-2); white-space: nowrap; padding: var(--space-3-5) var(--tab-x); border-bottom: 0; }
    .ep::before { content: none; }
    .ep[aria-selected="true"] .p { translate: none; }
    .src-info { border-top: 0; border-bottom: var(--divider); }
    .ep-out .ep-json { flex: none; height: 400px; }
    .doc-body { grid-template-columns: minmax(0, 1fr); gap: var(--space-8); margin-top: var(--space-12); }
    .doc-toc { position: static; }
    /* above the text the contents list folds into a box that opens on tap */
    .toc { border: var(--border); border-radius: var(--r-box); background: var(--paper); }
    .toc summary { padding: var(--space-3) var(--pad); border-bottom: 0; font-size: var(--text-md); color: var(--ink); cursor: pointer; }
    .toc[open] summary { border-bottom: var(--divider); }
    .toc summary .lc { display: block; }
    .toc ol { padding: var(--space-2) var(--pad) var(--space-3); }
    /* in the box the arrow takes the start of the line and the current entry steps aside for it, as the questions of
       the FAQ do on phones */
    .toc a::before { left: 0; }
    .toc a[aria-current] { padding-left: var(--space-4); }
    .board-body { grid-template-columns: minmax(0, 1fr); }
    .board-side { grid-template-columns: repeat(2, minmax(0, 1fr)); border-left: 0; border-top: var(--divider); }
    .sdks { grid-template-columns: minmax(0, 1fr); gap: var(--space-8); }
    /* stacked, the box follows the answer on screen; the tallest one would leave a dark gap under short ones */
    .fx-panel:not(.is-current) { display: none; }
    /* the questions stay a list here too (the homepage turns its endpoints into a row of tabs) */
    .explorer--faq .ep-list { display: block; padding-inline: var(--pad); border-bottom: var(--divider); }
    .explorer--faq .ep { padding: var(--space-3) 0; white-space: normal; border-bottom: var(--divider); }
    .explorer--faq .ep::before { content: "\203A"; content: "\203A" / ""; }
    .explorer--faq .ep[aria-selected="true"]::after { content: none; }
    .explorer--faq .ep[aria-selected="true"] .p { translate: var(--space-4) 0; }
    .hero-top--product { grid-template-columns: minmax(0, 1fr) auto; }
    .hero-mark { width: calc(3 * var(--grid-cell)); margin-block: 0; }
    .hero-mark--figure { width: calc(4 * var(--grid-cell)); } /* a wide figure, as the about page's row of sources */
    .why-grid { grid-template-columns: minmax(0, 1fr); }
    .why-grid--bento { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .why-grid--bento > *, .why-grid--bento > :nth-child(-n + 2) { grid-column: auto; }
    .why-grid--bento > :first-child { grid-column: 1 / -1; }
    .why-card { flex-direction: row; }
    .why-art { flex: none; width: 40%; height: auto; min-height: 152px; border-bottom: 0; border-right: var(--divider); }
    /* in the bento's two columns only the wide first card puts its picture beside its text */
    .why-grid--bento > :not(:first-child) { flex-direction: column; }
    .why-grid--bento > :not(:first-child) > .why-art { width: auto; border-right: 0; border-bottom: var(--divider); }
    .ep-view { flex: none; height: 440px; }
    .foot { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .foot > div:first-child { grid-column: 1 / -1; }
    .legal { grid-template-columns: 1fr; }
}
@media (max-width: 768px) {
    /* the copyright stands on its own line, the legal links follow in one row */
    .legal nav span { flex-basis: 100%; }
    /* a board's date or stamp always takes its own line, right under the title */
    .board-title { flex-direction: column; align-items: flex-start; gap: var(--space-0-5); }
    /* the trending board keeps its switches on one row: the type switch, then the window as a select at the end */
    .board--rank .board-ctl { width: 100%; flex-wrap: nowrap; justify-content: space-between; }
    .board--rank .board-ctl > .seg:has(+ .select) { display: none; }
    .board--rank .board-ctl > .select { display: inline-flex; }
    /* the figures of the questions stack; the next button keeps its short label */
    .fx-fig { height: auto; min-height: 280px; padding: var(--space-8) var(--pad); }
    :root { --gutter: var(--space-4); --nav-top: var(--space-2); --nav-h: 56px; --section-y: 72px; --pad: var(--space-4); --pad-lg: var(--pad); --text-hero: clamp(var(--text-3xl), 10.5vw, var(--text-4xl)); }
    h2 { font-size: var(--text-3xl); }
    .nav-right .btn { display: none; }
    .nav-inner { gap: var(--space-3); padding: 0 var(--space-2) 0 var(--space-3-5); }
    /* the search field hides behind the search button and opens over the whole bar */
    .nav .search { display: none; width: auto; flex: 1; min-width: 0; }
    .search-toggle { display: grid; }
    .nav-inner.is-searching .nav-logo, .nav-inner.is-searching .menu-mobile { display: none; }
    .nav-inner.is-searching .search { display: flex; }
    .nav-right { flex: 1; min-width: 0; justify-content: flex-end; gap: var(--space-0-5); }
    .nav-inner.is-searching .nav-right { gap: var(--space-2); }
    .nav-logo img { height: 27px; }
    .search kbd { display: none; }
    .search--fill { flex-basis: 100%; }
    .mega-inner { grid-template-columns: 1fr; }
    .hero { padding: 36px 0 var(--space-8); }
    .hero .hero-top + * { margin-top: var(--space-8); }
    .block-head { margin-bottom: var(--space-8); }
    .logo-marquee { --logo-scale: 1.1; }
    .tile--step { --s: var(--s-step); }
    .fig--xl { font-size: var(--text-6xl); }
    .fig--lg { font-size: var(--text-5xl); }
    .closing { grid-template-columns: 1fr; padding: 0 0 var(--space-8); gap: var(--space-8); }
    .closing--end { padding-bottom: var(--section-y); } /* the band before the footer keeps the section spacing under its actions */
    .closing-points, .points, .points:not(.points--grid) { grid-template-columns: 1fr; row-gap: 0; }
    :is(.closing-points, .points) li, :is(.closing-points, .points) li + li { padding: 18px 0; border-left: 0; }
    :is(.closing-points, .points) li + li { border-top: var(--divider); }
    .doc-head h1 { font-size: var(--text-3xl); }
    .board--rank { --tr-cols: 20px minmax(0, 1fr) 52px 60px 56px; }
    .board--rank .tr-row { gap: var(--space-2-5); }
    /* the mark steps behind the head as a faint watermark, as on the live product pages */
    .hero-top--product { position: relative; grid-template-columns: minmax(0, 1fr); }
    /* --center aligns left here, as every product hero on a phone */
    .hero-top--center { justify-items: stretch; text-align: left; }
    .hero-top--center .lead { margin-inline: 0; }
    .hero-top--center .hero-actions { justify-content: flex-start; }
    .hero-top--product > .hero-head { position: relative; z-index: 1; }
    /* centred on 40% of the head by its own height, square or not; transform, since the reveal owns translate */
    .hero-mark { position: absolute; top: 40%; right: calc(-1 * var(--space-10)); width: calc(3.5 * var(--grid-cell)); transform: translateY(-50%); pointer-events: none; }
    .hero-mark > * { opacity: 0.08; }
    /* a --figure mark keeps a part in the flow at full strength, the hero's gap under the actions, as tall as its
       picture. It fades in without the reveal's blur and shift, which would carry along what it places against the hero */
    .hero-mark--figure { position: static; width: 100%; aspect-ratio: auto; margin: 0; transform: none; pointer-events: auto; }
    .hero-mark--figure > * { opacity: 1; }
    .reveal-on .hero-mark--figure.rv { filter: none; translate: none; }
    .why-card { flex-direction: column; }
    .why-grid--bento { grid-template-columns: minmax(0, 1fr); }
    .why-grid--bento > :first-child { grid-column: auto; }
    .why-art { width: auto; border-right: 0; border-bottom: var(--divider); }
    .board--rank .tr-row > :nth-child(6) { display: none; }
    .board--rank .tr-row > :nth-child(5) .tip { left: auto; right: 0; translate: none; } /* sentiment is the last column here */
    /* a head tip spans the head row on phones, so it never runs off the screen */
    .tr-head { position: relative; }
    .tr-head > .has-tip { position: static; }
    .board .tr-head > .has-tip > .tip { right: var(--pad); left: var(--pad); width: auto; max-width: none; translate: none; }
    .board--rank :is(.tr-stock, .tr-num) small { display: none; }
    .board-side { grid-template-columns: minmax(0, 1fr); }
    .board--rank .box-foot > code { display: none; } /* phones keep the link to the full ranking, not the call */
    /* phones: the name over its install line, the copy button beside both */
    .sdk-list li { grid-template-columns: minmax(0, 1fr) auto; row-gap: var(--space-1); }
    .sdk-list code { grid-row: 2; white-space: normal; overflow-wrap: anywhere; } /* a long install line (Go) wraps instead of hiding its end */
    .sdk-list .field-copy { grid-area: 1 / 2 / 3 / 3; }
    .sdk-list--files .sdk-d { grid-row: 2; grid-column: 1 / -1; }
    .prose h2 { font-size: var(--text-xl); }
    .kv--cols > * { grid-template-columns: minmax(0, 1fr); }
    .closing h2 { font-size: var(--text-3xl); }
    .closing .mark { width: 150px; justify-self: start; grid-row: 1; }
    .sticky-cta { display: flex; }
}

@media (max-width: 400px) {
    .sticky-cta span { overflow: hidden; text-overflow: ellipsis; }
}
/* under 480px a rank board drops its rank, the order of the rows still says it. The ticker takes that room with its
   logo a step smaller and narrower gaps, so a long ticker such as GOOGL or FARTCOIN ends before the buzz. After the
   phone block, which sets the board's columns; a page class such as mv-board sets its own after this sheet */
@media (max-width: 480px) {
    .board--rank { --tr-cols: minmax(0, 1fr) 52px 60px 56px; }
    .board--rank .tr-row { gap: var(--space-2); }
    .board--rank .tr-row > :first-child { display: none; }
    .board--rank .tr-stock > .ident { gap: var(--space-2); --s: var(--logo-xs); }
}
@media (max-width: 360px) {
    .board--rank .tr-row, .board--rank .tr-stock > .ident { gap: var(--space-1-5); }
}

/* ---------- Product pages (one API per source) ----------
   Hero as on the homepage with a live trending board in place of the machine, then why, how (dark), endpoints with a
   real response for each, pricing and questions. */

/* how: the Adanos mark builds itself. Each of the first four steps lands its plate, bottom up from the silver collect
   plate to the gold aggregate plate; serve is no plate. The about page runs four steps, its last one the gold plate.
   The steps run in a row under it, on a rail that fills to the step that is on */
.build { --run: 2.8s; position: relative; display: grid; justify-items: center; gap: var(--space-14); }
/* serve: the answer leaves the finished mark along a line to the tag, with the request packets of the key band */
.build > .kb-lines { opacity: 0; transition: opacity var(--dur) ease-out; }
.build.is-serve > .kb-lines { opacity: 1; }
.build:not(.is-serve) > .kb-pks { display: none; }
.build-mark { width: 230px; height: auto; overflow: visible; }
/* every plate cuts the logo's gap into the plate under it, the gold one too */
.build-plate use { stroke: var(--graphite); stroke-width: 16; paint-order: stroke; }
.build-plate { transition: opacity var(--dur) ease-out, translate var(--dur-slow) var(--ease-out-expo); }
/* where the loop runs (wide screens with motion), a plate waits below its place until its step comes. The page starts
   in that state, so the script changes nothing on load */
@media (min-width: 769px) and (prefers-reduced-motion: no-preference) { .build-plate:not(.is-in) { opacity: 0; translate: 0 44px; } }
/* the track: the rail with the steps' nodes, gold up to the step that is on, and the tag that rides it */
.build-track { --gap: var(--space-6); position: relative; width: 100%; }
/* --steps: the count of steps, five on the product pages, four on the about page */
.build-steps { position: relative; display: grid; grid-template-columns: repeat(var(--steps, 5), minmax(0, 1fr)); column-gap: var(--gap); padding-top: var(--space-6); }
.build-steps::before, .build-steps::after { content: ""; position: absolute; top: 0; left: 0; height: 1px; }
.build-steps::before { width: calc((100% + var(--gap)) / var(--steps, 5) * (var(--steps, 5) - 1)); background: var(--dark-edge); } /* from the first node to the last */
.build-steps::after { width: calc((100% + var(--gap)) / var(--steps, 5) * var(--n, 0)); background: var(--code-gold); transition: width var(--dur-slow) var(--ease-out-expo); }
@media (prefers-reduced-motion: no-preference) { .build-tag { transition: left var(--dur-slow) var(--ease-out-expo); } }
.build-step { position: relative; }
.build-step :is(h3, p) { transition: color var(--dur) ease-out; }
/* where the loop runs, a step still to come reads in the muted ink, which keeps 4.5:1 */
@media (min-width: 769px) and (prefers-reduced-motion: no-preference) { .build-step:not(.is-now, .is-done) :is(h3, p) { color: var(--muted); } }
/* on wide screens the examples ride in the tag, so none shows under its step, not even before the script moves them */
@media (min-width: 769px) { .build-step > .build-eg { display: none; } }
.build-node { position: absolute; z-index: 1; top: calc(var(--space-6) * -1 - var(--dot) / 2); left: 0; width: var(--dot); height: var(--dot); border-radius: var(--r-round); background: var(--silver); transition: background-color var(--dur) ease-out, box-shadow var(--dur) ease-out; }
.build-step:is(.is-now, .is-done) .build-node { background: var(--code-gold); }
.build-step.is-now .build-node { box-shadow: 0 0 0 var(--space-1-5) var(--tint-gold); }
.build-step h3 { display: flex; align-items: baseline; gap: var(--space-2); }
.build-step h3 span { letter-spacing: 0; font-variant-numeric: tabular-nums; transition: color var(--dur) ease-out; }
.build-step.is-now h3 span { color: var(--code-gold); }
.build-step p { margin-top: var(--space-1-5); font-size: var(--text-sm); color: var(--ink-2); text-wrap: pretty; }
/* an example: what a step made of one real TSLA comment. On wide screens the script moves the examples into the tag,
   which rides above the rail with its stem on the node of the step that is on and stays inside the row (the script sets
   left and --stem). On phones each example stays under its step. */
.build-tag { position: absolute; z-index: 1; bottom: calc(100% + var(--space-5)); left: 0; }
.build-tag::after { content: ""; position: absolute; top: 100%; left: var(--stem, var(--space-3)); width: 1px; height: var(--space-5); background: var(--code-gold); }
.build-eg { display: flex; align-items: center; gap: var(--space-1-5); padding: var(--space-1) var(--space-2-5); border-radius: var(--r-xs); background: var(--dark-edge); font-size: var(--text-xs); line-height: var(--lh-title); white-space: nowrap; color: var(--paper); --s: var(--logo-xs); }
.build-eg .arw { color: var(--muted); }
.build-eg .m { color: var(--code-gold); }
.build-eg .k { color: var(--ink-2); }
.build-eg .s { color: var(--code-gold); }
.build-eg .n { color: var(--code-coral); }
.build-eg b { font-weight: var(--fw-medium); }
/* serve: the API's answer as a small code block */
.build-eg code { display: block; padding-block: var(--space-1); font-family: var(--mono); line-height: var(--lh-body); white-space: pre; color: var(--dark-body); }

/* one key, every source: from the key chip a line runs to every source API (product-2026.js draws them from the
   layout); requests travel along the lines and light a source up as they arrive. YouTube is dashed, without traffic */
.keyband { --run: 2.8s; position: relative; display: grid; grid-template-columns: minmax(0, 5fr) minmax(var(--space-16), 2fr) minmax(0, 4fr); align-items: center; margin-top: var(--space-4); padding: var(--pad-lg); background: var(--dark); border: var(--border); border-radius: var(--r-box); color: var(--paper); }
.kb-text p { max-width: 40ch; margin-top: var(--space-2); font-size: var(--text-md); color: var(--ink-2); }
.kb-chip { display: inline-flex; gap: var(--space-2); margin-top: var(--space-5); padding: var(--space-2) var(--space-3); border: var(--border); border-radius: var(--r); background: var(--bg); font-family: var(--mono); font-size: var(--text-xs); color: var(--ink); }
.kb-chip .m { color: var(--code-gold); }
.kb-lines { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
.kb-lines path { fill: none; stroke: var(--dark-line-2); stroke-width: 1.25; }
.kb-lines .is-soon { stroke-dasharray: 3 4; }
.kb-list { grid-column: 3; display: grid; gap: var(--space-2-5); }
.kb-src > :is(a, span) { display: flex; align-items: center; gap: var(--space-3); font-size: var(--text-sm); color: var(--paper); }
.kb-src b { font-weight: var(--fw-medium); }
.kb-src [aria-current] b { color: var(--paper); } /* this page's API */
.kb-src code { margin-left: auto; font-family: var(--mono); font-size: var(--text-xs); color: var(--muted); }
.kb-src .tag { margin-left: auto; }
.kb-tile { position: relative; z-index: 1; display: grid; border-radius: var(--r); }
.kb-src.is-soon .kb-tile { opacity: 0.45; filter: grayscale(1); }
@media (hover: hover) { .kb-src a { transition: color var(--dur-fast) ease-out; } .kb-src a:hover b { color: var(--paper); } }
.kb-pks { position: absolute; inset: 0; pointer-events: none; }
.kb-pk { position: absolute; top: 0; left: 0; width: var(--space-2-5); height: 3px; border-radius: var(--r-pill); background: var(--code-gold); filter: var(--glow-gold); offset-rotate: auto; opacity: 0; }
@media (prefers-reduced-motion: no-preference) {
    .kb-pk { animation: kb-run var(--run) linear var(--t) infinite; }
    @keyframes kb-run { 0% { offset-distance: 0%; opacity: 0; } 8%, 92% { opacity: 1; } 100% { offset-distance: 100%; opacity: 0; } }
    /* two requests per line, half a run apart: the source lights up as each one arrives */
    .kb-src.is-hit .kb-tile { animation: kb-hit var(--run) ease-out var(--t) infinite; }
    @keyframes kb-hit {
        0%, 50% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--gold) 70%, transparent); }
        15%, 65% { box-shadow: 0 0 0 var(--space-2-5) transparent; }
        49.9%, 100% { box-shadow: 0 0 0 0 transparent; }
    }
    /* down the left one request per line, so the tile lights once a run */
    .keyband.is-down .kb-src.is-hit .kb-tile { animation-name: kb-hit-one; }
    @keyframes kb-hit-one {
        0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--gold) 70%, transparent); }
        15% { box-shadow: 0 0 0 var(--space-2-5) transparent; }
        15.1%, 100% { box-shadow: 0 0 0 0 transparent; }
    }
    .keyband.is-paused :is(.kb-pk, .kb-tile) { animation-play-state: paused; }
}

/* ---------- Responsive ---------- */
@media (max-width: 1024px) {
    .build-track { --gap: var(--space-4); }
    .keyband { grid-template-columns: minmax(0, 4fr) minmax(var(--space-12), 1fr) minmax(0, 5fr); }
}
@media (max-width: 768px) {
    /* the steps run down a vertical rail, each with its example under its text; no loop runs and the mark stands complete */
    .build { gap: var(--space-8); }
    .build-mark { width: 120px; }
    .build-steps { grid-template-columns: minmax(0, 1fr); gap: var(--space-6); padding: 0 0 0 var(--space-6); }
    .build-eg { flex-wrap: wrap; width: fit-content; max-width: 100%; margin-top: var(--space-3); white-space: normal; }
    /* a piece of rail from each node to the next, so it ends at serve; gold once its step is done */
    .build-steps::before, .build-steps::after { display: none; }
    .build-step:not(:last-child)::after { content: ""; position: absolute; top: calc(var(--space-1-5) + var(--dot)); bottom: calc(-1 * (var(--space-6) + var(--space-1-5))); left: calc(var(--space-6) * -1 + var(--dot) / 2 - 0.5px); width: 1px; background: var(--dark-edge); transition: background-color var(--dur) ease-out; }
    .build-step.is-done::after { background: var(--code-gold); }
    .build-node { top: var(--space-1-5); left: calc(var(--space-6) * -1); background: var(--code-gold); }
    .keyband { grid-template-columns: minmax(0, 1fr); }
    .kb-list { grid-column: 1; margin-top: var(--space-6); padding-left: var(--space-10); } /* room for the line that runs down */
}
/* ---------- Stock dashboard (stock-2026.html) ----------
   Last in the sheet on purpose: these rules were the page's own <style>, read after every shared rule, so they
   still win each tie. None of them matches an element on another 2026 page. */
/* chart marks only the dashboard draws, and the hover readout */
.legend i.price { background: var(--graphite-2); }
.legend i.sent { width: var(--dot); height: var(--space-3); background: linear-gradient(var(--bull) 0 34%, var(--line-2) 0 66%, var(--bear) 0); }
/* no price data for this ticker: the panel keeps only its note */
.is-empty .legend { display: none; }
.sp-dot.street { background: var(--ink); }
.is-street .sp-track::after { content: none; }

/* ---------- Articles (insights: weekly reports, blog, data in action) ----------
   A content page (head, contents list, prose) plus the blocks articles carry. article-2026.html is built from a live
   article (scratchpad article/build.py); the chart and the stock card read recorded API data. */
.prose .art-card { margin-top: var(--space-5); }
.prose .art-card-head h3 { margin: 0; }
.prose .art-pcs { margin-block: var(--space-6); }
.prose .art-pc :is(.type-label, h3) { margin: 0 0 var(--space-3); }
.prose .art-pc:has(> .pos) :is(.type-label, h3) { color: var(--bull-ink); }
.prose .art-pc:has(> .neg) :is(.type-label, h3) { color: var(--bear-ink); }
