dr-sandbox/app/web/static/style.css

1668 lines
39 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* ---------------------------------------------------------------------------
* web1 — scientific instrument / research notebook
*
* Palette:
* page #fafaf8 off-white
* ink #1a1a1a charcoal
* mute #6b6b68 secondary text
* faint #b9b8b2 hairlines, disabled
* rule #e3e1db dividers
* accent #1f4e5f muted deep teal
* alarm #8a3a2a rust, for failures (sparingly)
* ------------------------------------------------------------------------- */
:root {
--page: #fafaf8;
--panel: #ffffff;
--ink: #1a1a1a;
--mute: #6b6b68;
--faint: #b9b8b2;
--rule: #e3e1db;
--rule-2: #ccc9c1;
--accent: #1f4e5f;
--accent-tint: #e9eff1;
--alarm: #8a3a2a;
--warm: #a77a2c;
--good: #3a6f3f;
/* Qualitative palette for plot lines. JS reads these via getComputedStyle
so the palette flips with the theme. */
--plot-1: #1f4e5f;
--plot-2: #8a3a2a;
--plot-3: #a77a2c;
--plot-4: #3a6f3f;
--plot-5: #5d4a7b;
--plot-6: #7a5c4b;
--plot-7: #2b5d7a;
--plot-8: #6b6b3e;
--serif: Georgia, "Iowan Old Style", "Palatino Linotype", serif;
--sans: -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue",
"Inter", "Arial", sans-serif;
--mono: "JetBrains Mono", "SF Mono", "Menlo", "Consolas", ui-monospace,
monospace;
--fs-base: 14px;
--lh-base: 1.55;
--space: 1rem;
}
/* Dark mode — warm near-black, preserving the scientific-notebook feel.
Toggled by setting [data-theme="dark"] on <html>. */
[data-theme="dark"] {
--page: #1a1917;
--panel: #1f1e1c;
--ink: #e8e4da;
--mute: #9a968c;
--faint: #5f5b52;
--rule: #2b2925;
--rule-2: #3a3834;
--accent: #84bcc9;
--accent-tint: #1c2930;
--alarm: #d18774;
--warm: #cba368;
--good: #8fb695;
--plot-1: #84bcc9;
--plot-2: #d18774;
--plot-3: #cba368;
--plot-4: #8fb695;
--plot-5: #a695c4;
--plot-6: #bc9f8a;
--plot-7: #8fa7c5;
--plot-8: #adad80;
}
html { color-scheme: light dark; }
[data-theme="light"] { color-scheme: light; }
[data-theme="dark"] { color-scheme: dark; }
/* Hardcoded light-mode colour patches. These predate the theme system;
overriding them here keeps the original selectors untouched. */
[data-theme="dark"] button.submit:hover,
[data-theme="dark"] .picker-footer .continue:not(:disabled):hover {
background: #a5d0da;
}
[data-theme="dark"] .flash.err,
[data-theme="dark"] .badge.cancelled {
background: #3a2520;
}
[data-theme="dark"] .badge.completed {
background: #1f2e21;
}
[data-theme="dark"] .dataset-picker {
--picker-panel: #252420;
--picker-hair: #3a3834;
}
[data-theme="dark"] .dataset-picker .card-desc {
color: var(--ink);
}
* { box-sizing: border-box; }
html, body {
margin: 0;
padding: 0;
background: var(--page);
color: var(--ink);
font-family: var(--sans);
font-size: var(--fs-base);
line-height: var(--lh-base);
font-feature-settings: "tnum" 1, "cv11" 1; /* tabular numerals */
-webkit-font-smoothing: antialiased;
}
code, kbd, pre, samp, .mono, .num {
font-family: var(--mono);
font-feature-settings: "tnum" 1;
}
a {
color: var(--accent);
text-decoration: none;
border-bottom: 1px solid transparent;
transition: border-color 120ms ease;
}
a:hover { border-bottom-color: var(--accent); }
hr {
border: 0;
border-top: 1px solid var(--rule);
margin: 2rem 0;
}
/* ---------- shell ------------------------------------------------------- */
.masthead {
border-bottom: 1px solid var(--rule);
padding: 1.6rem 2.2rem 1.2rem;
background: var(--page);
display: flex;
justify-content: space-between;
align-items: flex-end;
gap: 2rem;
}
.masthead .title {
font-family: var(--serif);
font-size: 1.55rem;
letter-spacing: -0.01em;
font-weight: 500;
margin: 0;
}
.masthead .title em {
font-style: italic;
color: var(--mute);
font-weight: 400;
}
.masthead .meta {
text-align: right;
color: var(--mute);
font-size: 0.78rem;
line-height: 1.5;
font-family: var(--mono);
}
.masthead .meta .dot {
display: inline-block; width: 6px; height: 6px; border-radius: 50%;
background: var(--good); margin-right: 4px; vertical-align: 1px;
}
.masthead .meta .dot.bad { background: var(--alarm); }
main {
display: grid;
grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
gap: 0;
max-width: 1440px;
margin: 0 auto;
}
.col-left {
padding: 1.8rem 2rem 2rem 2.2rem;
border-right: 1px solid var(--rule);
}
.col-right {
padding: 1.8rem 2.2rem 2rem 2rem;
}
@media (max-width: 940px) {
main { grid-template-columns: 1fr; }
.col-left { border-right: 0; border-bottom: 1px solid var(--rule); }
}
/* ---------- typography / section labels -------------------------------- */
.section-label {
font-family: var(--sans);
font-size: 0.70rem;
font-weight: 600;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--mute);
margin: 0 0 0.6rem;
padding-bottom: 0.35rem;
border-bottom: 1px solid var(--rule);
display: flex;
align-items: baseline;
justify-content: space-between;
}
.section-label .ordinal {
font-family: var(--mono);
font-weight: 500;
color: var(--faint);
font-size: 0.72rem;
letter-spacing: 0;
}
.section + .section { margin-top: 1.9rem; }
.lead {
color: var(--mute);
font-size: 0.87rem;
font-style: italic;
font-family: var(--serif);
margin: 0.4rem 0 0.9rem;
max-width: 44ch;
}
/* ---------- form ------------------------------------------------------- */
.form-grid {
display: grid;
grid-template-columns: max-content 1fr;
row-gap: 0.55rem;
column-gap: 1.2rem;
align-items: baseline;
}
.form-grid label {
font-size: 0.82rem;
color: var(--ink);
font-variant-numeric: tabular-nums;
white-space: nowrap;
}
.form-grid label .hint {
display: block;
font-size: 0.72rem;
color: var(--mute);
font-style: italic;
font-family: var(--serif);
margin-top: 1px;
white-space: normal;
max-width: 24ch;
}
.form-grid input[type="text"],
.form-grid input[type="number"],
.form-grid select {
font-family: var(--mono);
font-size: 0.85rem;
color: var(--ink);
background: transparent;
border: 0;
border-bottom: 1px solid var(--rule-2);
padding: 3px 2px 4px;
width: 100%;
outline: none;
transition: border-color 120ms ease, background 120ms ease;
border-radius: 0;
}
.form-grid input[type="text"]:focus,
.form-grid input[type="number"]:focus,
.form-grid select:focus {
border-bottom-color: var(--accent);
background: var(--accent-tint);
}
.form-grid input[readonly] {
color: var(--mute);
background: transparent;
border-bottom-style: dotted;
}
.form-grid input[type="checkbox"] {
accent-color: var(--accent);
margin: 0;
transform: translateY(1px);
}
select {
appearance: none;
-webkit-appearance: none;
background-image: linear-gradient(45deg, transparent 50%, var(--mute) 50%),
linear-gradient(-45deg, transparent 50%, var(--mute) 50%);
background-position: calc(100% - 10px) 50%, calc(100% - 5px) 50%;
background-size: 5px 5px;
background-repeat: no-repeat;
padding-right: 18px;
}
/* reducer picker — a typographic list, not a dropdown */
.reducer-list {
list-style: none;
padding: 0;
margin: 0 0 0.4rem;
display: flex;
flex-direction: column;
border-top: 1px solid var(--rule);
}
.reducer-list li { border-bottom: 1px solid var(--rule); }
.reducer-list input[type="radio"] { display: none; }
.reducer-list label {
display: grid;
grid-template-columns: 1.4rem 1fr auto;
gap: 0.6rem;
padding: 0.55rem 0.2rem 0.55rem 0.1rem;
cursor: pointer;
transition: background 100ms ease;
}
.reducer-list label:hover { background: var(--accent-tint); }
.reducer-list .mark {
font-family: var(--mono);
color: var(--faint);
text-align: center;
font-size: 0.9rem;
line-height: 1.1;
}
.reducer-list input:checked + label {
background: var(--accent-tint);
}
.reducer-list input:checked + label .mark { color: var(--accent); }
.reducer-list input:checked + label .name { color: var(--accent); font-weight: 600; }
.reducer-list .name {
font-family: var(--sans);
font-size: 0.88rem;
font-weight: 500;
}
.reducer-list .blurb {
display: block;
color: var(--mute);
font-size: 0.76rem;
font-style: italic;
font-family: var(--serif);
margin-top: 1px;
}
.reducer-list .pkg {
font-family: var(--mono);
color: var(--faint);
font-size: 0.72rem;
align-self: start;
text-align: right;
}
/* Narrow viewports: let the blurb span full width under the name/pkg row
instead of getting crammed into the middle column. */
@media (max-width: 780px) {
.reducer-list label {
grid-template-columns: 1.4rem 1fr auto;
grid-template-areas:
"mark name pkg"
"mark blurb blurb";
column-gap: 0.6rem;
row-gap: 2px;
}
.reducer-list .mark { grid-area: mark; }
.reducer-list .pkg { grid-area: pkg; }
.reducer-list .text { display: contents; }
.reducer-list .name { grid-area: name; }
.reducer-list .blurb { grid-area: blurb; }
}
/* advanced disclosure */
details.advanced {
margin-top: 0.8rem;
border-top: 1px dashed var(--rule);
padding-top: 0.6rem;
}
details.advanced > summary {
cursor: pointer;
list-style: none;
color: var(--mute);
font-size: 0.74rem;
text-transform: uppercase;
letter-spacing: 0.12em;
font-weight: 600;
padding: 0.2rem 0;
user-select: none;
}
details.advanced > summary::-webkit-details-marker { display: none; }
details.advanced > summary::before {
content: "[ + ]";
font-family: var(--mono);
color: var(--faint);
margin-right: 0.5rem;
letter-spacing: 0;
}
details.advanced[open] > summary::before { content: "[ ]"; color: var(--accent); }
.advanced-body { padding-top: 0.5rem; }
/* submit */
.actions {
margin-top: 1.4rem;
padding-top: 1rem;
border-top: 1px solid var(--rule);
display: flex;
align-items: center;
gap: 1rem;
}
button.submit {
font-family: var(--sans);
font-size: 0.82rem;
font-weight: 600;
letter-spacing: 0.09em;
text-transform: uppercase;
color: var(--page);
background: var(--accent);
border: 1px solid var(--accent);
padding: 0.55rem 1.2rem;
border-radius: 1px;
cursor: pointer;
transition: background 120ms ease;
}
button.submit:hover { background: #143642; }
button.submit:disabled { background: var(--faint); border-color: var(--faint); cursor: not-allowed; }
.actions .foot-note {
font-size: 0.72rem;
color: var(--mute);
font-style: italic;
font-family: var(--serif);
}
.flash {
padding: 0.6rem 0.8rem;
margin: 0.6rem 0;
border-left: 2px solid var(--accent);
background: var(--accent-tint);
font-size: 0.82rem;
}
.flash.err { border-left-color: var(--alarm); background: #f4e8e4; color: var(--alarm); }
/* ---------- runs list -------------------------------------------------- */
.run-count {
font-family: var(--mono);
color: var(--faint);
font-size: 0.72rem;
letter-spacing: 0;
text-transform: none;
}
.runs {
margin: 0;
padding: 0;
list-style: none;
border-top: 1px solid var(--rule);
}
.runs li.run {
border-bottom: 1px solid var(--rule);
padding: 0.85rem 0 0.85rem;
display: grid;
grid-template-columns: 1.25rem 5.5rem 1fr;
column-gap: 0.6rem;
align-items: start;
}
.runs li.run > .compare-cb,
.runs li.run > .compare-cb-slot {
width: 1rem;
height: 1rem;
margin: 3px 0 0 0;
align-self: start;
cursor: pointer;
accent-color: var(--accent);
}
.runs li.run > .compare-cb-slot {
visibility: hidden;
cursor: default;
}
.runs li.run > .compare-cb:disabled {
cursor: not-allowed;
opacity: 0.35;
}
.compare-bar {
display: flex;
align-items: center;
gap: 0.7rem;
margin-bottom: 0.5rem;
flex-wrap: wrap;
}
.compare-bar button {
font: inherit;
font-size: 0.82rem;
background: transparent;
border: 1px solid var(--rule);
color: var(--ink);
padding: 0.3rem 0.7rem;
cursor: pointer;
transition: background 100ms ease, border-color 100ms ease;
}
.compare-bar button:not(:disabled):hover {
background: var(--accent-tint);
border-color: var(--accent);
}
.compare-bar button:disabled {
opacity: 0.45;
cursor: not-allowed;
}
.compare-bar #compare-count {
font-family: var(--mono);
font-size: 0.76rem;
color: var(--faint);
margin-left: 0.25rem;
}
.compare-hint {
font-size: 0.76rem;
font-style: italic;
}
.runs li.run.just-submitted {
background: linear-gradient(to right, var(--accent-tint), transparent 60%);
padding-left: 0.55rem;
margin-left: -0.55rem;
}
.run .stamp {
font-family: var(--mono);
font-size: 0.72rem;
color: var(--mute);
line-height: 1.3;
padding-top: 2px;
}
.run .stamp .id {
display: block;
color: var(--faint);
font-size: 0.68rem;
margin-top: 3px;
}
.run .body { min-width: 0; }
.run .line1 {
display: flex;
gap: 0.55rem;
align-items: baseline;
flex-wrap: wrap;
}
.run .badge {
font-family: var(--mono);
font-size: 0.68rem;
letter-spacing: 0.05em;
text-transform: uppercase;
padding: 1px 6px;
border: 1px solid currentColor;
border-radius: 1px;
line-height: 1.2;
}
.badge.running { color: var(--accent); background: var(--accent-tint); }
.badge.scheduled,
.badge.pending { color: var(--mute); }
.badge.completed { color: var(--good); background: #edf1ed; }
.badge.failed,
.badge.crashed,
.badge.cancelled { color: var(--alarm); background: #f4e8e4; }
.run .stamp .rt {
display: block;
color: var(--faint);
font-size: 0.68rem;
margin-bottom: 8px;
font-variant-numeric: tabular-nums;
}
.run .recipe {
font-family: var(--serif);
font-size: 0.92rem;
font-style: italic;
color: var(--ink);
}
.run .recipe .embedder { font-style: normal; font-family: var(--mono); font-size: 0.82rem; color: var(--accent); }
.run .recipe .generator { font-style: normal; font-family: var(--mono); font-size: 0.82rem; color: var(--mute); }
.run .paramline {
margin-top: 0.25rem;
font-family: var(--mono);
font-size: 0.72rem;
color: var(--mute);
display: flex;
flex-wrap: wrap;
gap: 0 1.1rem;
row-gap: 2px;
}
.run .paramline .k { color: var(--faint); }
.run .outputs {
margin-top: 0.45rem;
display: flex;
flex-wrap: wrap;
gap: 0 1.2rem;
row-gap: 4px;
font-size: 0.8rem;
font-family: var(--sans);
}
.run .outputs .tag {
font-family: var(--mono);
font-size: 0.7rem;
color: var(--faint);
text-transform: uppercase;
letter-spacing: 0.06em;
margin-right: 0.25rem;
}
.run .outputs a[aria-disabled="true"] {
color: var(--faint);
font-style: italic;
cursor: default;
pointer-events: none;
}
.run .outputs a[aria-disabled="true"]::after {
content: " — waiting";
color: var(--faint);
font-size: 0.72rem;
font-family: var(--serif);
font-style: italic;
}
/* empty runs */
.empty {
padding: 1.4rem 0;
color: var(--mute);
font-style: italic;
font-family: var(--serif);
border-bottom: 1px solid var(--rule);
}
/* footer */
.colophon {
max-width: 1440px;
margin: 0 auto;
padding: 1rem 2.2rem 2rem;
color: var(--faint);
font-size: 0.72rem;
font-family: var(--mono);
letter-spacing: 0;
display: flex;
justify-content: space-between;
gap: 1rem;
border-top: 1px solid var(--rule);
}
.colophon span.k { color: var(--mute); }
.colophon .prefect-badge { display: inline-flex; align-items: center; gap: 4px; }
.colophon .prefect-badge .dot {
display: inline-block;
width: 6px; height: 6px;
border-radius: 50%;
background: var(--good);
}
.colophon .prefect-badge .dot.bad { background: var(--alarm); }
/* subtle htmx indicator */
.htmx-indicator {
opacity: 0;
transition: opacity 180ms ease;
color: var(--mute);
font-family: var(--mono);
font-size: 0.74rem;
}
.htmx-request .htmx-indicator { opacity: 1; }
.htmx-request.htmx-indicator { opacity: 1; }
/* ---------- dataset picker (§ 1) -------------------------------------- */
/* Collapsible <details> below the masthead; expands to a gallery of 3D
dataset previews, collapses to a one-line summary chip once confirmed. */
.dataset-picker {
--picker-panel: #f2eee4;
--picker-hair: #d8d3c6;
border-bottom: 1px solid var(--rule);
background: var(--page);
}
.dataset-picker > summary {
list-style: none;
cursor: pointer;
padding: 0.9rem 2.2rem;
display: flex;
justify-content: space-between;
align-items: center;
gap: 1rem;
user-select: none;
}
.dataset-picker > summary::-webkit-details-marker { display: none; }
.dataset-picker > summary:hover { background: var(--accent-tint); }
.dataset-picker .picker-meta {
display: flex;
align-items: baseline;
gap: 1rem;
flex-wrap: wrap;
min-width: 0;
}
.dataset-picker .section-number {
font-family: var(--mono);
font-size: 0.78rem;
font-weight: 600;
color: var(--accent);
letter-spacing: 0;
}
.dataset-picker .picker-title {
font-family: var(--serif);
font-size: 1rem;
color: var(--ink);
font-style: italic;
}
.dataset-picker .picker-selection {
font-size: 0.78rem;
color: var(--mute);
display: inline-flex;
align-items: baseline;
gap: 0.5rem;
}
.dataset-picker .picker-selection .lbl {
font-family: var(--mono);
font-size: 0.68rem;
letter-spacing: 0.08em;
text-transform: uppercase;
color: var(--faint);
}
.dataset-picker .picker-selection code {
font-family: var(--mono);
font-size: 0.78rem;
color: var(--accent);
}
.dataset-picker .picker-toggle {
font-family: var(--mono);
font-size: 0.74rem;
color: var(--faint);
letter-spacing: 0;
white-space: nowrap;
}
.dataset-picker .picker-toggle::before { content: "[ edit ]"; }
.dataset-picker[open] .picker-toggle::before { content: "[ collapse ]"; color: var(--accent); }
.dataset-picker.intro .picker-toggle::before { content: "[ read ]"; }
.dataset-picker.intro[open] .picker-toggle::before { content: "[ collapse ]"; color: var(--accent); }
.dataset-picker.metrics-inline .picker-toggle::before { content: "[ expand ]"; }
.dataset-picker.metrics-inline[open] .picker-toggle::before { content: "[ collapse ]"; color: var(--accent); }
.intro-body {
display: grid;
grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
gap: 2.6rem;
align-items: center;
}
@media (max-width: 940px) {
.intro-body {
grid-template-columns: 1fr;
gap: 1.4rem;
}
.intro-prose { margin-inline: auto; }
}
.intro-prose {
max-width: 72ch;
color: var(--ink);
font-family: var(--serif);
font-size: 0.95rem;
line-height: 1.65;
padding: 0.3rem 0 0.4rem;
}
.intro-prose p { margin: 0 0 0.9rem; }
.intro-prose p:last-child { margin-bottom: 0; }
.intro-prose strong {
font-family: var(--sans);
font-weight: 600;
font-style: normal;
font-size: 0.82rem;
letter-spacing: 0.02em;
text-transform: uppercase;
color: var(--accent);
margin-right: 0.2rem;
}
.intro-prose a {
color: var(--accent);
text-decoration: underline;
text-underline-offset: 2px;
}
.intro-prose em { font-style: italic; }
.intro-figure {
margin: 0;
padding: 0;
max-width: 560px;
justify-self: center;
width: 100%;
}
.intro-schema {
width: 100%;
height: auto;
display: block;
}
.intro-schema .frame {
fill: none;
stroke: var(--rule-2);
stroke-width: 1;
}
.intro-schema .frame.depth { opacity: 0.35; }
.intro-schema .axes line {
stroke: var(--faint);
stroke-width: 1;
}
.intro-schema .dots circle {
fill: var(--ink);
opacity: 0.65;
}
.intro-schema .t-hint {
font-family: var(--mono);
font-size: 10px;
fill: var(--faint);
letter-spacing: 0.04em;
}
.intro-schema .arrow-line,
.intro-schema .arrow-head {
stroke: var(--ink);
stroke-width: 1.4;
fill: none;
stroke-linecap: round;
stroke-linejoin: round;
}
.intro-schema .phi {
font-family: var(--serif);
font-style: italic;
font-size: 22px;
fill: var(--accent);
}
.intro-schema .arrow-sub {
font-family: var(--serif);
font-style: italic;
font-size: 11px;
fill: var(--mute);
}
.intro-schema .trajs polyline {
fill: none;
stroke: currentColor;
stroke-width: 1.4;
stroke-linecap: round;
stroke-linejoin: round;
}
.intro-schema .dot-start circle {
fill: none;
stroke: currentColor;
stroke-width: 1.2;
}
.intro-schema .dot-end circle {
fill: currentColor;
}
.intro-schema .dots-hi circle {
fill: currentColor;
}
/* Three tracked points, colored identically on input and on their projected
trajectory — currentColor on every themed element picks this up. */
.intro-schema .track-a { color: var(--accent); }
.intro-schema .track-b { color: var(--alarm); }
.intro-schema .track-c { color: var(--warm); }
.intro-schema .cap text {
font-family: var(--serif);
font-style: italic;
font-size: 11px;
fill: var(--mute);
}
.dataset-picker .picker-body {
padding: 0.4rem 2.2rem 1.6rem;
max-width: 1440px;
margin: 0 auto;
}
.dataset-picker .lede {
color: var(--mute);
font-family: var(--serif);
font-style: italic;
font-size: 0.88rem;
max-width: 62ch;
margin: 0.2rem 0 0.9rem;
}
.dataset-picker .lede kbd {
font-family: var(--mono);
font-size: 0.72rem;
background: var(--panel);
border: 1px solid var(--rule);
padding: 0 5px;
margin: 0 1px;
color: var(--ink);
}
.picker-controls {
display: grid;
grid-template-columns: auto 1fr auto;
align-items: center;
column-gap: 1rem;
row-gap: 0.55rem;
padding: 0.75rem 0;
border-top: 1px solid var(--rule);
border-bottom: 1px solid var(--rule);
margin-bottom: 1.1rem;
}
.picker-controls .ctl-label {
font-family: var(--mono);
font-size: 0.68rem;
letter-spacing: 0.08em;
text-transform: uppercase;
color: var(--mute);
}
.picker-controls .segmented {
grid-column: 2 / -1;
/* Shared 5-column track across every segmented row. 3-option rows drop
their options into columns 1/3/5 so first/middle/last align with the
5-option row's first/middle/last. */
display: grid;
grid-template-columns: repeat(5, 1fr);
align-items: center;
}
.picker-controls .segmented.count-3 > label:nth-child(1) { grid-column: 1; }
.picker-controls .segmented.count-3 > label:nth-child(2) { grid-column: 3; }
.picker-controls .segmented.count-3 > label:nth-child(3) { grid-column: 5; }
.picker-controls .segmented label {
font-family: var(--mono);
font-size: 0.78rem;
color: var(--mute);
cursor: pointer;
padding: 3px 2px 4px;
transition: color 120ms ease;
user-select: none;
font-variant-numeric: tabular-nums;
position: relative;
text-align: center;
}
.picker-controls .segmented label > span {
display: inline-block;
padding: 0 2px 1px;
border-bottom: 1px solid transparent;
transition: border-color 120ms ease;
}
.picker-controls .segmented label:hover { color: var(--ink); }
.picker-controls .segmented label:has(input:checked) {
color: var(--accent);
}
.picker-controls .segmented label:has(input:checked) > span {
border-bottom-color: var(--accent);
}
.picker-controls .segmented label:has(input:focus-visible) {
outline: 1px solid var(--accent);
outline-offset: 2px;
}
.picker-controls .segmented input[type="radio"] {
position: absolute;
opacity: 0;
width: 1px; height: 1px;
margin: 0;
}
.dataset-picker .gallery {
display: flex;
gap: 1.15rem;
overflow-x: auto;
overflow-y: hidden;
scroll-snap-type: x mandatory;
scroll-behavior: smooth;
-webkit-overflow-scrolling: touch;
padding: 2px 2px 0.85rem;
margin: 0 -2px 1.1rem;
scrollbar-width: thin;
scrollbar-color: var(--rule-2) transparent;
}
.dataset-picker .gallery::-webkit-scrollbar { height: 6px; }
.dataset-picker .gallery::-webkit-scrollbar-track { background: transparent; }
.dataset-picker .gallery::-webkit-scrollbar-thumb {
background: var(--rule-2);
border-radius: 3px;
}
.dataset-picker .gallery::-webkit-scrollbar-thumb:hover { background: var(--mute); }
.dataset-picker .picker-loading {
padding: 3rem 0;
text-align: center;
color: var(--mute);
font-family: var(--mono);
font-size: 0.82rem;
}
.dataset-picker .card {
flex: 0 0 240px;
/* Prevent long .card-path from forcing the card wider than its flex-basis. */
min-width: 0;
scroll-snap-align: start;
border: 1px solid var(--rule);
background: var(--picker-panel);
cursor: pointer;
display: flex;
flex-direction: column;
transition: border-color 120ms ease, box-shadow 120ms ease;
}
.dataset-picker .card:hover { border-color: var(--rule-2); }
.dataset-picker .card.selected {
border-color: var(--accent);
box-shadow: 0 0 0 1px var(--accent);
}
.dataset-picker .viz {
aspect-ratio: 1 / 1;
position: relative;
overflow: hidden;
}
.dataset-picker .viz canvas {
position: absolute;
inset: 0;
display: block;
width: 100% !important;
height: 100% !important;
}
.dataset-picker .fig-label {
position: absolute;
top: 8px;
left: 10px;
font-family: var(--mono);
font-size: 0.62rem;
color: var(--mute);
letter-spacing: 0.05em;
text-transform: uppercase;
pointer-events: none;
}
.dataset-picker .key-hint {
position: absolute;
top: 6px;
right: 8px;
font-family: var(--mono);
font-size: 0.7rem;
color: var(--mute);
background: rgba(250, 250, 247, 0.85);
border: 1px solid var(--rule);
padding: 0 5px;
pointer-events: none;
}
.dataset-picker .card.selected .key-hint {
color: var(--accent);
border-color: var(--accent);
}
.dataset-picker .controls-hint {
position: absolute;
bottom: 6px;
right: 8px;
font-family: var(--mono);
font-size: 0.62rem;
color: var(--mute);
opacity: 0;
transition: opacity 150ms ease;
pointer-events: none;
}
.dataset-picker .card:hover .controls-hint { opacity: 0.75; }
.dataset-picker .card-body {
padding: 0.75rem 0.9rem 0.9rem;
border-top: 1px solid var(--rule);
background: var(--page);
flex: 1;
}
.dataset-picker .card-label {
font-family: var(--sans);
font-weight: 500;
font-size: 0.9rem;
margin-bottom: 2px;
display: flex;
align-items: baseline;
gap: 0.5rem;
}
.dataset-picker .card-label .dot {
display: inline-block;
width: 7px; height: 7px;
border-radius: 50%;
background: transparent;
border: 1px solid var(--rule-2);
}
.dataset-picker .card.selected .card-label .dot {
background: var(--accent);
border-color: var(--accent);
}
.dataset-picker .card-path {
font-family: var(--mono);
font-size: 0.68rem;
color: var(--mute);
margin-bottom: 0.4rem;
word-break: break-all;
}
.dataset-picker .card-desc {
font-family: var(--serif);
font-size: 0.82rem;
color: #4a4a4a;
line-height: 1.5;
}
.picker-footer {
display: flex;
align-items: center;
justify-content: space-between;
padding-top: 0.85rem;
border-top: 1px solid var(--rule);
gap: 1.2rem;
flex-wrap: wrap;
}
.picker-footer .selection {
font-size: 0.82rem;
color: var(--mute);
display: inline-flex;
align-items: baseline;
gap: 0.5rem;
}
.picker-footer .selection .lbl {
font-family: var(--mono);
font-size: 0.68rem;
letter-spacing: 0.08em;
text-transform: uppercase;
}
.picker-footer .selection code {
font-family: var(--mono);
font-size: 0.82rem;
color: var(--accent);
}
.picker-footer .continue {
background: var(--accent);
color: var(--page);
border: 1px solid var(--accent);
padding: 0.45rem 1rem;
font-family: var(--sans);
font-size: 0.82rem;
font-weight: 600;
letter-spacing: 0.04em;
cursor: pointer;
border-radius: 1px;
transition: background 120ms ease;
}
.picker-footer .continue:not(:disabled):hover { background: #143642; }
.picker-footer .continue:disabled {
background: var(--faint);
border-color: var(--faint);
color: var(--page);
cursor: not-allowed;
}
@media (max-width: 940px) {
.dataset-picker > summary { padding: 0.9rem 1.2rem; }
.dataset-picker .picker-body { padding: 0.4rem 1.2rem 1.4rem; }
}
/* ---------- metrics page ----------------------------------------------- */
.masthead-link {
font-family: var(--mono);
color: var(--accent);
border-bottom: 1px solid transparent;
}
.masthead-link:hover { border-bottom-color: var(--accent); }
.theme-toggle {
position: absolute;
top: 0.6rem;
right: 0.8rem;
z-index: 50;
background: transparent;
border: 0;
color: var(--mute);
font-size: 1.05rem;
line-height: 1;
cursor: pointer;
padding: 0.25rem 0.35rem;
transition: color 120ms ease, transform 240ms ease;
user-select: none;
}
.theme-toggle:hover { color: var(--accent); }
.theme-toggle:focus-visible {
outline: 1px solid var(--accent);
outline-offset: 2px;
border-radius: 2px;
}
[data-theme="dark"] .theme-toggle { transform: rotate(180deg); }
.masthead .nav-link {
font-family: var(--mono);
font-size: 0.78rem;
color: var(--accent);
border-bottom: 1px solid transparent;
margin-left: 0.8rem;
white-space: nowrap;
}
.masthead .nav-link:hover { border-bottom-color: var(--accent); }
.metrics-page {
max-width: 1440px;
margin: 0 auto;
padding: 1.4rem 2.2rem 2rem;
}
.filter-bar {
display: flex;
flex-wrap: wrap;
align-items: flex-start;
gap: 1.1rem 2rem;
padding: 0.9rem 0 1rem;
border-bottom: 1px solid var(--rule);
margin-bottom: 1.4rem;
}
.filter-group { display: flex; flex-direction: column; gap: 0.35rem; min-width: 0; }
.filter-group .ctl-label {
font-family: var(--mono);
font-size: 0.68rem;
letter-spacing: 0.08em;
text-transform: uppercase;
color: var(--mute);
}
.filter-group.stat-group { min-width: 18rem; }
.filter-group .chips {
display: flex;
flex-wrap: wrap;
gap: 0.3rem 0.35rem;
align-items: center;
}
.chip {
font-family: var(--mono);
font-size: 0.75rem;
color: var(--mute);
background: transparent;
border: 1px solid var(--rule-2);
border-radius: 2px;
padding: 0.22rem 0.55rem;
cursor: pointer;
transition: background 120ms ease, border-color 120ms ease, color 120ms ease;
user-select: none;
letter-spacing: 0.02em;
font-variant-numeric: tabular-nums;
}
.chip:hover { color: var(--ink); }
.chip.is-on {
color: var(--accent);
border-color: var(--accent);
background: var(--accent-tint);
}
.chip:focus-visible { outline: 1px solid var(--accent); outline-offset: 2px; }
.chip-meta {
color: var(--faint);
font-family: var(--serif);
font-style: italic;
font-size: 0.76rem;
letter-spacing: 0;
border-style: dashed;
margin-left: 0.25rem;
}
.chip-meta:hover {
color: var(--accent);
border-color: var(--accent);
background: transparent;
}
.filter-group .segmented.count-4 {
display: grid;
grid-template-columns: repeat(4, 1fr);
align-items: center;
border-bottom: 1px solid var(--rule-2);
padding-bottom: 3px;
}
.filter-group .segmented label {
font-family: var(--mono);
font-size: 0.78rem;
color: var(--mute);
cursor: pointer;
padding: 3px 2px 4px;
transition: color 120ms ease;
user-select: none;
font-variant-numeric: tabular-nums;
position: relative;
text-align: center;
}
.filter-group .segmented label > span {
display: inline-block;
padding: 0 2px 1px;
border-bottom: 1px solid transparent;
transition: border-color 120ms ease;
}
.filter-group .segmented label:hover { color: var(--ink); }
.filter-group .segmented label:has(input:checked) { color: var(--accent); }
.filter-group .segmented label:has(input:checked) > span {
border-bottom-color: var(--accent);
}
.filter-group .segmented input[type="radio"] {
position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0;
}
.filter-count {
font-family: var(--mono);
font-size: 0.8rem;
color: var(--ink);
font-variant-numeric: tabular-nums;
margin-left: auto;
align-self: center;
padding-top: 0.3rem;
}
.filter-count .muted { color: var(--mute); }
.plots {
display: grid;
gap: 1.6rem;
margin-bottom: 1.4rem;
}
@media (min-width: 1100px) {
.plots { grid-template-columns: 1fr 1fr; }
.plots .plot:nth-child(3) { grid-column: 1 / -1; }
}
.plot { margin: 0; }
.plot figcaption {
display: flex;
align-items: baseline;
gap: 0.8rem;
margin-bottom: 0.4rem;
border-bottom: 1px solid var(--rule);
padding-bottom: 0.3rem;
}
.plot .plot-title {
font-family: var(--sans);
font-size: 0.82rem;
font-weight: 600;
letter-spacing: 0.02em;
color: var(--ink);
}
.plot .plot-sub {
font-family: var(--serif);
font-style: italic;
font-size: 0.76rem;
color: var(--mute);
}
.plot-area svg.chart {
width: 100%;
height: auto;
display: block;
background: var(--panel);
}
.plot-area svg .grid { stroke: var(--rule); stroke-width: 1; }
.plot-area svg .axis { stroke: var(--rule-2); stroke-width: 1; }
.plot-area svg .axis-tick { stroke: var(--rule-2); stroke-width: 1; }
.plot-area svg text.axis {
font-family: var(--mono);
font-size: 10px;
fill: var(--mute);
}
.plot-area svg text.axis-label {
font-family: var(--mono);
font-size: 10px;
fill: var(--faint);
letter-spacing: 0.04em;
text-transform: uppercase;
}
.plot-area svg text.empty {
font-family: var(--serif);
font-style: italic;
font-size: 13px;
fill: var(--faint);
}
.plot-area svg path.series {
opacity: 0.88;
transition: opacity 120ms ease, stroke-width 120ms ease;
}
.plot-area svg path.series:hover { opacity: 1; stroke-width: 2.25; }
.legend {
display: grid;
gap: 0.35rem;
padding: 0.8rem 0 0.4rem;
border-top: 1px solid var(--rule);
}
.legend .legend-row {
display: grid;
grid-template-columns: 10px 1fr auto;
gap: 0.75rem;
align-items: baseline;
padding: 0.22rem 0.4rem;
border: 0;
background: transparent;
color: var(--ink);
cursor: pointer;
text-align: left;
font: inherit;
border-radius: 2px;
transition: background 100ms ease, opacity 120ms ease;
}
.legend .legend-row:hover { background: var(--accent-tint); }
.legend .legend-row.is-selected {
background: var(--accent-tint);
box-shadow: inset 2px 0 0 var(--accent);
}
.legend .legend-row.is-selected .lbl { color: var(--accent); font-weight: 600; }
.legend .legend-row.is-dim { opacity: 0.42; }
.legend .legend-row.is-dim:hover { opacity: 0.85; }
.legend .legend-row:focus-visible {
outline: 1px solid var(--accent);
outline-offset: 1px;
}
.legend-clear {
font-family: var(--mono);
font-size: 0.72rem;
letter-spacing: 0.04em;
text-transform: uppercase;
color: var(--accent);
background: transparent;
border: 1px solid var(--rule-2);
padding: 0.25rem 0.6rem;
border-radius: 2px;
cursor: pointer;
justify-self: start;
margin-bottom: 0.4rem;
transition: background 120ms ease, border-color 120ms ease;
}
.legend-clear:hover { background: var(--accent-tint); border-color: var(--accent); }
.legend .swatch {
width: 10px; height: 10px;
border-radius: 2px;
display: inline-block;
align-self: center;
}
.legend .lbl {
font-family: var(--mono);
font-size: 0.78rem;
color: var(--ink);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.legend .fn {
font-family: var(--mono);
font-size: 0.72rem;
color: var(--faint);
text-align: right;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 30ch;
}
.metrics-page .empty,
.metrics-inline .empty {
border: 1px dashed var(--rule-2);
padding: 1.4rem;
text-align: center;
color: var(--mute);
font-family: var(--serif);
font-style: italic;
font-size: 0.92rem;
margin-top: 1rem;
}
@media (max-width: 780px) {
.metrics-page { padding: 1rem 1.1rem 1.4rem; }
.filter-bar { gap: 0.9rem 1.2rem; }
.filter-group.stat-group { width: 100%; min-width: 0; }
.filter-count { margin-left: 0; text-align: left; padding-top: 0; }
.legend .legend-row { grid-template-columns: 10px 1fr; }
.legend .fn { display: none; }
}
/* ---------- compare page ------------------------------------------------ */
.compare-layout {
--panel-h: 62vh;
padding: 1.2rem 1.6rem 1.6rem;
display: flex;
flex-direction: column;
gap: 1rem;
}
.compare-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1rem;
}
.compare-panel {
display: flex;
flex-direction: column;
border: 1px solid var(--rule);
background: var(--panel);
border-radius: 2px;
min-width: 0;
min-height: 0;
overflow: hidden;
}
.compare-panel-head {
display: flex;
align-items: baseline;
gap: 0.55rem;
padding: 0.55rem 0.85rem;
border-bottom: 1px solid var(--rule);
font-family: var(--mono);
font-size: 0.78rem;
color: var(--mute);
flex-wrap: wrap;
}
.compare-panel-head .panel-tag {
display: inline-block;
min-width: 1.2em;
padding: 0 0.35rem;
border-radius: 2px;
background: var(--accent-tint);
color: var(--accent);
font-weight: 600;
text-align: center;
font-size: 0.72rem;
letter-spacing: 0.04em;
}
.compare-panel[data-slot="b"] .compare-panel-head .panel-tag {
color: var(--warm);
background: color-mix(in srgb, var(--warm) 14%, transparent);
}
.compare-panel-head .panel-embedder {
color: var(--ink);
font-weight: 600;
}
.compare-panel-head .panel-generator {
color: var(--ink);
}
.compare-panel-head .panel-sep {
color: var(--faint);
}
.compare-panel-head .panel-params {
color: var(--mute);
font-size: 0.74rem;
flex-basis: 100%;
}
.compare-panel-head .panel-stem {
margin-left: auto;
color: var(--faint);
font-size: 0.72rem;
border-bottom: 1px solid transparent;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.compare-panel-head .panel-stem:hover {
color: var(--mute);
border-bottom-color: var(--faint);
}
.compare-canvas {
position: relative;
flex: 1 1 auto;
min-height: 0;
background: var(--picker-panel, var(--panel));
height: var(--panel-h);
}
.compare-canvas canvas {
display: block;
width: 100% !important;
height: 100% !important;
}
.compare-status {
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
padding: 1rem;
text-align: center;
color: var(--mute);
font-family: var(--mono);
font-size: 0.82rem;
pointer-events: none;
}
.compare-status.is-error {
color: var(--alarm);
}
.compare-controls {
display: flex;
align-items: center;
gap: 0.9rem;
padding: 0.7rem 0.9rem;
border: 1px solid var(--rule);
border-radius: 2px;
background: var(--panel);
font-family: var(--mono);
font-size: 0.8rem;
color: var(--mute);
flex-wrap: wrap;
}
.compare-controls .cc-play {
appearance: none;
border: 1px solid var(--rule-2);
background: var(--panel);
color: var(--ink);
width: 2.1rem;
height: 2.1rem;
border-radius: 2px;
cursor: pointer;
font-size: 0.9rem;
line-height: 1;
display: inline-flex;
align-items: center;
justify-content: center;
transition: background 120ms ease, border-color 120ms ease;
}
.compare-controls .cc-play:hover {
background: var(--accent-tint);
border-color: var(--accent);
color: var(--accent);
}
.compare-controls .cc-scrub {
flex: 1 1 auto;
min-width: 10rem;
accent-color: var(--accent);
}
.compare-controls .cc-time {
display: inline-flex;
gap: 0.35rem;
white-space: nowrap;
color: var(--ink);
font-variant-numeric: tabular-nums;
}
.compare-controls .cc-time-sep { color: var(--faint); }
.compare-controls .cc-time-a { color: var(--accent); }
.compare-controls .cc-time-b { color: var(--warm); }
.compare-controls .cc-speed-wrap,
.compare-controls .cc-sync-wrap,
.compare-controls .cc-motion-wrap {
display: inline-flex;
align-items: center;
gap: 0.35rem;
}
.compare-controls .cc-lbl {
color: var(--faint);
text-transform: lowercase;
font-size: 0.74rem;
}
.compare-controls select {
appearance: none;
-webkit-appearance: none;
border: 1px solid var(--rule-2);
background: var(--panel);
color: var(--ink);
font-family: var(--mono);
font-size: 0.78rem;
padding: 0.25rem 1.4rem 0.25rem 0.5rem;
border-radius: 2px;
cursor: pointer;
background-image: linear-gradient(45deg, transparent 50%, var(--mute) 50%),
linear-gradient(-45deg, transparent 50%, var(--mute) 50%);
background-position: calc(100% - 12px) 50%, calc(100% - 7px) 50%;
background-size: 5px 5px, 5px 5px;
background-repeat: no-repeat;
}
.compare-controls select:focus {
outline: none;
border-color: var(--accent);
}
@media (max-width: 900px) {
.compare-layout { --panel-h: 45vh; padding: 1rem 0.9rem 1.2rem; }
.compare-grid { grid-template-columns: 1fr; }
}