Move remaining static inline styles into dashboard.css, bump Now Playing text size
Three inline style="..." attributes were pure styling with no per-request data behind them (a hero-block spacing tweak, a trailing note's margin, a gap between two stacked rows) — moved each into dashboard.css as a scoped structural selector so future adjustments happen in one place instead of being split between the template and the stylesheet. Also bumped .stream-title/.stream-user/.stream-icon in the Now Playing card one step up the existing --fs-* scale (13px->15px, 12px->13px, 15px->18px) rather than introducing a one-off size. Documented the "styles belong in CSS, not inline" rule in CLAUDE.md, with the actual exception: per-request computed values (a meter's width, a threshold colour) and JS-toggled initial visibility still can't live in a static stylesheet and are fine to stay inline. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
1cc5a247cf
commit
326ab6cee5
3 changed files with 26 additions and 6 deletions
11
CLAUDE.md
11
CLAUDE.md
|
|
@ -42,6 +42,17 @@ the user's Unraid home server. Server-side project directory is still named
|
||||||
`SCRIPT_NAME` subpath. Server-rendered config (timezone, script root)
|
`SCRIPT_NAME` subpath. Server-rendered config (timezone, script root)
|
||||||
reaches JS through `<body data-*>`, never string-interpolated into a
|
reaches JS through `<body data-*>`, never string-interpolated into a
|
||||||
script block.
|
script block.
|
||||||
|
- **No `style="..."` attributes for anything static.** A one-off tweak
|
||||||
|
(button height, a margin, a font size) belongs in the matching
|
||||||
|
`static/css/*.css` file, scoped with a structural selector (an
|
||||||
|
adjacent-sibling or `:last-child` rule tied to the surrounding markup)
|
||||||
|
or a small modifier class — not inline on the element. The only
|
||||||
|
legitimate inline `style=` left in `dashboard.html` are per-request
|
||||||
|
computed values Jinja has to interpolate (a meter's `width: {{ pct
|
||||||
|
}}%`, a colour chosen by threshold) and JS-toggled initial visibility
|
||||||
|
(`display:none` on something `dashboard.js` reveals) — those can't
|
||||||
|
live in a static stylesheet. Everything else should read as a class
|
||||||
|
name, not a value.
|
||||||
- **`static/css/base.css`** — the single source of truth for the design
|
- **`static/css/base.css`** — the single source of truth for the design
|
||||||
tokens, shared by all three templates: surfaces, a 6-step `--fs-*` type
|
tokens, shared by all three templates: surfaces, a 6-step `--fs-*` type
|
||||||
scale, semantic colours, and `--tap: 44px` for minimum touch targets.
|
scale, semantic colours, and `--tap: 44px` for minimum touch targets.
|
||||||
|
|
|
||||||
|
|
@ -131,6 +131,9 @@ main {
|
||||||
}
|
}
|
||||||
.row.cols-3 { grid-template-columns: repeat(3, 1fr); }
|
.row.cols-3 { grid-template-columns: repeat(3, 1fr); }
|
||||||
.row.cols-2 { grid-template-columns: repeat(2, 1fr); }
|
.row.cols-2 { grid-template-columns: repeat(2, 1fr); }
|
||||||
|
/* A section with two stacked rows (Watch insights) needs the same gap
|
||||||
|
between them as the grid uses between columns. */
|
||||||
|
.row + .row { margin-top: var(--gap); }
|
||||||
|
|
||||||
/* ── Card ───────────────────────────────────────────── */
|
/* ── Card ───────────────────────────────────────────── */
|
||||||
.card {
|
.card {
|
||||||
|
|
@ -193,13 +196,13 @@ main {
|
||||||
border-top: 1px solid var(--border);
|
border-top: 1px solid var(--border);
|
||||||
}
|
}
|
||||||
.stream:first-child { border-top: none; padding-top: 0; }
|
.stream:first-child { border-top: none; padding-top: 0; }
|
||||||
.stream-icon { font-size: var(--fs-base); flex-shrink: 0; }
|
.stream-icon { font-size: var(--fs-lg); flex-shrink: 0; }
|
||||||
.stream-info { min-width: 0; flex: 1; }
|
.stream-info { min-width: 0; flex: 1; }
|
||||||
.stream-title {
|
.stream-title {
|
||||||
font-size: var(--fs-sm); font-weight: 600;
|
font-size: var(--fs-base); font-weight: 600;
|
||||||
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
.stream-user { font-size: var(--fs-xs); color: var(--text-3); }
|
.stream-user { font-size: var(--fs-sm); color: var(--text-3); }
|
||||||
.live-dot {
|
.live-dot {
|
||||||
width: 7px; height: 7px; border-radius: 50%;
|
width: 7px; height: 7px; border-radius: 50%;
|
||||||
background: var(--ok); flex-shrink: 0;
|
background: var(--ok); flex-shrink: 0;
|
||||||
|
|
@ -242,6 +245,10 @@ dl.stats {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
|
grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
|
||||||
}
|
}
|
||||||
|
/* Only the Downloads card stacks stats below the hero figure/sub block —
|
||||||
|
give that pairing breathing room without affecting stats blocks that
|
||||||
|
open a card (Sonarr/Radarr put dl.stats right after the search bar). */
|
||||||
|
.card-body > [aria-live="polite"] + dl.stats { margin-top: 0.9rem; }
|
||||||
dl.stats > div {
|
dl.stats > div {
|
||||||
background: var(--surface-2);
|
background: var(--surface-2);
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
|
|
@ -595,6 +602,8 @@ dd.is-accent { color: var(--accent); }
|
||||||
}
|
}
|
||||||
|
|
||||||
.empty { color: var(--text-3); font-size: var(--fs-sm); }
|
.empty { color: var(--text-3); font-size: var(--fs-sm); }
|
||||||
|
/* Storage card's usage note trails the meter with no room to spare below it. */
|
||||||
|
.meter-legend + .empty { margin-bottom: 0; }
|
||||||
|
|
||||||
/* ── Errors ─────────────────────────────────────────── */
|
/* ── Errors ─────────────────────────────────────────── */
|
||||||
.error {
|
.error {
|
||||||
|
|
|
||||||
|
|
@ -130,7 +130,7 @@
|
||||||
<span id="sab-timeleft-row" style="display:none;"> · ETA <span id="sab-timeleft"></span></span>
|
<span id="sab-timeleft-row" style="display:none;"> · ETA <span id="sab-timeleft"></span></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<dl class="stats" style="margin-top:0.9rem;">
|
<dl class="stats">
|
||||||
<div><dt>Avg speed (7d)</dt><dd>{{ sabnzbd.avg_speed }}</dd></div>
|
<div><dt>Avg speed (7d)</dt><dd>{{ sabnzbd.avg_speed }}</dd></div>
|
||||||
<div><dt>Grabbed (7d)</dt><dd>{{ sabnzbd.completed_7d }}</dd></div>
|
<div><dt>Grabbed (7d)</dt><dd>{{ sabnzbd.completed_7d }}</dd></div>
|
||||||
<div><dt>Volume (7d)</dt><dd>{{ sabnzbd.week_size }}</dd></div>
|
<div><dt>Volume (7d)</dt><dd>{{ sabnzbd.week_size }}</dd></div>
|
||||||
|
|
@ -168,7 +168,7 @@
|
||||||
{% if unraid.disk_count %}<span>{{ unraid.disk_count }} disk{{ 's' if unraid.disk_count != 1 }}</span>{% endif %}
|
{% if unraid.disk_count %}<span>{{ unraid.disk_count }} disk{{ 's' if unraid.disk_count != 1 }}</span>{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% if unraid.source == "local" %}
|
{% if unraid.source == "local" %}
|
||||||
<p class="empty" style="margin-bottom:0;">Container disk usage ({{ unraid.mount }}). Set <code>UNRAID_API_KEY</code> for full array stats.</p>
|
<p class="empty">Container disk usage ({{ unraid.mount }}). Set <code>UNRAID_API_KEY</code> for full array stats.</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if unraid.disks or unraid.caches %}
|
{% if unraid.disks or unraid.caches %}
|
||||||
|
|
@ -520,7 +520,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if tautulli.top_tv_list or tautulli.top_movie_list %}
|
{% if tautulli.top_tv_list or tautulli.top_movie_list %}
|
||||||
<div class="row cols-2" style="margin-top: var(--gap);">
|
<div class="row cols-2">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header"><h3>Top TV</h3></div>
|
<div class="card-header"><h3>Top TV</h3></div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue