From 045ce88b6b085dd90087b35bf7be8bcf64e7dfe4 Mon Sep 17 00:00:00 2001 From: Randall Stillwell Date: Thu, 4 Jun 2026 12:20:55 -0500 Subject: [PATCH] =?UTF-8?q?feat(design):=20warm=E2=86=94cool=20gradient=20?= =?UTF-8?q?+=20edge-light=20response=20on=20chips?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Operator feedback 2026-06-04: "increase the gradient in the background that goes from our nice warm red to a nice purpley blue. And then let's have the corners or the edges of our sections respond as if those two are light sources." Two coordinated changes that together create the "lit by two light sources" effect. 1) Body gradient pushed harder + diagonal warm↔cool story (styles/globals.css body { ... } + [data-theme="dark"] body) - Dark theme: * Warm ember pool bottom-left: alpha 0.55 → 0.72, ellipse enlarged from 75%/55% to 95%/70%. * Top-right corner: switched from secondary ember + dim purple-magenta (0.26) to a unified bright purpley-blue pool (alpha 0.58, indigo→violet ramp, 90%/70% ellipse). * Base linear-gradient: 180deg vertical wash → 45deg diagonal (warm aubergine bottom-left → indigo top-right) so the whole page reads as one continuous warm↔cool dialogue, not just two corner pools. - Light theme: * Top-right gold accent replaced with purpley-blue (indigo 0.42 → violet 0.20 → light violet 0.08) so both themes share the same diagonal story. * Bottom-left ember boosted (0.42 → 0.55, ellipse enlarged). * Base linear-gradient: 180deg → 45deg diagonal (warm-cream → cool-violet). 2) Edge-light tokens on every floating chip's shadow stack (styles/globals.css + components/Layout.js + components/ui/TopSearchBar.js) - New design tokens in :root and [data-theme="dark"]: --edge-light-warm (offset -X +Y → glow on the chip's bottom-left edge, matching the warm ember light source) --edge-light-cool (offset +X -Y → glow on the chip's top-right edge, matching the cool purpley-blue light source) Light: 0.16 warm / 0.12 cool. Dark: 0.34 warm / 0.28 cool. - .glass-panel and .glass-panel-strong shadow stacks updated to prepend the two edge-light tokens. Every glass surface in the app now picks up the directional rim glows from the body gradient without per-component changes (DailyEmberWidget, CommandPaletteModal popover, the logged-out sidebar Support/ Theme tray, UserMenu dropdown, etc). - components/Layout.js nav-chip and components/ui/TopSearchBar.js inline boxShadow strings prepended with the same two tokens (they use inline styles rather than the .glass-panel class so they need the explicit shadow stack). Result: the body now visibly transitions from warm ember (bottom- left) through a neutral midpoint to purpley-blue (top-right). Every floating chip's bottom-left and top-right edges pick up subtle directional glow from the matching corner, reading as light wrapping around the chip's rim from the two off-screen-ish light sources. Tests: - npm run test:run: 113/113 - npm run lint: 0 errors (1 pre-existing warning) - npm run build: green Co-authored-by: Cursor --- components/Layout.js | 14 ++- components/ui/TopSearchBar.js | 10 ++- styles/globals.css | 158 +++++++++++++++++++++------------- 3 files changed, 121 insertions(+), 61 deletions(-) diff --git a/components/Layout.js b/components/Layout.js index 3120a3a..7b2348e 100644 --- a/components/Layout.js +++ b/components/Layout.js @@ -845,14 +845,24 @@ export default function Layout({ children, user = null, showSearch = false }) { className="hidden md:flex md:flex-col md:gap-4 w-64" aria-label="Sidebar" > - {/* Nav chip */} + {/* Nav chip. 2026-06-04 two-light-source pass: prepended the + two edge-light tokens so the nav chip's bottom-left and + top-right edges pick up warm + cool directional glows from + the matching corners of the body gradient — the chip + visually "responds" to the two light sources the operator + asked for. The chip is positioned at the top-left of the + viewport so it sits closer to the warm light source; that's + a coincidence of layout, not something the token reacts to, + but the warm glow does naturally read stronger on this chip + because the warm source is right there. */}
diff --git a/components/ui/TopSearchBar.js b/components/ui/TopSearchBar.js index d57f72f..125107a 100644 --- a/components/ui/TopSearchBar.js +++ b/components/ui/TopSearchBar.js @@ -315,7 +315,15 @@ export default function TopSearchBar({ background: 'var(--glass-surface-mid)', backdropFilter: 'blur(12px) saturate(180%)', WebkitBackdropFilter: 'blur(12px) saturate(180%)', - boxShadow: 'var(--rim-light-inner), var(--elevation-ambient)', + // 2026-06-04 two-light-source pass: prepended edge-light + // tokens so the header's bottom-left and top-right edges + // pick up warm + cool directional glows. The header sits + // near the top-right of the viewport so the cool source + // reads stronger on it (the purple light is right above); + // the warm rim still appears on the bottom-left edge of the + // chip, just dimmer at this distance from the ember pool. + boxShadow: + 'var(--edge-light-warm), var(--edge-light-cool), var(--rim-light-inner), var(--elevation-ambient)', }} > {/* Search affordance — read-only-ish input that opens the diff --git a/styles/globals.css b/styles/globals.css index 4c09837..d45316a 100644 --- a/styles/globals.css +++ b/styles/globals.css @@ -200,47 +200,52 @@ body { } /* Apply theme colors. - The hearth gradient: a soft warm wash that gives glass surfaces a real - substrate to blur and distort. Without this the page bg is flat warm- - white and the blur is functionally invisible (the chief reason the - first 3 redesign PRs landed but the user said "still looks the same"). - Two layers: - - A radial ember glow biased to the bottom-left (the seat of a fire) - - A soft vertical gradient from cooler-top to warmer-bottom - Fixed attachment so scrolling content slides over the gradient rather - than pulling it along — that's what gives glass surfaces their - parallax-blur behavior. */ + The hearth gradient: two diagonal light sources that the floating + chrome chips visually "respond" to via the --edge-light-warm / + --edge-light-cool design tokens (defined further down in :root / + [data-theme="dark"]). + - Warm ember light source: bottom-left of the viewport. + - Cool purpley-blue light source: top-right of the viewport. + The base linear-gradient runs along the same 45deg diagonal between + the two sources so the page itself reads as a single continuous + wash, not just two corner pools on a flat substrate. Pushed harder + 2026-06-04 per operator feedback ("increase the gradient in the + background that goes from our nice warm red to a nice purpley + blue") — alphas roughly doubled vs the prior pass, ellipses + enlarged, and the top-right corner switched from gold to + purpley-blue on light theme so both themes carry the same warm↔ + cool diagonal story. + Fixed attachment so scrolling content slides over the gradient + rather than pulling it along — that's what gives glass surfaces + their parallax-blur behavior. */ body { background-color: var(--bg-primary-light); background-image: - /* Bright amber ember pool, bottom-left — "seat of the fire". */ + /* Warm ember pool, bottom-left — primary light source. */ radial-gradient( - ellipse 75% 55% at 8% 108%, - rgba(255, 110, 0, 0.42) 0%, - rgba(255, 140, 30, 0.22) 28%, - rgba(255, 171, 64, 0.08) 55%, - transparent 78% + ellipse 90% 65% at 5% 110%, + rgba(255, 95, 0, 0.55) 0%, + rgba(255, 130, 25, 0.28) 28%, + rgba(255, 171, 64, 0.10) 55%, + transparent 80% ), - /* Secondary amber, bottom-right — balances wide displays. */ + /* Purpley-blue pool, top-right — secondary light source (replaces + the prior gold accent). Indigo→violet so the chip rims that + respond to this source via --edge-light-cool read as cool. */ radial-gradient( - ellipse 60% 50% at 98% 105%, - rgba(255, 130, 20, 0.30) 0%, - rgba(255, 171, 64, 0.10) 45%, - transparent 72% + ellipse 85% 65% at 100% -8%, + rgba(99, 102, 241, 0.42) 0%, + rgba(124, 58, 237, 0.20) 30%, + rgba(167, 139, 250, 0.08) 58%, + transparent 80% ), - /* Gold accent, top-right — "smoke catching last light". */ - radial-gradient( - ellipse 60% 45% at 95% -8%, - rgba(255, 171, 64, 0.24) 0%, - rgba(255, 200, 110, 0.08) 40%, - transparent 68% - ), - /* Base wash: cooler-cream top → warmer-amber-tinted bottom. */ + /* Base diagonal wash: warm-cream bottom-left → cool-violet top-right. + 45deg = bottom-left → top-right (matches the two light sources). */ linear-gradient( - 180deg, - rgba(254, 252, 248, 1) 0%, - rgba(252, 244, 230, 1) 55%, - rgba(250, 233, 210, 1) 100% + 45deg, + rgba(255, 240, 220, 1) 0%, + rgba(252, 244, 230, 1) 50%, + rgba(230, 232, 252, 1) 100% ); background-attachment: fixed; color: var(--text-primary-light); @@ -249,36 +254,36 @@ body { [data-theme="dark"] body { background-color: var(--bg-primary-dark); background-image: - /* Bright ember-red pool, bottom-left — the operator mockup's - defining visual. High alpha against deep navy makes it glow. */ + /* Warm ember-red pool, bottom-left — primary light source. + Pushed to 0.72 (was 0.55) so the operator's "nice warm red" + reads as a real glow against deep navy. */ radial-gradient( - ellipse 75% 55% at 8% 108%, - rgba(255, 75, 30, 0.55) 0%, - rgba(255, 110, 0, 0.30) 25%, - rgba(255, 140, 30, 0.10) 55%, - transparent 78% + ellipse 95% 70% at 5% 110%, + rgba(255, 65, 25, 0.72) 0%, + rgba(255, 95, 0, 0.42) 24%, + rgba(255, 130, 30, 0.16) 52%, + transparent 80% ), - /* Secondary ember, bottom-right. */ + /* Purpley-blue pool, top-right — secondary light source. Pushed + to 0.58 (was 0.26) + a more saturated indigo→violet ramp so + the corner reads unambiguously as the second light source the + chip rims respond to. */ radial-gradient( - ellipse 60% 50% at 98% 105%, - rgba(255, 110, 30, 0.36) 0%, - rgba(255, 140, 50, 0.12) 45%, - transparent 72% + ellipse 90% 70% at 100% -10%, + rgba(139, 92, 246, 0.58) 0%, + rgba(99, 102, 241, 0.32) 28%, + rgba(168, 85, 247, 0.12) 55%, + transparent 82% ), - /* Purple-magenta accent, top-right — the "cosmic" highlight from - the mockup's dark variant. Brings TCG/celestial brand energy. */ - radial-gradient( - ellipse 65% 50% at 95% -8%, - rgba(168, 85, 247, 0.26) 0%, - rgba(124, 58, 237, 0.10) 40%, - transparent 68% - ), - /* Subtle vertical wash: pure deep navy → slightly purpler bottom. */ + /* Base diagonal wash: warm-tinted deep aubergine bottom-left → + cool-tinted deep indigo top-right. 45deg matches the light + sources. The midpoint stays near the previous deep-navy so + chrome surfaces still have a calm substrate to blur against. */ linear-gradient( - 180deg, - rgba(13, 14, 26, 1) 0%, - rgba(17, 18, 38, 1) 55%, - rgba(22, 18, 45, 1) 100% + 45deg, + rgba(40, 16, 22, 1) 0%, + rgba(17, 18, 38, 1) 50%, + rgba(28, 22, 58, 1) 100% ); background-attachment: fixed; color: var(--text-primary-dark); @@ -340,6 +345,21 @@ body { --bg-primary-rgb: 254, 252, 248; --bg-secondary-rgb: 247, 243, 237; --bg-tertiary-rgb: 240, 230, 214; + + /* Two-light-source edge glow tokens (2026-06-04 operator request: + "let's have the corners or the edges of our sections respond as + if those two are light sources"). + Each token is a complete box-shadow declaration with the offset + pointing toward the matching light source — the colored shadow + bleeds outward from the chip's bottom-left edge (warm) and top- + right edge (cool), reading as light catching on the rim. + Light theme alphas are softer; the dark theme override below + bumps them since the deeper substrate can absorb more saturation + before the effect over-reads. Compose into chip shadow stacks + ahead of rim-light-inner + elevation tokens so the directional + glow is the dominant edge cue. */ + --edge-light-warm: -6px 6px 18px rgba(255, 110, 0, 0.16); + --edge-light-cool: 6px -6px 18px rgba(99, 102, 241, 0.12); } /* Dark theme variables */ @@ -366,6 +386,13 @@ body { --input-border: var(--input-border-dark); --input-text: var(--input-text-dark); --input-placeholder: var(--input-placeholder-dark); + + /* Dark-theme edge glows — alphas bumped since the deeper substrate + can take more saturation before reading as garish, and so the + "lit by ember + lit by purple" effect carries on dark theme (the + default for first-time visitors). See :root for full rationale. */ + --edge-light-warm: -8px 8px 26px rgba(255, 110, 30, 0.34); + --edge-light-cool: 8px -8px 26px rgba(139, 92, 246, 0.28); } /* Custom component styles - Fire-themed */ @@ -724,10 +751,23 @@ body { only the `-webkit-` form which modern browsers ignore. Write only the unprefixed form; Lightning CSS's autoprefixer adds the prefix per browserslist (ios_saf <18 still needs it). */ +/* Glass panels — the canonical floating-chrome surface. 2026-06-04 + two-light-source pass: `--edge-light-warm` (offset toward bottom- + left) and `--edge-light-cool` (offset toward top-right) lead the + shadow stack so every glass surface picks up the directional rim + glows from the matching corners of the body gradient. Order + matters — directional glows must paint OUTSIDE the structural + elevation shadow, so they sit at the top of the stack (CSS paints + the LAST listed shadow lowest visually, but for box-shadow the + list order doesn't matter for compositing — what matters is each + shadow's geometry. They're listed warm→cool→rim→elevation as a + readability convention). */ .glass-panel { background: var(--glass-surface-mid); backdrop-filter: blur(12px) saturate(180%); box-shadow: + var(--edge-light-warm), + var(--edge-light-cool), var(--rim-light-inner), var(--rim-light-outer), var(--elevation-ambient); @@ -737,6 +777,8 @@ body { background: var(--glass-surface-high); backdrop-filter: blur(20px) saturate(180%); box-shadow: + var(--edge-light-warm), + var(--edge-light-cool), var(--rim-light-inner), var(--rim-light-outer), var(--elevation-pronounced);