Files
WebinarNotes/.obsidian/plugins/webinar-dash/styles.css
meels ef2e2bd14f fix: give table cells symmetric horizontal padding
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.
2026-07-28 16:53:25 +02:00

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;
}
}