SPB Git forge

spb/cancerindex

Public
37commits 1branches 0releases
2.9 MBsize
maindefault branch
10 days agolast push
TypeScript 97.2% SQL 1.5% CSS 0.6% JavaScript 0.5%
16.1 KB · 698 lines css
Raw Blame History
1@import 'tailwindcss';23/*4  CancerIndex design language (CLAUDE.md UI rules): scientific / editorial / institutional / dense.5  Off-white paper, deep charcoal ink, muted neutrals, ONE restrained accent (deep teal) for links and6  active states, thin rules, tabular numerals. No gradients, no card grids, no decorative colour.7  Colour is never the sole carrier of meaning: every badge also carries text.8*/910@theme {11  --font-sans: var(--font-ui), ui-sans-serif, system-ui, sans-serif;12  --font-serif: var(--font-display), 'Iowan Old Style', Georgia, serif;13  --font-mono: var(--font-code), ui-monospace, 'SF Mono', Menlo, monospace;1415  --color-paper: #fafaf7;16  --color-paper-2: #f3f3ee;17  --color-paper-3: #ebebe4;18  --color-ink: #1c1c1a;19  --color-ink-2: #4a4a46;20  --color-ink-3: #7b7b75;21  --color-ink-4: #a8a8a1;22  --color-rule: #dcdcd4;23  --color-rule-strong: #b8b8ae;24  --color-accent: #0f5f63;25  --color-accent-2: #0b4a4d;26  --color-accent-soft: #e2eeee;27  --color-warn: #8a4b0a;28  --color-warn-soft: #f6ead8;29  --color-danger: #8b1e2d;30  --color-danger-soft: #f4e1e4;31  --color-ok: #2d5f2e;32  --color-ok-soft: #e1ecdf;3334  --color-series-1: #0f5f63;35  --color-series-2: #8a4b0a;36  --color-series-3: #4a4a46;37  --color-series-4: #2d5f2e;38  --color-series-5: #8b1e2d;39  --color-series-6: #7b7b75;40  --color-series-7: #5b3a8c;41  --color-series-8: #1f5fa8;4243  --radius-sm: 2px;44  --radius-md: 3px;45}4647/*48  Dark mode (SPEC §86). Same tokens, inverted values; charts and badges reference the tokens only.49  `--color-white` is re-pointed so Tailwind's `bg-white` form controls follow the theme.50  Applied when the user chose "dark" (data-theme) or follows the OS preference (no explicit choice).51*/52:root[data-theme='dark'],53:root:not([data-theme='light']):not([data-theme='dark']).ci-system-dark {54  color-scheme: dark;55  --color-paper: #151514;56  --color-paper-2: #1d1d1b;57  --color-paper-3: #282826;58  --color-ink: #ecece6;59  --color-ink-2: #c3c3bb;60  --color-ink-3: #8f8f88;61  --color-ink-4: #626259;62  --color-rule: #2f2f2c;63  --color-rule-strong: #47473f;64  --color-accent: #6cc3c6;65  --color-accent-2: #8fd3d5;66  --color-accent-soft: #16353a;67  --color-warn: #e0a860;68  --color-warn-soft: #3a2a13;69  --color-danger: #ee8a95;70  --color-danger-soft: #3f1c22;71  --color-ok: #93c692;72  --color-ok-soft: #1d301d;73  --color-white: #1d1d1b;74  --color-series-1: #6cc3c6;75  --color-series-2: #e0a860;76  --color-series-3: #b9b9b1;77  --color-series-4: #93c692;78  --color-series-5: #ee8a95;79  --color-series-6: #8f8f88;80  --color-series-7: #b39ddb;81  --color-series-8: #7fb2ea;82}83@media (prefers-color-scheme: dark) {84  :root:not([data-theme='light']) {85    color-scheme: dark;86    --color-paper: #151514;87    --color-paper-2: #1d1d1b;88    --color-paper-3: #282826;89    --color-ink: #ecece6;90    --color-ink-2: #c3c3bb;91    --color-ink-3: #8f8f88;92    --color-ink-4: #626259;93    --color-rule: #2f2f2c;94    --color-rule-strong: #47473f;95    --color-accent: #6cc3c6;96    --color-accent-2: #8fd3d5;97    --color-accent-soft: #16353a;98    --color-warn: #e0a860;99    --color-warn-soft: #3a2a13;100    --color-danger: #ee8a95;101    --color-danger-soft: #3f1c22;102    --color-ok: #93c692;103    --color-ok-soft: #1d301d;104    --color-white: #1d1d1b;105    --color-series-1: #6cc3c6;106    --color-series-2: #e0a860;107    --color-series-3: #b9b9b1;108    --color-series-4: #93c692;109    --color-series-5: #ee8a95;110    --color-series-6: #8f8f88;111    --color-series-7: #b39ddb;112    --color-series-8: #7fb2ea;113  }114}115116:root {117  color-scheme: light;118  --ci-header-h: 56px;119}120121html {122  background: var(--color-paper);123  color: var(--color-ink);124  font-family: var(--font-sans);125  font-size: 15px;126  line-height: 1.5;127  -webkit-text-size-adjust: 100%;128  scroll-padding-top: calc(var(--ci-header-h) + 56px);129}130131body {132  font-variant-numeric: tabular-nums;133  font-feature-settings: 'tnum' 1, 'cv11' 1;134  text-rendering: optimizeLegibility;135}136137h1,138h2,139h3,140.font-display {141  font-family: var(--font-serif);142  font-weight: 500;143  letter-spacing: -0.005em;144  text-wrap: balance;145}146147a {148  text-underline-offset: 2px;149}150151:focus-visible {152  outline: 2px solid var(--color-accent);153  outline-offset: 2px;154}155156::selection {157  background: var(--color-accent-soft);158}159160/*161  Grid children default to min-width:auto, so a wide SVG, a long identifier or a mono formula162  would stretch a column past the viewport on mobile. Let columns shrink; inner tables scroll163  inside .ci-table-wrap and long strings wrap through overflow-wrap.164*/165.grid > * {166  min-width: 0;167}168code,169kbd,170.ci-mono {171  overflow-wrap: anywhere;172}173174/* --- Utility classes shared by components (kept minimal; Tailwind does the rest) --- */175176.ci-link {177  color: var(--color-accent);178  text-decoration: underline;179  text-decoration-color: color-mix(in oklab, var(--color-accent) 35%, transparent);180}181.ci-link:hover {182  text-decoration-color: var(--color-accent);183}184185.ci-rule {186  border-top: 1px solid var(--color-rule);187}188189.ci-kicker {190  font-family: var(--font-sans);191  font-size: 11px;192  font-weight: 600;193  letter-spacing: 0.08em;194  text-transform: uppercase;195  color: var(--color-ink-3);196}197198.ci-mono {199  font-family: var(--font-mono);200  font-size: 0.86em;201  letter-spacing: 0;202}203204.ci-num {205  font-variant-numeric: tabular-nums;206  text-align: right;207  white-space: nowrap;208}209210/* Dense data table */211.ci-table-wrap {212  overflow-x: auto;213  -webkit-overflow-scrolling: touch;214  border-top: 1px solid var(--color-rule-strong);215  border-bottom: 1px solid var(--color-rule);216}217.ci-table {218  width: 100%;219  min-width: 100%;220  border-collapse: separate;221  border-spacing: 0;222  font-size: 13.5px;223}224.ci-table thead th {225  position: sticky;226  top: 0;227  z-index: 1;228  background: var(--color-paper);229  border-bottom: 1px solid var(--color-rule-strong);230  padding: 8px 10px;231  text-align: left;232  font-family: var(--font-sans);233  font-size: 11px;234  font-weight: 600;235  letter-spacing: 0.06em;236  text-transform: uppercase;237  color: var(--color-ink-3);238  white-space: nowrap;239}240.ci-table thead th.num,241.ci-table td.num {242  text-align: right;243}244.ci-table tbody td {245  padding: 7px 10px;246  border-bottom: 1px solid var(--color-rule);247  vertical-align: top;248}249.ci-table tbody tr:hover td {250  background: var(--color-paper-2);251}252.ci-table th.sticky-col,253.ci-table td.sticky-col {254  position: sticky;255  left: 0;256  background: var(--color-paper);257  z-index: 2;258}259260/* Sticky in-page tabs */261.ci-tabs {262  position: sticky;263  top: var(--ci-header-h);264  z-index: 20;265  background: color-mix(in oklab, var(--color-paper) 94%, transparent);266  backdrop-filter: saturate(120%) blur(6px);267  border-bottom: 1px solid var(--color-rule);268  overflow-x: auto;269  scrollbar-width: none;270}271.ci-tabs::-webkit-scrollbar {272  display: none;273}274.ci-tab {275  display: inline-block;276  padding: 10px 2px;277  margin-right: 18px;278  font-size: 13.5px;279  color: var(--color-ink-2);280  border-bottom: 2px solid transparent;281  white-space: nowrap;282}283.ci-tab:hover {284  color: var(--color-ink);285}286.ci-tab[aria-current='page'] {287  color: var(--color-accent);288  border-bottom-color: var(--color-accent);289  font-weight: 500;290}291292/* Popover used for provenance (CSS-only, hover + focus) */293.ci-pop {294  position: relative;295  display: inline-block;296}297.ci-pop > .ci-pop-panel {298  display: none;299  position: absolute;300  z-index: 40;301  left: 0;302  top: calc(100% + 4px);303  min-width: 260px;304  max-width: 360px;305  background: var(--color-paper);306  border: 1px solid var(--color-rule-strong);307  box-shadow: 0 6px 24px -10px rgba(0, 0, 0, 0.35);308  padding: 10px 12px;309  font-size: 12.5px;310  line-height: 1.45;311  text-align: left;312  white-space: normal;313  font-weight: 400;314  text-transform: none;315  letter-spacing: 0;316  color: var(--color-ink);317}318.ci-pop:hover > .ci-pop-panel,319.ci-pop:focus-within > .ci-pop-panel {320  display: block;321}322@media (max-width: 640px) {323  .ci-pop > .ci-pop-panel {324    position: fixed;325    left: 12px;326    right: 12px;327    top: auto;328    bottom: 12px;329    max-width: none;330  }331}332333/* Completeness dots */334.ci-dots {335  display: inline-flex;336  gap: 3px;337  vertical-align: middle;338}339.ci-dot {340  width: 7px;341  height: 7px;342  border-radius: 50%;343  border: 1px solid var(--color-ink-4);344  background: transparent;345}346.ci-dot.on {347  background: var(--color-accent);348  border-color: var(--color-accent);349}350351details > summary {352  cursor: pointer;353  list-style: none;354}355details > summary::-webkit-details-marker {356  display: none;357}358359.ci-prose p + p {360  margin-top: 0.75em;361}362.ci-prose h2 {363  font-size: 1.35rem;364  margin-top: 2rem;365  margin-bottom: 0.5rem;366}367.ci-prose h3 {368  font-size: 1.1rem;369  margin-top: 1.4rem;370  margin-bottom: 0.35rem;371}372.ci-prose ul {373  list-style: disc;374  padding-left: 1.25rem;375  margin: 0.5rem 0;376}377.ci-prose li + li {378  margin-top: 0.25rem;379}380.ci-prose code {381  font-family: var(--font-mono);382  font-size: 0.85em;383  background: var(--color-paper-3);384  padding: 0 4px;385}386387pre.ci-code {388  font-family: var(--font-mono);389  font-size: 12.5px;390  line-height: 1.5;391  background: var(--color-paper-2);392  border: 1px solid var(--color-rule);393  padding: 10px 12px;394  overflow-x: auto;395  white-space: pre;396}397398@media print {399  .no-print {400    display: none !important;401  }402}403404/* ------------------------------------------------------------------------------------------------405   Hardening pass (pagination, table weight, accessibility). Appended; nothing above is rewritten.406   ------------------------------------------------------------------------------------------------ */407408/* Badges: one short class per tone instead of a long utility string repeated on every table row409   (every className ships twice — HTML + RSC payload). Text always accompanies the colour. */410.ci-badge {411  display: inline-flex;412  align-items: center;413  gap: 4px;414  border: 1px solid transparent;415  border-radius: var(--radius-sm);416  padding: 1px 6px;417  font-size: 11px;418  font-weight: 500;419  line-height: 16px;420  letter-spacing: 0.02em;421}422.ci-badge--neutral {423  background: var(--color-paper-3);424  color: var(--color-ink-2);425}426.ci-badge--accent {427  background: var(--color-accent-soft);428  color: var(--color-accent-2);429}430.ci-badge--warn {431  background: var(--color-warn-soft);432  color: var(--color-warn);433}434.ci-badge--danger {435  background: var(--color-danger-soft);436  color: var(--color-danger);437}438.ci-badge--ok {439  background: var(--color-ok-soft);440  color: var(--color-ok);441}442.ci-badge--outline {443  background: transparent;444  color: var(--color-ink-2);445  border-color: var(--color-rule-strong);446}447448/* Source badge link (compact rows and popover trigger share one class) */449.ci-src {450  font-family: var(--font-mono);451  display: inline-flex;452  align-items: center;453  border: 1px solid var(--color-rule-strong);454  border-radius: var(--radius-sm);455  background: var(--color-paper);456  padding: 0 4px;457  font-size: 10.5px;458  line-height: 16px;459  color: var(--color-ink-2);460  text-decoration: none;461  white-space: nowrap;462}463.ci-src:hover,464.ci-src:focus-visible {465  border-color: var(--color-accent);466  color: var(--color-accent);467}468469/* Pager */470.ci-pager-link {471  display: inline-block;472  min-width: 28px;473  border: 1px solid var(--color-rule);474  padding: 4px 8px;475  text-align: center;476  color: var(--color-ink-2);477  text-decoration: none;478  line-height: 1.2;479}480.ci-pager-link:hover {481  border-color: var(--color-accent);482  color: var(--color-accent);483}484.ci-pager-link.is-current {485  border-color: var(--color-accent);486  background: var(--color-accent-soft);487  color: var(--color-accent-2);488  font-weight: 500;489}490.ci-pager-link.is-disabled {491  color: var(--color-ink-4);492  cursor: default;493}494495/* Filter chips (status / phase / cohort / jurisdiction selectors) */496.ci-chip {497  display: inline-block;498  border: 1px solid var(--color-rule);499  padding: 2px 8px;500  color: var(--color-ink-2);501  text-decoration: none;502  line-height: 1.35;503}504.ci-chip:hover {505  border-color: var(--color-accent);506}507.ci-chip[aria-current='page'],508.ci-chip.is-selected {509  border-color: var(--color-accent);510  background: var(--color-accent-soft);511  color: var(--color-accent-2);512}513514/* Focus visibility: links inside dense tables, tabs, chips and pager get a visible ring even when515   the surrounding element clips overflow (outline-offset 0 keeps the ring inside table cells). */516.ci-tab:focus-visible,517.ci-chip:focus-visible,518.ci-pager-link:focus-visible,519.ci-src:focus-visible,520.ci-table a:focus-visible,521.ci-table summary:focus-visible {522  outline: 2px solid var(--color-accent);523  outline-offset: 0;524  border-radius: 2px;525}526.ci-tabs a:focus-visible {527  outline-offset: -2px;528}529details > summary:focus-visible {530  outline: 2px solid var(--color-accent);531  outline-offset: 2px;532}533534/* Table captions live above the table (visible text, not sr-only) — the caption is the place where535   the ONE provenance popover per table sits. */536.ci-table caption {537  caption-side: top;538  text-align: left;539  padding: 0 0 6px;540  font-size: 12px;541  color: var(--color-ink-3);542}543.ci-table thead th[aria-sort] {544  cursor: default;545}546547/* Skeletons (loading.tsx) — never look like data */548.ci-skeleton {549  background: linear-gradient(90deg, var(--color-paper-3) 0%, var(--color-paper-2) 50%, var(--color-paper-3) 100%);550  background-size: 200% 100%;551  border-radius: 2px;552  animation: ci-shimmer 1.4s ease-in-out infinite;553}554@keyframes ci-shimmer {555  from {556    background-position: 200% 0;557  }558  to {559    background-position: -200% 0;560  }561}562@media (prefers-reduced-motion: reduce) {563  .ci-skeleton {564    animation: none;565  }566}567568/* Keep the sticky provenance popover reachable by keyboard users: the panel becomes visible while569   any element inside is focused (focus-within already covers the trigger). */570.ci-pop:focus-within > .ci-pop-panel {571  display: block;572}573574/* Row-group header inside a single dense table (one <tbody> per variant / cancer group) */575.ci-table tr.ci-group th {576  position: static;577  background: var(--color-paper-2);578  border-top: 1px solid var(--color-rule-strong);579  border-bottom: 1px solid var(--color-rule);580  padding: 7px 10px;581  text-align: left;582  font-family: var(--font-sans);583  font-size: 13.5px;584  font-weight: 500;585  letter-spacing: 0;586  text-transform: none;587  color: var(--color-ink);588  white-space: normal;589  overflow-wrap: anywhere;590}591.ci-table tbody:first-of-type tr.ci-group th {592  border-top: 0;593}594.ci-evidence td.w-t {595  min-width: 160px;596}597abbr.no-underline {598  text-decoration: none;599}600601/* Compact list rows (e.g. variants on a gene page): link left, meta right */602.ci-rows {603  margin: 0;604  padding: 0;605  list-style: none;606  font-size: 13.5px;607}608.ci-rows > li {609  display: flex;610  align-items: baseline;611  justify-content: space-between;612  gap: 8px;613  border-bottom: 1px solid var(--color-rule);614  padding: 4px 0;615}616.ci-rows > li > span {617  font-size: 11.5px;618  color: var(--color-ink-3);619  text-align: right;620}621622/* Publication list */623.ci-pubs {624  margin: 0;625  padding: 0;626  list-style: none;627}628.ci-pub {629  padding: 10px 0;630  border-bottom: 1px solid var(--color-rule);631  font-size: 13.5px;632}633.ci-pub > div {634  display: flex;635  flex-wrap: wrap;636  align-items: baseline;637  column-gap: 8px;638}639.ci-pub > p {640  margin-top: 2px;641  font-size: 12.5px;642  color: var(--color-ink-3);643}644645/* Evidence table: link, level and details styles are scoped here instead of per-cell classes646   (50 rows × ~8 classes × 2 copies per page). */647.ci-evidence a {648  color: var(--color-accent);649  text-decoration: underline;650  text-decoration-color: color-mix(in oklab, var(--color-accent) 35%, transparent);651}652.ci-evidence a:hover {653  text-decoration-color: var(--color-accent);654}655.ci-evidence tr.ci-group a.ci-mono {656  color: var(--color-ink-3);657  text-decoration: none;658}659.ci-evidence tr.ci-group a.ci-mono:hover {660  color: var(--color-accent);661}662.ci-evidence abbr {663  font-family: var(--font-mono);664  font-size: 0.86em;665  font-weight: 500;666  text-decoration: none;667}668.ci-evidence td.ev {669  max-width: 360px;670  font-size: 12.5px;671  color: var(--color-ink-2);672}673.ci-evidence td.ev summary {674  color: var(--color-accent);675  text-decoration: underline;676  text-decoration-color: color-mix(in oklab, var(--color-accent) 35%, transparent);677}678.ci-evidence td.ev details p {679  margin-top: 4px;680}681682/* Theme toggle (header) */683.ci-theme-toggle {684  display: inline-flex;685  align-items: center;686  gap: 4px;687  border: 1px solid var(--color-rule);688  padding: 5px 7px;689  color: var(--color-ink-2);690  background: transparent;691  cursor: pointer;692  line-height: 1;693}694.ci-theme-toggle:hover {695  border-color: var(--color-accent);696  color: var(--color-accent);697}698