feat(design): warm↔cool gradient + edge-light response on chips #115

Merged
varutasu merged 1 commit from two-light-source-edge-glow into main 2026-06-04 13:23:22 -04:00
3 changed files with 121 additions and 61 deletions

View file

@ -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. */}
<div
className="flex-1 flex flex-col md:rounded-3xl md:overflow-hidden min-h-0"
style={{
background: 'var(--glass-surface-mid)',
backdropFilter: 'blur(var(--glass-blur-mid)) saturate(var(--glass-saturate))',
WebkitBackdropFilter: 'blur(var(--glass-blur-mid)) saturate(var(--glass-saturate))',
boxShadow: 'var(--rim-light-inner), var(--elevation-ambient)',
boxShadow:
'var(--edge-light-warm), var(--edge-light-cool), var(--rim-light-inner), var(--elevation-ambient)',
}}
>
<div className="p-4 h-full flex flex-col w-full">

View file

@ -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

View file

@ -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). Indigoviolet 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 indigoviolet 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 warmcoolrimelevation 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);