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

1825 lines
43 KiB
CSS
Raw Permalink 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;
/* Blurb gets its own row spanning name+pkg, so its width is uniform
across rows (the pkg column is auto-sized per label, which made the
blurb width vary noticeably when pkg strings differ in length). */
grid-template-areas:
"mark name pkg"
"mark blurb blurb";
column-gap: 0.6rem;
row-gap: 2px;
padding: 0.55rem 0.2rem 0.55rem 0.1rem;
cursor: pointer;
transition: background 100ms ease;
}
.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; }
.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;
}
/* 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;
}
.compare-bar .compare-clear {
background: transparent;
border: 0;
color: var(--faint);
font: inherit;
font-size: 0.72rem;
padding: 0 0.2rem;
cursor: pointer;
text-decoration: underline dotted;
text-underline-offset: 3px;
}
.compare-bar .compare-clear:hover { color: var(--alarm); }
.runs-filter {
display: flex;
flex-direction: column;
gap: 0.4rem;
padding: 0.25rem 0 0.7rem;
margin-bottom: 0.3rem;
border-bottom: 1px dashed var(--rule);
}
.runs-filter-row {
display: flex;
flex-wrap: wrap;
gap: 0.4rem 1.4rem;
}
/* Hide a row entirely when every child group is display:none (all axes
in it have a single value). :has is supported in all modern evergreens. */
.runs-filter-row:not(:has(.runs-filter-group:not([style*="display: none"]))) {
display: none;
}
.runs-filter-group {
display: flex;
align-items: center;
gap: 0.5rem;
min-width: 0;
flex: 1 1 auto;
}
.runs-filter-group .ctl-label {
font-family: var(--mono);
font-size: 0.66rem;
letter-spacing: 0.08em;
text-transform: uppercase;
color: var(--faint);
}
.runs-filter-group .chips {
display: flex;
flex-wrap: wrap;
gap: 0.25rem 0.3rem;
align-items: center;
}
.runs-filter-group .chips .chip-meta-wrap {
display: inline-flex;
gap: 0.25rem 0.3rem;
flex-shrink: 0;
}
.runs li.run.filtered-out { display: none; }
.runs li.run.just-submitted {
background: linear-gradient(to right, var(--accent-tint), transparent 60%);
padding-left: 0.55rem;
margin-left: -0.55rem;
}
.runs li.run.stale {
opacity: 0.55;
}
.runs li.run.stale .stale-note {
color: var(--alarm);
font-style: italic;
font-size: 0.72rem;
margin-left: 0.3rem;
}
.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 { position: relative; }
.plot-area svg path.series {
opacity: 0.88;
transition: opacity 120ms ease, stroke-width 120ms ease;
}
.plot-area svg.has-hover path.series { opacity: 0.22; }
.plot-area svg.has-hover path.series.is-hover { opacity: 1; stroke-width: 2.25; }
.plot-area svg .chart-marker { fill: var(--panel); }
.chart-tooltip {
position: absolute;
pointer-events: none;
z-index: 4;
min-width: 180px;
max-width: 320px;
padding: 0.4rem 0.55rem;
background: var(--panel);
border: 1px solid var(--rule-2);
border-left: 3px solid var(--tt-accent, var(--ink));
box-shadow: 0 4px 14px rgba(0, 0, 0, 0.12);
font-size: 0.74rem;
line-height: 1.25;
color: var(--ink);
}
.chart-tooltip[hidden] { display: none; }
.chart-tooltip .tt-label {
font-family: var(--sans);
font-weight: 600;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.chart-tooltip .tt-values {
font-family: var(--mono);
color: var(--mute);
margin-top: 0.15rem;
}
.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: repeat(auto-fit, minmax(360px, 1fr));
gap: 1rem;
}
.compare-panel {
--panel-color: var(--accent);
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: color-mix(in srgb, var(--panel-color) 14%, transparent);
color: var(--panel-color);
font-weight: 600;
text-align: center;
font-size: 0.72rem;
letter-spacing: 0.04em;
}
.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-params .param.diff,
.compare-panel-head .panel-embedder.diff,
.compare-panel-head .panel-generator.diff {
color: var(--alarm);
font-weight: 600;
}
.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: 0 0 auto;
min-height: 0;
background: var(--picker-panel, var(--panel));
/* Height derives from column width × aspect ratio. Controlled by the
axes dropdown via --canvas-aspect on the grid. --panel-h is the cap. */
aspect-ratio: var(--canvas-aspect, 1 / 1);
max-height: var(--panel-h);
cursor: crosshair;
}
.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-seg { color: var(--panel-color, var(--ink)); }
.compare-controls .cc-speed-wrap,
.compare-controls .cc-sync-wrap,
.compare-controls .cc-motion-wrap,
.compare-controls .cc-color-wrap {
display: inline-flex;
align-items: center;
gap: 0.35rem;
}
/* Hide a wrap entirely when its select is disabled (e.g., axes on a
single-panel modal view). */
.compare-controls label:has(select:disabled) { display: none; }
.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; }
}
/* ---------- run modal --------------------------------------------------- */
#run-modal {
width: min(1200px, 94vw);
max-width: 94vw;
height: min(820px, 88vh);
max-height: 88vh;
padding: 0;
border: 1px solid var(--rule);
border-radius: 4px;
background: var(--panel);
color: var(--ink);
}
#run-modal::backdrop {
background: color-mix(in srgb, #000 48%, transparent);
}
.run-modal-body {
display: flex;
flex-direction: column;
gap: 0.8rem;
height: 100%;
padding: 0.8rem 1rem 1rem;
box-sizing: border-box;
--panel-h: 62vh;
}
.run-modal-head {
display: flex;
align-items: center;
justify-content: space-between;
gap: 0.5rem;
font-family: var(--mono);
font-size: 0.82rem;
color: var(--mute);
}
.run-modal-close {
appearance: none;
border: 1px solid var(--rule-2);
background: var(--panel);
color: var(--ink);
width: 1.9rem;
height: 1.9rem;
border-radius: 2px;
cursor: pointer;
font-size: 1rem;
line-height: 1;
}
.run-modal-close:hover {
background: var(--accent-tint);
border-color: var(--accent);
color: var(--accent);
}
#run-modal .compare-grid {
flex: 1 1 auto;
min-height: 0;
}