dr-sandbox/app/web/static/style.css
2026-04-21 19:46:31 -06:00

864 lines
20 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;
--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;
}
* { 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;
min-height: calc(100vh - 72px);
}
.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;
}
/* 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: 5.5rem 1fr;
column-gap: 1rem;
align-items: start;
}
.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 .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); }
/* 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;
}
.dataset-picker .picker-toggle::before { content: "[ edit ]"; }
.dataset-picker[open] .picker-toggle::before { content: "[ collapse ]"; color: var(--accent); }
.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 .ctl-value {
font-family: var(--mono);
font-size: 0.82rem;
color: var(--accent);
min-width: 3.5rem;
text-align: right;
font-variant-numeric: tabular-nums;
}
.picker-controls input[type="range"] {
width: 100%;
accent-color: var(--accent);
height: 4px;
}
.picker-controls .segmented {
grid-column: 2 / -1;
display: flex;
justify-content: space-between;
align-items: center;
}
.picker-controls .segmented label {
font-family: var(--mono);
font-size: 0.78rem;
color: var(--mute);
cursor: pointer;
padding: 3px 2px 4px;
border-bottom: 1px solid transparent;
transition: color 120ms ease, border-color 120ms ease;
user-select: none;
font-variant-numeric: tabular-nums;
position: relative;
}
.picker-controls .segmented label:hover { color: var(--ink); }
.picker-controls .segmented label:has(input:checked) {
color: var(--accent);
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; }
}