fix(design-v2): match approved mockups — solid navy, side rail, editorial type
CI / test (push) Has been cancelled

v2 was 'harbor backdrop everywhere + glass cards', but the approved
mockups at _design/atmospheric-redesign/ use solid navy with subtle
gradient, harbor selectively (theme swatches, frame heroes), left
side rail at desktop, and editorial Marcellus/Cormorant typography.

This rewrite:
- Drops the full-page harbor backdrop; body is now solid navy with
  a single radial gradient highlight
- Loads Marcellus, Cormorant Garamond, DM Mono via Google Fonts
- Editorial type recipes: h1/h2/h3 + frame card name + settings title
  use Marcellus. settings__hint becomes italic Cormorant. Section
  labels become DM Mono caps with 0.28em letterspacing
- TopNav restyled at desktop (≥960px) into a left-fixed side rail:
  240px wide, vertical stack of nav items, active item shows inset
  yellow rule + surface bg. Body gets 240px padding-left to shift
  content right.
- Theme swatches reuse the harbor.jpg inside their preview area,
  tinted to each dusk's color — matches the mockup exactly
- Per-dusk surface colors made opaque (was rgba 0.55) so cards are
  fully readable

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-15 14:55:19 -04:00
parent 4f78ed8897
commit 645291c724
13 changed files with 204 additions and 167 deletions
+195 -158
View File
@@ -1,217 +1,254 @@
// ─── Design v2 — atmospheric dusks ──────────────────────────────────────
// Opt-in overlay activated via [data-design="v2"] on <html>. The user's
// theme preference (warm-craft, ocean-dusk, etc.) chooses *which* dusk;
// all six get a tinted-photo backdrop and a darker, glass-friendly token set.
//
// The yellow V (brand) stays #f0d000 across every dusk.
// Opt-in overlay activated via [data-design="v2"] on <html>. Matches the
// approved mockups at _design/atmospheric-redesign/ — solid navy ground,
// harbor photo used selectively as content (theme swatches, frame heroes,
// login splash), editorial typography (Marcellus + Cormorant Garamond),
// left side rail at desktop.
// Editorial fonts — loaded for v2 only
@import url('https://fonts.googleapis.com/css2?family=Marcellus&family=Cormorant+Garamond:ital,wght@0,400;0,500;1,400&family=DM+Mono:wght@400;500&display=swap');
[data-design="v2"] {
// Brand constants survive every theme/dusk
// ── Brand constants (survive every dusk) ──────────────────────────
--brand-yellow: #f0d000;
// Default dusk = warm-craft → "amber dusk"
// Glass opacity bumped to ~0.82 so cards stay readable on top of the
// harbor photo (0.55 was too transparent — text disappeared into the bg).
// ── Typography ────────────────────────────────────────────────────
--font-display: 'Marcellus', Georgia, serif;
--font-accent: 'Cormorant Garamond', Georgia, serif;
--font-mono: 'DM Mono', ui-monospace, monospace;
// Body stays Nunito (warmer + better-readable at small sizes than serif)
// ── Default dusk = warm-craft → "amber dusk" ──────────────────────
--color-bg: #1a0d05;
--color-surface: rgba(36, 18, 6, 0.85);
--color-surface-2: rgba(58, 28, 10, 0.85);
--color-border: rgba(230, 180, 130, 0.32);
--color-surface: #2a1810;
--color-surface-2: #3a241a;
--color-border: rgba(230, 180, 130, 0.20);
--color-text: #faecd0;
--color-text-muted: #d0b08c;
--color-text-muted: #c8a880;
--color-primary: #e89048;
--color-primary-fg: #1a0d05;
--color-secondary: rgba(58, 28, 10, 0.85);
--color-secondary: #3a241a;
--color-secondary-fg:#faecd0;
--color-destructive: #e08070;
--color-destructive-fg: #ffffff;
--color-focus-ring: var(--brand-yellow);
// Per-theme dusk overrides — only the bg-tint + accent change between dusks
&[data-theme="ocean-dusk"] {
--color-bg: #06121f;
--color-surface: rgba(10, 26, 44, 0.85);
--color-surface-2: rgba(18, 40, 66, 0.85);
--color-border: rgba(180, 210, 235, 0.30);
--color-text: #f4eed8;
--color-text-muted: #c0d0e0;
--color-primary: #4e9fc8;
--color-primary-fg: #06121f;
--color-bg: #06121f; --color-surface: #0e2030; --color-surface-2: #142a40;
--color-border: rgba(180,210,235,0.20);
--color-text: #f4eed8; --color-text-muted: #b8c8d8;
--color-primary: #4e9fc8; --color-primary-fg: #06121f;
--color-secondary: #142a40;
}
&[data-theme="sage-cream"] {
--color-bg: #081208;
--color-surface: rgba(14, 32, 18, 0.85);
--color-surface-2: rgba(24, 50, 28, 0.85);
--color-border: rgba(180, 220, 180, 0.28);
--color-text: #ecf3e0;
--color-text-muted: #b8d0b0;
--color-primary: #88c068;
--color-primary-fg: #081208;
--color-bg: #081208; --color-surface: #142418; --color-surface-2: #1c3022;
--color-border: rgba(180,220,180,0.18);
--color-text: #ecf3e0; --color-text-muted: #a8c0a0;
--color-primary: #88c068; --color-primary-fg: #081208;
--color-secondary: #1c3022;
}
&[data-theme="playful-pop"] {
--color-bg: #1a060f;
--color-surface: rgba(40, 12, 30, 0.85);
--color-surface-2: rgba(60, 20, 48, 0.85);
--color-border: rgba(230, 180, 200, 0.30);
--color-text: #f8e8ec;
--color-text-muted: #d8b0c0;
--color-primary: #d878a0;
--color-primary-fg: #1a060f;
--color-bg: #1a060f; --color-surface: #281020; --color-surface-2: #381a30;
--color-border: rgba(230,180,200,0.20);
--color-text: #f8e8ec; --color-text-muted: #d0a0b8;
--color-primary: #d878a0; --color-primary-fg: #1a060f;
--color-secondary: #381a30;
}
&[data-theme="dusty-mauve"] {
--color-bg: #100618;
--color-surface: rgba(30, 12, 42, 0.85);
--color-surface-2: rgba(46, 20, 64, 0.85);
--color-border: rgba(210, 190, 230, 0.28);
--color-text: #f0e8f8;
--color-text-muted: #c8b8d8;
--color-primary: #b890d8;
--color-primary-fg: #100618;
--color-bg: #100618; --color-surface: #1c1028; --color-surface-2: #281a3a;
--color-border: rgba(210,190,230,0.18);
--color-text: #f0e8f8; --color-text-muted: #c0b0d0;
--color-primary: #b890d8; --color-primary-fg: #100618;
--color-secondary: #281a3a;
}
&[data-theme="honey-slate"] {
--color-bg: #18120a;
--color-surface: rgba(36, 28, 10, 0.85);
--color-surface-2: rgba(54, 42, 18, 0.85);
--color-border: rgba(232, 200, 130, 0.32);
--color-text: #faf0d8;
--color-text-muted: #d8c098;
--color-primary: #e8c050;
--color-primary-fg: #18120a;
--color-bg: #18120a; --color-surface: #281e10; --color-surface-2: #3a2c1a;
--color-border: rgba(232,200,130,0.22);
--color-text: #faf0d8; --color-text-muted: #d0b888;
--color-primary: #e8c050; --color-primary-fg: #18120a;
--color-secondary: #3a2c1a;
}
// Harbor photo backdrop — fixed under everything, theme-tinted
// ── Body: SOLID navy with subtle vignette — no full-page harbor ────
body {
position: relative;
}
body::before {
content: '';
position: fixed;
inset: 0;
background: url('/build/assets/harbor.jpg') center/cover no-repeat;
filter: brightness(0.42) saturate(0.85);
z-index: -3;
}
body::after {
content: '';
position: fixed;
inset: 0;
background:
radial-gradient(ellipse 80% 70% at 50% 50%, transparent 0%, rgba(0,0,0,0.45) 100%),
radial-gradient(ellipse 90% 70% at 50% 30%, color-mix(in srgb, var(--color-surface) 60%, transparent) 0%, transparent 70%),
var(--color-bg);
opacity: 0.70;
mix-blend-mode: multiply;
z-index: -2;
pointer-events: none;
color: var(--color-text);
}
// ─── Top nav — stronger glass so text is readable ─────────────────────
.top-nav {
background: color-mix(in srgb, var(--color-bg) 70%, transparent);
backdrop-filter: saturate(160%) blur(20px);
-webkit-backdrop-filter: saturate(160%) blur(20px);
border-bottom-color: var(--color-border);
// ── Editorial display type — page titles, frame names, section labels ──
h1, h2, h3 { font-family: var(--font-display); font-weight: 400; letter-spacing: 0.005em; }
&__wordmark { color: var(--color-text); }
// ── TopNav restyled (mobile/tablet stays horizontal; desktop becomes
// a left side rail per the mockup) ───────────────────────────────
.top-nav {
background: color-mix(in srgb, var(--color-bg) 95%, transparent);
border-bottom-color: var(--color-border);
&__wordmark { color: var(--color-text); font-family: var(--font-display); font-weight: 400; }
&__tab {
color: var(--color-text-muted);
&:hover { background: var(--color-surface); color: var(--color-text); }
&--active {
background: var(--color-surface-2);
background: var(--color-surface);
color: var(--brand-yellow);
}
}
}
// ─── Bottom nav — same treatment for mobile/tablet ───────────────────
@media (min-width: 960px) {
// Reshape the existing .top-nav into a fixed left rail
.top-nav {
position: fixed;
top: 0; left: 0; bottom: 0;
width: 240px;
height: auto;
flex-direction: column;
align-items: stretch;
gap: 0;
padding: 28px 18px 24px;
padding-top: calc(28px + env(safe-area-inset-top));
background: color-mix(in srgb, var(--color-bg) 96%, transparent);
border-right: 1px solid var(--color-border);
border-bottom: 0;
z-index: 50;
&__brand {
padding-bottom: 20px;
margin-bottom: 16px;
border-bottom: 1px solid var(--color-border);
}
&__wordmark { font-size: var(--text-xl); }
&__tabs {
flex-direction: column;
gap: 4px;
align-items: stretch;
margin-left: 0;
}
&__tab {
width: 100%;
justify-content: flex-start;
padding: 12px 14px;
gap: 12px;
border-radius: var(--radius-md);
&--active {
background: var(--color-surface);
box-shadow: inset 3px 0 0 var(--brand-yellow);
}
}
}
// Shift main content right of the rail
body { padding-left: 240px; }
}
// ── Bottom nav (mobile/tablet only) ─────────────────────────────────
.bottom-nav {
background: color-mix(in srgb, var(--color-bg) 78%, transparent);
backdrop-filter: saturate(160%) blur(20px);
-webkit-backdrop-filter: saturate(160%) blur(20px);
background: color-mix(in srgb, var(--color-bg) 95%, transparent);
border-top-color: var(--color-border);
.bottom-nav__tab--active { color: var(--brand-yellow); }
}
// ─── Theme swatches — each previews ITS OWN dusk in v2 ─────────────────
// Each swatch's --swatch-bg / --swatch-primary are set inline by SettingsView
// from the v1 THEMES table. Override per-swatch via the aria-label so each
// tile previews its dusk variant regardless of which theme is active.
.theme-swatch {
// ── Glass cards — solid-ish at v2 (mockup uses near-solid panels) ──
.frame-card,
.home-view__empty-card,
.library__tile,
.settings__section-card {
background: var(--color-surface);
border-color: var(--color-border);
&--active { border-color: var(--brand-yellow); }
&__label { color: var(--color-text); }
box-shadow:
0 1px 0 color-mix(in srgb, var(--color-text) 8%, transparent) inset,
0 24px 48px -16px rgba(0,0,0,0.6);
}
.theme-swatch[aria-label*="Warm Craft" i] {
background: #2a1808; --swatch-primary: #e89048;
}
.theme-swatch[aria-label*="Ocean Dusk" i] {
background: #0c1c2e; --swatch-primary: #4e9fc8;
}
.theme-swatch[aria-label*="Sage" i] {
background: #122418; --swatch-primary: #88c068;
}
.theme-swatch[aria-label*="Playful" i] {
background: #2a0e1e; --swatch-primary: #d878a0;
}
.theme-swatch[aria-label*="Dusty" i] {
background: #1e0c2a; --swatch-primary: #b890d8;
}
.theme-swatch[aria-label*="Honey" i] {
background: #241c0e; --swatch-primary: #e8c050;
}
.theme-swatch__bar { background: var(--swatch-primary); }
.theme-swatch__dot { background: var(--swatch-primary); opacity: 0.6; }
// ─── Buttons — primary stays accent-coloured; secondary becomes glass ──
// The .settings__install button is the main primary action; keep it
// accent-coloured so it's clearly tappable. But its text-color was hard
// to read on the bright orange — force light text on accent.
.settings__install {
color: var(--color-primary-fg);
// ── Frame card hero — keep solid navy area (the user's photo goes here
// when device is online; placeholder when offline) ────────────────
.frame-card__hero {
background: var(--color-surface-2);
}
// The design toggle cards in Settings should look like glass cards, not
// the v1 cream rectangles. (Selectors mirror the toggle markup.)
// ── Frame card name uses editorial serif ───────────────────────────
.frame-card__name {
font-family: var(--font-display);
font-weight: 400;
font-size: var(--text-xl);
}
// ── Home view editorial polish ─────────────────────────────────────
.home-view {
&__empty-title { font-family: var(--font-display); }
}
// ── Library editorial polish ───────────────────────────────────────
.library {
&__add-btn { background: var(--color-primary); color: var(--color-primary-fg); }
}
// ── Settings: page title in display serif ──────────────────────────
.settings {
&__title { font-family: var(--font-display); font-weight: 400; letter-spacing: 0.005em; }
&__section-title {
font-family: var(--font-mono);
font-size: 11px;
letter-spacing: 0.28em;
color: var(--color-text-muted);
}
&__hint {
font-family: var(--font-accent);
font-style: italic;
color: var(--color-text-muted);
}
&__install { color: var(--color-primary-fg); font-weight: 700; }
&__row,
&__action-link { border-color: var(--color-border); }
&__row-label { color: var(--color-text-muted); }
&__row-value,
&__action-link { color: var(--color-text); }
&__logout { color: var(--color-destructive); }
}
// ── Design toggle in Settings ──────────────────────────────────────
.design-toggle__opt {
background: var(--color-surface);
border-color: var(--color-border);
color: var(--color-text);
&:hover { border-color: var(--brand-yellow); }
&--active {
border-color: var(--brand-yellow);
background: var(--color-surface-2);
}
&--active { border-color: var(--brand-yellow); background: var(--color-surface-2); }
}
.design-toggle__sub { color: var(--color-text-muted); }
// ─── Frame card (Home) — let the glass + harbor backdrop show through ──
// The frame card uses --color-surface as its bg already, which is now
// semi-translucent. Add a subtle inset highlight + outer glow for depth.
.frame-card {
box-shadow:
0 1px 0 color-mix(in srgb, var(--color-text) 8%, transparent) inset,
0 24px 48px -16px rgba(0,0,0,0.55);
border-color: var(--color-border);
}
// Settings list rows / dividers
.settings__row,
.settings__action-link {
border-color: var(--color-border);
}
.settings__row-label { color: var(--color-text-muted); }
.settings__row-value,
.settings__action-link { color: var(--color-text); }
.settings__logout { color: var(--color-destructive); }
// Frosted-glass surfaces — anywhere v1 used --color-surface as a solid bg
// becomes a backdrop-blurred semi-translucent panel.
.frame-card,
.library__tile,
.settings__section-card,
.home-view__empty-card,
.design-toggle__opt,
// ── Theme swatches — each previews ITS OWN dusk with the harbor tint
// inside the preview area (matches the mockup) ───────────────────
.theme-swatch {
backdrop-filter: saturate(160%) blur(20px);
-webkit-backdrop-filter: saturate(160%) blur(20px);
border-color: var(--color-border);
background: var(--color-surface);
color: var(--color-text);
&--active { border-color: var(--brand-yellow); }
&__label { color: var(--color-text); }
// Harbor-tinted preview inside each swatch
&__preview {
background-image: url('/build/assets/harbor.jpg');
background-size: cover;
background-position: center;
position: relative;
overflow: hidden;
&::after {
content: '';
position: absolute; inset: 0;
mix-blend-mode: multiply;
}
}
}
.theme-swatch[aria-label*="Warm Craft" i] .theme-swatch__preview::after { background: rgba(60, 25, 8, 0.55); }
.theme-swatch[aria-label*="Ocean Dusk" i] .theme-swatch__preview::after { background: rgba(8, 22, 38, 0.55); }
.theme-swatch[aria-label*="Sage" i] .theme-swatch__preview::after { background: rgba(20, 40, 22, 0.55); }
.theme-swatch[aria-label*="Playful" i] .theme-swatch__preview::after { background: rgba(56, 16, 38, 0.55); }
.theme-swatch[aria-label*="Dusty" i] .theme-swatch__preview::after { background: rgba(40, 18, 56, 0.55); }
.theme-swatch[aria-label*="Honey" i] .theme-swatch__preview::after { background: rgba(48, 36, 14, 0.55); }
// Hide the v1 swatch bars/dot — the harbor preview replaces them
.theme-swatch__bar,
.theme-swatch__dot { display: none; }
}