@import 'tailwindcss'; /* CancerIndex design language (CLAUDE.md UI rules): scientific / editorial / institutional / dense. Off-white paper, deep charcoal ink, muted neutrals, ONE restrained accent (deep teal) for links and active states, thin rules, tabular numerals. No gradients, no card grids, no decorative colour. Colour is never the sole carrier of meaning: every badge also carries text. */ @theme { --font-sans: var(--font-ui), ui-sans-serif, system-ui, sans-serif; --font-serif: var(--font-display), 'Iowan Old Style', Georgia, serif; --font-mono: var(--font-code), ui-monospace, 'SF Mono', Menlo, monospace; --color-paper: #fafaf7; --color-paper-2: #f3f3ee; --color-paper-3: #ebebe4; --color-ink: #1c1c1a; --color-ink-2: #4a4a46; --color-ink-3: #7b7b75; --color-ink-4: #a8a8a1; --color-rule: #dcdcd4; --color-rule-strong: #b8b8ae; --color-accent: #0f5f63; --color-accent-2: #0b4a4d; --color-accent-soft: #e2eeee; --color-warn: #8a4b0a; --color-warn-soft: #f6ead8; --color-danger: #8b1e2d; --color-danger-soft: #f4e1e4; --color-ok: #2d5f2e; --color-ok-soft: #e1ecdf; --color-series-1: #0f5f63; --color-series-2: #8a4b0a; --color-series-3: #4a4a46; --color-series-4: #2d5f2e; --color-series-5: #8b1e2d; --color-series-6: #7b7b75; --color-series-7: #5b3a8c; --color-series-8: #1f5fa8; --radius-sm: 2px; --radius-md: 3px; } /* Dark mode (SPEC §86). Same tokens, inverted values; charts and badges reference the tokens only. `--color-white` is re-pointed so Tailwind's `bg-white` form controls follow the theme. Applied when the user chose "dark" (data-theme) or follows the OS preference (no explicit choice). */ :root[data-theme='dark'], :root:not([data-theme='light']):not([data-theme='dark']).ci-system-dark { color-scheme: dark; --color-paper: #151514; --color-paper-2: #1d1d1b; --color-paper-3: #282826; --color-ink: #ecece6; --color-ink-2: #c3c3bb; --color-ink-3: #8f8f88; --color-ink-4: #626259; --color-rule: #2f2f2c; --color-rule-strong: #47473f; --color-accent: #6cc3c6; --color-accent-2: #8fd3d5; --color-accent-soft: #16353a; --color-warn: #e0a860; --color-warn-soft: #3a2a13; --color-danger: #ee8a95; --color-danger-soft: #3f1c22; --color-ok: #93c692; --color-ok-soft: #1d301d; --color-white: #1d1d1b; --color-series-1: #6cc3c6; --color-series-2: #e0a860; --color-series-3: #b9b9b1; --color-series-4: #93c692; --color-series-5: #ee8a95; --color-series-6: #8f8f88; --color-series-7: #b39ddb; --color-series-8: #7fb2ea; } @media (prefers-color-scheme: dark) { :root:not([data-theme='light']) { color-scheme: dark; --color-paper: #151514; --color-paper-2: #1d1d1b; --color-paper-3: #282826; --color-ink: #ecece6; --color-ink-2: #c3c3bb; --color-ink-3: #8f8f88; --color-ink-4: #626259; --color-rule: #2f2f2c; --color-rule-strong: #47473f; --color-accent: #6cc3c6; --color-accent-2: #8fd3d5; --color-accent-soft: #16353a; --color-warn: #e0a860; --color-warn-soft: #3a2a13; --color-danger: #ee8a95; --color-danger-soft: #3f1c22; --color-ok: #93c692; --color-ok-soft: #1d301d; --color-white: #1d1d1b; --color-series-1: #6cc3c6; --color-series-2: #e0a860; --color-series-3: #b9b9b1; --color-series-4: #93c692; --color-series-5: #ee8a95; --color-series-6: #8f8f88; --color-series-7: #b39ddb; --color-series-8: #7fb2ea; } } :root { color-scheme: light; --ci-header-h: 56px; } html { background: var(--color-paper); color: var(--color-ink); font-family: var(--font-sans); font-size: 15px; line-height: 1.5; -webkit-text-size-adjust: 100%; scroll-padding-top: calc(var(--ci-header-h) + 56px); } body { font-variant-numeric: tabular-nums; font-feature-settings: 'tnum' 1, 'cv11' 1; text-rendering: optimizeLegibility; } h1, h2, h3, .font-display { font-family: var(--font-serif); font-weight: 500; letter-spacing: -0.005em; text-wrap: balance; } a { text-underline-offset: 2px; } :focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; } ::selection { background: var(--color-accent-soft); } /* Grid children default to min-width:auto, so a wide SVG, a long identifier or a mono formula would stretch a column past the viewport on mobile. Let columns shrink; inner tables scroll inside .ci-table-wrap and long strings wrap through overflow-wrap. */ .grid > * { min-width: 0; } code, kbd, .ci-mono { overflow-wrap: anywhere; } /* --- Utility classes shared by components (kept minimal; Tailwind does the rest) --- */ .ci-link { color: var(--color-accent); text-decoration: underline; text-decoration-color: color-mix(in oklab, var(--color-accent) 35%, transparent); } .ci-link:hover { text-decoration-color: var(--color-accent); } .ci-rule { border-top: 1px solid var(--color-rule); } .ci-kicker { font-family: var(--font-sans); font-size: 11px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--color-ink-3); } .ci-mono { font-family: var(--font-mono); font-size: 0.86em; letter-spacing: 0; } .ci-num { font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; } /* Dense data table */ .ci-table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; border-top: 1px solid var(--color-rule-strong); border-bottom: 1px solid var(--color-rule); } .ci-table { width: 100%; min-width: 100%; border-collapse: separate; border-spacing: 0; font-size: 13.5px; } .ci-table thead th { position: sticky; top: 0; z-index: 1; background: var(--color-paper); border-bottom: 1px solid var(--color-rule-strong); padding: 8px 10px; text-align: left; font-family: var(--font-sans); font-size: 11px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--color-ink-3); white-space: nowrap; } .ci-table thead th.num, .ci-table td.num { text-align: right; } .ci-table tbody td { padding: 7px 10px; border-bottom: 1px solid var(--color-rule); vertical-align: top; } .ci-table tbody tr:hover td { background: var(--color-paper-2); } .ci-table th.sticky-col, .ci-table td.sticky-col { position: sticky; left: 0; background: var(--color-paper); z-index: 2; } /* Sticky in-page tabs */ .ci-tabs { position: sticky; top: var(--ci-header-h); z-index: 20; background: color-mix(in oklab, var(--color-paper) 94%, transparent); backdrop-filter: saturate(120%) blur(6px); border-bottom: 1px solid var(--color-rule); overflow-x: auto; scrollbar-width: none; } .ci-tabs::-webkit-scrollbar { display: none; } .ci-tab { display: inline-block; padding: 10px 2px; margin-right: 18px; font-size: 13.5px; color: var(--color-ink-2); border-bottom: 2px solid transparent; white-space: nowrap; } .ci-tab:hover { color: var(--color-ink); } .ci-tab[aria-current='page'] { color: var(--color-accent); border-bottom-color: var(--color-accent); font-weight: 500; } /* Popover used for provenance (CSS-only, hover + focus) */ .ci-pop { position: relative; display: inline-block; } .ci-pop > .ci-pop-panel { display: none; position: absolute; z-index: 40; left: 0; top: calc(100% + 4px); min-width: 260px; max-width: 360px; background: var(--color-paper); border: 1px solid var(--color-rule-strong); box-shadow: 0 6px 24px -10px rgba(0, 0, 0, 0.35); padding: 10px 12px; font-size: 12.5px; line-height: 1.45; text-align: left; white-space: normal; font-weight: 400; text-transform: none; letter-spacing: 0; color: var(--color-ink); } .ci-pop:hover > .ci-pop-panel, .ci-pop:focus-within > .ci-pop-panel { display: block; } @media (max-width: 640px) { .ci-pop > .ci-pop-panel { position: fixed; left: 12px; right: 12px; top: auto; bottom: 12px; max-width: none; } } /* Completeness dots */ .ci-dots { display: inline-flex; gap: 3px; vertical-align: middle; } .ci-dot { width: 7px; height: 7px; border-radius: 50%; border: 1px solid var(--color-ink-4); background: transparent; } .ci-dot.on { background: var(--color-accent); border-color: var(--color-accent); } details > summary { cursor: pointer; list-style: none; } details > summary::-webkit-details-marker { display: none; } .ci-prose p + p { margin-top: 0.75em; } .ci-prose h2 { font-size: 1.35rem; margin-top: 2rem; margin-bottom: 0.5rem; } .ci-prose h3 { font-size: 1.1rem; margin-top: 1.4rem; margin-bottom: 0.35rem; } .ci-prose ul { list-style: disc; padding-left: 1.25rem; margin: 0.5rem 0; } .ci-prose li + li { margin-top: 0.25rem; } .ci-prose code { font-family: var(--font-mono); font-size: 0.85em; background: var(--color-paper-3); padding: 0 4px; } pre.ci-code { font-family: var(--font-mono); font-size: 12.5px; line-height: 1.5; background: var(--color-paper-2); border: 1px solid var(--color-rule); padding: 10px 12px; overflow-x: auto; white-space: pre; } @media print { .no-print { display: none !important; } } /* ------------------------------------------------------------------------------------------------ Hardening pass (pagination, table weight, accessibility). Appended; nothing above is rewritten. ------------------------------------------------------------------------------------------------ */ /* Badges: one short class per tone instead of a long utility string repeated on every table row (every className ships twice — HTML + RSC payload). Text always accompanies the colour. */ .ci-badge { display: inline-flex; align-items: center; gap: 4px; border: 1px solid transparent; border-radius: var(--radius-sm); padding: 1px 6px; font-size: 11px; font-weight: 500; line-height: 16px; letter-spacing: 0.02em; } .ci-badge--neutral { background: var(--color-paper-3); color: var(--color-ink-2); } .ci-badge--accent { background: var(--color-accent-soft); color: var(--color-accent-2); } .ci-badge--warn { background: var(--color-warn-soft); color: var(--color-warn); } .ci-badge--danger { background: var(--color-danger-soft); color: var(--color-danger); } .ci-badge--ok { background: var(--color-ok-soft); color: var(--color-ok); } .ci-badge--outline { background: transparent; color: var(--color-ink-2); border-color: var(--color-rule-strong); } /* Source badge link (compact rows and popover trigger share one class) */ .ci-src { font-family: var(--font-mono); display: inline-flex; align-items: center; border: 1px solid var(--color-rule-strong); border-radius: var(--radius-sm); background: var(--color-paper); padding: 0 4px; font-size: 10.5px; line-height: 16px; color: var(--color-ink-2); text-decoration: none; white-space: nowrap; } .ci-src:hover, .ci-src:focus-visible { border-color: var(--color-accent); color: var(--color-accent); } /* Pager */ .ci-pager-link { display: inline-block; min-width: 28px; border: 1px solid var(--color-rule); padding: 4px 8px; text-align: center; color: var(--color-ink-2); text-decoration: none; line-height: 1.2; } .ci-pager-link:hover { border-color: var(--color-accent); color: var(--color-accent); } .ci-pager-link.is-current { border-color: var(--color-accent); background: var(--color-accent-soft); color: var(--color-accent-2); font-weight: 500; } .ci-pager-link.is-disabled { color: var(--color-ink-4); cursor: default; } /* Filter chips (status / phase / cohort / jurisdiction selectors) */ .ci-chip { display: inline-block; border: 1px solid var(--color-rule); padding: 2px 8px; color: var(--color-ink-2); text-decoration: none; line-height: 1.35; } .ci-chip:hover { border-color: var(--color-accent); } .ci-chip[aria-current='page'], .ci-chip.is-selected { border-color: var(--color-accent); background: var(--color-accent-soft); color: var(--color-accent-2); } /* Focus visibility: links inside dense tables, tabs, chips and pager get a visible ring even when the surrounding element clips overflow (outline-offset 0 keeps the ring inside table cells). */ .ci-tab:focus-visible, .ci-chip:focus-visible, .ci-pager-link:focus-visible, .ci-src:focus-visible, .ci-table a:focus-visible, .ci-table summary:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 0; border-radius: 2px; } .ci-tabs a:focus-visible { outline-offset: -2px; } details > summary:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; } /* Table captions live above the table (visible text, not sr-only) — the caption is the place where the ONE provenance popover per table sits. */ .ci-table caption { caption-side: top; text-align: left; padding: 0 0 6px; font-size: 12px; color: var(--color-ink-3); } .ci-table thead th[aria-sort] { cursor: default; } /* Skeletons (loading.tsx) — never look like data */ .ci-skeleton { background: linear-gradient(90deg, var(--color-paper-3) 0%, var(--color-paper-2) 50%, var(--color-paper-3) 100%); background-size: 200% 100%; border-radius: 2px; animation: ci-shimmer 1.4s ease-in-out infinite; } @keyframes ci-shimmer { from { background-position: 200% 0; } to { background-position: -200% 0; } } @media (prefers-reduced-motion: reduce) { .ci-skeleton { animation: none; } } /* Keep the sticky provenance popover reachable by keyboard users: the panel becomes visible while any element inside is focused (focus-within already covers the trigger). */ .ci-pop:focus-within > .ci-pop-panel { display: block; } /* Row-group header inside a single dense table (one per variant / cancer group) */ .ci-table tr.ci-group th { position: static; background: var(--color-paper-2); border-top: 1px solid var(--color-rule-strong); border-bottom: 1px solid var(--color-rule); padding: 7px 10px; text-align: left; font-family: var(--font-sans); font-size: 13.5px; font-weight: 500; letter-spacing: 0; text-transform: none; color: var(--color-ink); white-space: normal; overflow-wrap: anywhere; } .ci-table tbody:first-of-type tr.ci-group th { border-top: 0; } .ci-evidence td.w-t { min-width: 160px; } abbr.no-underline { text-decoration: none; } /* Compact list rows (e.g. variants on a gene page): link left, meta right */ .ci-rows { margin: 0; padding: 0; list-style: none; font-size: 13.5px; } .ci-rows > li { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; border-bottom: 1px solid var(--color-rule); padding: 4px 0; } .ci-rows > li > span { font-size: 11.5px; color: var(--color-ink-3); text-align: right; } /* Publication list */ .ci-pubs { margin: 0; padding: 0; list-style: none; } .ci-pub { padding: 10px 0; border-bottom: 1px solid var(--color-rule); font-size: 13.5px; } .ci-pub > div { display: flex; flex-wrap: wrap; align-items: baseline; column-gap: 8px; } .ci-pub > p { margin-top: 2px; font-size: 12.5px; color: var(--color-ink-3); } /* Evidence table: link, level and details styles are scoped here instead of per-cell classes (50 rows × ~8 classes × 2 copies per page). */ .ci-evidence a { color: var(--color-accent); text-decoration: underline; text-decoration-color: color-mix(in oklab, var(--color-accent) 35%, transparent); } .ci-evidence a:hover { text-decoration-color: var(--color-accent); } .ci-evidence tr.ci-group a.ci-mono { color: var(--color-ink-3); text-decoration: none; } .ci-evidence tr.ci-group a.ci-mono:hover { color: var(--color-accent); } .ci-evidence abbr { font-family: var(--font-mono); font-size: 0.86em; font-weight: 500; text-decoration: none; } .ci-evidence td.ev { max-width: 360px; font-size: 12.5px; color: var(--color-ink-2); } .ci-evidence td.ev summary { color: var(--color-accent); text-decoration: underline; text-decoration-color: color-mix(in oklab, var(--color-accent) 35%, transparent); } .ci-evidence td.ev details p { margin-top: 4px; } /* Theme toggle (header) */ .ci-theme-toggle { display: inline-flex; align-items: center; gap: 4px; border: 1px solid var(--color-rule); padding: 5px 7px; color: var(--color-ink-2); background: transparent; cursor: pointer; line-height: 1; } .ci-theme-toggle:hover { border-color: var(--color-accent); color: var(--color-accent); }