th and td were padded '... 0' on the left, so the concept column ran flush against the pane edge and every other column sat hard against the preceding cell's text. Group-header rows inherit the change, so they stay aligned with the cells below them.
284 lines
11 KiB
CSS
284 lines
11 KiB
CSS
.webinar-dash {
|
|
--wd-ink-000: #ffffff; --wd-ink-050: #f7f7f7; --wd-ink-100: #ececec;
|
|
--wd-ink-200: #d9d9d9; --wd-ink-400: #8a8a8a; --wd-ink-500: #5e5e5e;
|
|
--wd-ink-700: #262626; --wd-ink-900: #0a0a0a; --wd-ink-999: #000000;
|
|
--wd-red-500: #e1261c; --wd-red-600: #c31c14;
|
|
|
|
--wd-bg: var(--wd-ink-000);
|
|
--wd-bg-subtle: var(--wd-ink-050);
|
|
--wd-fg: var(--wd-ink-999);
|
|
--wd-fg-2: var(--wd-ink-700);
|
|
--wd-fg-3: var(--wd-ink-500);
|
|
--wd-fg-4: var(--wd-ink-400);
|
|
--wd-border: var(--wd-ink-200);
|
|
--wd-border-strong: var(--wd-ink-999);
|
|
--wd-border-subtle: var(--wd-ink-100);
|
|
--wd-accent: var(--wd-red-500);
|
|
--wd-accent-press: var(--wd-red-600);
|
|
--wd-accent-on: #ffffff;
|
|
--wd-ok: #0a8a3f;
|
|
--wd-warn: #c68a00;
|
|
--wd-danger: var(--wd-red-500);
|
|
|
|
--wd-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
|
--wd-sans: "Inter", ui-sans-serif, system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
|
|
|
|
font-family: var(--wd-sans);
|
|
color: var(--wd-fg);
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 16px;
|
|
/* Past roughly this width the two panes stop reading as a pair and table
|
|
rows get hard to track across. Cap the whole dashboard, not just the
|
|
grid, so the toolbar stays flush with the panes below it. */
|
|
max-width: 1600px;
|
|
/* Makes this element the reference for the @container query further down,
|
|
so the grid collapses on the pane's width rather than the window's. */
|
|
container-type: inline-size;
|
|
}
|
|
|
|
.theme-dark .webinar-dash {
|
|
--wd-bg: var(--wd-ink-900);
|
|
--wd-bg-subtle: #161616;
|
|
--wd-fg: var(--wd-ink-000);
|
|
--wd-fg-2: var(--wd-ink-200);
|
|
--wd-fg-3: var(--wd-ink-400);
|
|
--wd-fg-4: var(--wd-ink-500);
|
|
--wd-border: var(--wd-ink-700);
|
|
--wd-border-strong: #b8b8b8;
|
|
--wd-border-subtle: #161616;
|
|
/* Accent tracks the installed theme at .obsidian/themes/tesanti/theme.css,
|
|
whose dark section reads "Black canvas, same signal red": --accent-h/-s/-l
|
|
are declared once at :root and never redeclared under .theme-dark, and only
|
|
the hover state lifts (#c31c14 light, #ff4d43 dark). Match that exactly. */
|
|
--wd-accent: var(--wd-red-500);
|
|
--wd-accent-press: #ff4d43;
|
|
--wd-accent-on: #ffffff;
|
|
/* Status tokens are separate from the brand accent by design-system rule, and
|
|
here they carry small text in a dense table. #e1261c on near-black is about
|
|
3.8:1, under AA for small text, so these lift where the accent does not. */
|
|
--wd-ok: #2fbf6a;
|
|
--wd-warn: #e0a516;
|
|
--wd-danger: #ff5c50;
|
|
}
|
|
|
|
/* ------------------------------------------------------------------
|
|
Escape Obsidian's readable-line-length cap.
|
|
|
|
With "Readable line length" on (the default), Obsidian caps note
|
|
content at --file-line-width, roughly 700px. That is right for prose
|
|
and wrong for a two-pane dashboard, which gets squeezed into a column.
|
|
|
|
:has() scopes this to the sizer that actually contains a dashboard, so
|
|
every other note in the vault keeps its readable width. Both selectors
|
|
are needed: reading view sizes on .markdown-preview-sizer, live preview
|
|
on .cm-sizer.
|
|
|
|
If you would rather not rely on this, the alternatives are Settings ->
|
|
Editor -> Readable line length (off, but that widens every note), or
|
|
adding `cssclasses: wide-dash` to the note's frontmatter and swapping
|
|
the :has() selectors below for `.wide-dash .markdown-preview-sizer`.
|
|
|
|
The plugin also lifts this cap inline in `widenHost()`, which is the path
|
|
that actually carries the load — an inline style cannot lose a specificity
|
|
fight. These rules are the belt-and-braces copy, and they need !important
|
|
because Obsidian's own rule qualifies the sizer with the view class and so
|
|
outranks a bare `.markdown-preview-sizer:has(...)`.
|
|
------------------------------------------------------------------ */
|
|
.markdown-preview-sizer:has(.webinar-dash),
|
|
.markdown-preview-view.is-readable-line-width .markdown-preview-sizer:has(.webinar-dash),
|
|
.markdown-source-view.mod-cm6 .cm-content:has(.webinar-dash),
|
|
.markdown-source-view.mod-cm6 .cm-sizer:has(.webinar-dash) {
|
|
max-width: none !important;
|
|
}
|
|
|
|
.wd-grid {
|
|
display: grid;
|
|
grid-template-columns: minmax(0, 38fr) minmax(0, 62fr);
|
|
gap: 24px;
|
|
}
|
|
.wd-grid > * { min-width: 0; }
|
|
|
|
.wd-bar {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 12px;
|
|
flex-wrap: wrap;
|
|
border: 1px solid var(--wd-border);
|
|
border-radius: 4px;
|
|
padding: 8px 12px;
|
|
background: var(--wd-bg-subtle);
|
|
}
|
|
|
|
.wd-btn-ghost {
|
|
background: transparent;
|
|
color: var(--wd-fg);
|
|
border-color: var(--wd-border-strong);
|
|
}
|
|
.wd-btn-ghost:hover {
|
|
background: var(--wd-bg-muted, var(--wd-bg-subtle));
|
|
border-color: var(--wd-border-strong);
|
|
}
|
|
|
|
.wd-pane { display: flex; flex-direction: column; gap: 20px; }
|
|
|
|
/* The coverage pane sits behind a hairline with a 24px inset, so its table does
|
|
not run flush against the gap between the two panes. The table cells are
|
|
deliberately zero-padded on the left (`.wd-tbl td`) so the concept column
|
|
aligns with the eyebrow above it — that alignment only reads correctly when
|
|
the pane itself provides the inset, which is what this rule restores. */
|
|
.wd-pane-right {
|
|
border-left: 1px solid var(--wd-border);
|
|
padding-left: 24px;
|
|
}
|
|
|
|
.wd-eyebrow {
|
|
font-family: var(--wd-mono); font-size: 11px; line-height: 1;
|
|
letter-spacing: 0.12em; text-transform: uppercase;
|
|
color: var(--wd-fg-3); font-weight: 500;
|
|
display: flex; align-items: center; gap: 8px;
|
|
}
|
|
.wd-eyebrow::before {
|
|
content: ""; width: 5px; height: 5px; flex: none; background: var(--wd-accent);
|
|
}
|
|
|
|
.wd-block { display: flex; flex-direction: column; gap: 12px; }
|
|
|
|
.wd-row {
|
|
display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
|
|
border: 1px solid var(--wd-border); border-radius: 4px;
|
|
padding: 12px 12px 12px 16px; background: var(--wd-bg);
|
|
}
|
|
.wd-row + .wd-row { margin-top: -1px; }
|
|
.wd-row-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
|
|
.wd-row-name {
|
|
font-size: 14px; font-weight: 600;
|
|
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
|
}
|
|
.wd-mono {
|
|
font-family: var(--wd-mono); font-size: 11px; color: var(--wd-fg-3);
|
|
font-variant-numeric: tabular-nums;
|
|
}
|
|
|
|
.wd-btn {
|
|
display: inline-flex; align-items: center; gap: 6px; flex: none;
|
|
font-family: var(--wd-sans); font-size: 13px; font-weight: 600;
|
|
padding: 6px 12px; border-radius: 6px; cursor: pointer;
|
|
border: 1px solid var(--wd-accent); background: var(--wd-accent);
|
|
color: var(--wd-accent-on);
|
|
transition: background 120ms cubic-bezier(0.2, 0, 0, 1);
|
|
}
|
|
.wd-btn:hover { background: var(--wd-accent-press); border-color: var(--wd-accent-press); }
|
|
.wd-btn:focus-visible { outline: 2px solid var(--wd-accent); outline-offset: 2px; }
|
|
.wd-btn[disabled] {
|
|
opacity: 0.45; cursor: not-allowed;
|
|
background: transparent; color: var(--wd-fg-3); border-color: var(--wd-border);
|
|
}
|
|
.wd-btn svg { width: 14px; height: 14px; flex: none; }
|
|
|
|
.wd-done { display: flex; flex-direction: column; }
|
|
.wd-done-row {
|
|
display: flex; align-items: baseline; gap: 12px; padding: 5px 0;
|
|
border-bottom: 1px solid var(--wd-border-subtle); font-size: 13px;
|
|
}
|
|
.wd-done-row:last-child { border-bottom: 0; }
|
|
.wd-done-name {
|
|
color: var(--wd-fg-2);
|
|
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
|
}
|
|
|
|
.wd-note { font-size: 12px; color: var(--wd-fg-3); }
|
|
.wd-error {
|
|
font-size: 13px; color: var(--wd-danger);
|
|
border: 1px solid var(--wd-danger); border-radius: 4px; padding: 12px;
|
|
}
|
|
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.webinar-dash * { transition-duration: 0.01ms !important; }
|
|
}
|
|
|
|
.wd-meter { display: flex; gap: 2px; height: 8px; width: 100%; }
|
|
.wd-meter > i { display: block; height: 100%; }
|
|
.wd-seg-covered { background: var(--wd-ok); }
|
|
.wd-seg-partial { background: var(--wd-warn); }
|
|
.wd-seg-absent { background: var(--wd-danger); }
|
|
|
|
.wd-key { display: flex; flex-wrap: wrap; gap: 16px; font-size: 12px; color: var(--wd-fg-2); }
|
|
.wd-key > span { display: inline-flex; align-items: center; gap: 6px; }
|
|
.wd-key i { width: 8px; height: 8px; flex: none; }
|
|
|
|
.wd-tbl { width: 100%; border-collapse: collapse; font-size: 13px; }
|
|
.wd-tbl th {
|
|
font-family: var(--wd-mono); font-size: 10px; letter-spacing: 0.1em;
|
|
text-transform: uppercase; color: var(--wd-fg-3); font-weight: 500;
|
|
/* Symmetric horizontal padding. These were `... 0` on the left, which left
|
|
the concept column flush against the pane edge and every other column
|
|
hard against the preceding cell's text. */
|
|
text-align: left; padding: 0 12px 8px;
|
|
border-bottom: 1px solid var(--wd-border-strong);
|
|
}
|
|
.wd-tbl td {
|
|
padding: 6px 12px; border-bottom: 1px solid var(--wd-border-subtle);
|
|
vertical-align: baseline;
|
|
}
|
|
.wd-grp td {
|
|
padding-top: 16px; border-bottom: 1px solid var(--wd-border-strong);
|
|
font-family: var(--wd-mono); font-size: 10px; letter-spacing: 0.1em;
|
|
text-transform: uppercase; color: var(--wd-fg); font-weight: 500;
|
|
}
|
|
.wd-stat { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; font-weight: 600; }
|
|
.wd-stat svg { width: 13px; height: 13px; flex: none; }
|
|
.wd-covered { color: var(--wd-ok); }
|
|
.wd-partial { color: var(--wd-warn); }
|
|
.wd-absent { color: var(--wd-danger); }
|
|
.wd-pin { font-family: var(--wd-mono); font-size: 10px; color: var(--wd-fg-4); }
|
|
|
|
.wd-status { font-family: var(--wd-mono); font-size: 11px; flex: none; }
|
|
.wd-status-running { color: var(--wd-warn); }
|
|
.wd-status-done { color: var(--wd-ok); }
|
|
.wd-status-failed { color: var(--wd-danger); }
|
|
.wd-output {
|
|
flex-basis: 100%;
|
|
width: 100%;
|
|
font-family: var(--wd-mono); font-size: 11px; white-space: pre-wrap;
|
|
max-height: 220px; overflow: auto; margin-top: 8px;
|
|
border: 1px solid var(--wd-border); border-radius: 4px; padding: 8px;
|
|
color: var(--wd-fg-2);
|
|
}
|
|
|
|
/* ------------------------------------------------------------------
|
|
Responsive overrides — deliberately last in the file.
|
|
|
|
At-rules do not raise specificity: a rule inside @container or @media
|
|
competes with the base rule on source order alone. These blocks were
|
|
previously above the .wd-pane-right base rule, so the base rule won
|
|
and the collapsed layout silently never applied. Keep every override
|
|
here, after everything it overrides.
|
|
|
|
Collapse on the width that actually matters — the pane's, not the
|
|
window's. A media query measures the window, so a wide window with the
|
|
dashboard in a narrow split pane would keep two cramped columns. The
|
|
container query responds to the pane itself; the media query stays as
|
|
a floor for a genuinely narrow window.
|
|
------------------------------------------------------------------ */
|
|
@container (max-width: 820px) {
|
|
.wd-grid { grid-template-columns: minmax(0, 1fr); }
|
|
/* Stacked, the divider belongs above the pane, not beside it. */
|
|
.wd-pane-right {
|
|
border-left: 0;
|
|
padding-left: 0;
|
|
border-top: 1px solid var(--wd-border);
|
|
padding-top: 20px;
|
|
}
|
|
}
|
|
|
|
@media (max-width: 820px) {
|
|
.wd-grid { grid-template-columns: minmax(0, 1fr); }
|
|
.wd-pane-right {
|
|
border-left: 0;
|
|
padding-left: 0;
|
|
border-top: 1px solid var(--wd-border);
|
|
padding-top: 20px;
|
|
}
|
|
}
|