UI consistency (page shell 1/2): extract shared .page-shell primitive

First step of the page-layout-shell standardization (kettui's UI-consistency
point #1). The dashboard, tools, watchlist and wishlist pages each defined a
byte-identical "card" container (padding 28px 24px 30px, margin 20px, gradient
bg, radius 24px, border + border-top, layered shadow) under four different
class names.

Extract that into a single `.page-shell` primitive (modeled on the canonical
dashboard/stats look) and have the four pages adopt it. Each keeps its bespoke
class for page-specific extras and as a JS/mobile hook:
- dashboard-container: keeps display:flex / column / gap:25px
- watchlist/wishlist-page-container: keep position:relative
- tools-page-container: no extras (box now fully from .page-shell)

Zero visual change: computed styles are identical (declarations relocated, not
altered), and mobile.css overrides still target the retained bespoke classes.
Per-page themed headers (watchlist amber, etc.) are intentionally NOT touched.

The class name is intended for reuse by the React pages too, so the primitive
is shared across both stacks.

Next (wave 2): migrate settings / automations / playlist-explorer / library
onto .page-shell, which snaps their slightly-off spacing to canonical.
This commit is contained in:
BoulderBadgeDad 2026-05-28 22:38:55 -07:00
parent 4bbb0913fa
commit d2a730a6aa
2 changed files with 21 additions and 50 deletions

View file

@ -311,7 +311,7 @@
<!-- Dashboard Page -->
<div class="page" id="dashboard-page">
<div class="dashboard-container">
<div class="page-shell dashboard-container">
<div class="dashboard-header">
<div class="header-text">
<h2 class="header-title"><img src="/static/dashboard.png" class="page-header-icon" alt=""><span>System Dashboard</span></h2>
@ -6322,7 +6322,7 @@
TOOLS PAGE
═══════════════════════════════════════════════════════════════════ -->
<div class="page" id="tools-page">
<div class="tools-page-container">
<div class="page-shell tools-page-container">
<div class="tools-page-header">
<div class="tools-page-header-left">
<h2 class="tools-page-title">
@ -6779,7 +6779,7 @@
WATCHLIST PAGE
═══════════════════════════════════════════════════════════════════ -->
<div class="page" id="watchlist-page">
<div class="watchlist-page-container">
<div class="page-shell watchlist-page-container">
<!-- Header -->
<div class="watchlist-page-header">
<div class="watchlist-page-header-left">
@ -6895,7 +6895,7 @@
WISHLIST PAGE
═══════════════════════════════════════════════════════════════════ -->
<div class="page" id="wishlist-page">
<div class="wishlist-page-container">
<div class="page-shell wishlist-page-container">
<!-- Header -->
<div class="wishlist-page-header">
<div class="wishlist-page-header-left">

View file

@ -7990,13 +7990,13 @@ body.helper-mode-active #dashboard-activity-feed:hover {
/* ======================================================= */
/* Main Dashboard Layout */
.dashboard-container {
display: flex;
flex-direction: column;
gap: 25px;
/* Spacing between sections */
padding: 28px 24px 30px 24px;
/* Shared page shell
The canonical page card (the dashboard / stats look). Adopted by the
dashboard, tools, watchlist and wishlist pages and intended for reuse
by the React pages too (same class name). Page-specific extras (flex
layout, position) stay on the per-page class. */
.page-shell {
padding: 28px 24px 30px;
/* Semi-transparent to let page particles show through */
background: linear-gradient(135deg,
rgba(20, 20, 20, 0.55) 0%,
@ -8005,7 +8005,6 @@ body.helper-mode-active #dashboard-activity-feed:hover {
border: 1px solid rgba(255, 255, 255, 0.08);
border-top: 1px solid rgba(255, 255, 255, 0.12);
margin: 20px;
/* Soft floating shadow */
box-shadow:
0 8px 32px rgba(0, 0, 0, 0.3),
@ -8013,6 +8012,13 @@ body.helper-mode-active #dashboard-activity-feed:hover {
inset 0 1px 0 rgba(255, 255, 255, 0.08);
}
.dashboard-container {
display: flex;
flex-direction: column;
gap: 25px;
/* Spacing between sections; card styling comes from .page-shell */
}
.dashboard-section {
display: flex;
flex-direction: column;
@ -59446,20 +59452,7 @@ body.reduce-effects *::after {
TOOLS PAGE
*/
.tools-page-container {
padding: 28px 24px 30px;
margin: 20px;
background: linear-gradient(135deg,
rgba(20, 20, 20, 0.55) 0%,
rgba(12, 12, 12, 0.62) 100%);
border-radius: 24px;
border: 1px solid rgba(255, 255, 255, 0.08);
border-top: 1px solid rgba(255, 255, 255, 0.12);
box-shadow:
0 8px 32px rgba(0, 0, 0, 0.3),
0 4px 16px rgba(0, 0, 0, 0.2),
inset 0 1px 0 rgba(255, 255, 255, 0.08);
}
/* .tools-page-container: card styling now from .page-shell (no extras). */
.tools-page-header {
padding: 20px 24px 18px;
@ -59632,18 +59625,7 @@ body.reduce-effects *::after {
*/
.watchlist-page-container {
padding: 28px 24px 30px;
margin: 20px;
background: linear-gradient(135deg,
rgba(20, 20, 20, 0.55) 0%,
rgba(12, 12, 12, 0.62) 100%);
border-radius: 24px;
border: 1px solid rgba(255, 255, 255, 0.08);
border-top: 1px solid rgba(255, 255, 255, 0.12);
box-shadow:
0 8px 32px rgba(0, 0, 0, 0.3),
0 4px 16px rgba(0, 0, 0, 0.2),
inset 0 1px 0 rgba(255, 255, 255, 0.08);
/* card styling from .page-shell; keep page-specific positioning */
position: relative;
}
@ -60044,18 +60026,7 @@ body.reduce-effects *::after {
*/
.wishlist-page-container {
padding: 28px 24px 30px;
margin: 20px;
background: linear-gradient(135deg,
rgba(20, 20, 20, 0.55) 0%,
rgba(12, 12, 12, 0.62) 100%);
border-radius: 24px;
border: 1px solid rgba(255, 255, 255, 0.08);
border-top: 1px solid rgba(255, 255, 255, 0.12);
box-shadow:
0 8px 32px rgba(0, 0, 0, 0.3),
0 4px 16px rgba(0, 0, 0, 0.2),
inset 0 1px 0 rgba(255, 255, 255, 0.08);
/* card styling from .page-shell; keep page-specific positioning */
position: relative;
}