refactor(design): move light response onto chip borders; cut directional drop shadows #116
3 changed files with 109 additions and 65 deletions
|
|
@ -845,24 +845,26 @@ export default function Layout({ children, user = null, showSearch = false }) {
|
||||||
className="hidden md:flex md:flex-col md:gap-4 w-64"
|
className="hidden md:flex md:flex-col md:gap-4 w-64"
|
||||||
aria-label="Sidebar"
|
aria-label="Sidebar"
|
||||||
>
|
>
|
||||||
{/* Nav chip. 2026-06-04 two-light-source pass: prepended the
|
{/* Nav chip. 2026-06-04 corner-border pass: same gradient-
|
||||||
two edge-light tokens so the nav chip's bottom-left and
|
border technique as `.glass-panel` — the chip's fill is
|
||||||
top-right edges pick up warm + cool directional glows from
|
clipped to padding-box, and three border-box-clipped
|
||||||
the matching corners of the body gradient — the chip
|
gradient layers expose the warm bottom-left + cool top-
|
||||||
visually "responds" to the two light sources the operator
|
right catch-lights through a 1px transparent border. The
|
||||||
asked for. The chip is positioned at the top-left of the
|
warm/cool drop shadows that lived here through PR #115
|
||||||
viewport so it sits closer to the warm light source; that's
|
are gone — the directional response is on the border
|
||||||
a coincidence of layout, not something the token reacts to,
|
now, not extending into the body gradient. */}
|
||||||
but the warm glow does naturally read stronger on this chip
|
|
||||||
because the warm source is right there. */}
|
|
||||||
<div
|
<div
|
||||||
className="flex-1 flex flex-col md:rounded-3xl md:overflow-hidden min-h-0"
|
className="flex-1 flex flex-col md:rounded-3xl md:overflow-hidden min-h-0"
|
||||||
style={{
|
style={{
|
||||||
background: 'var(--glass-surface-mid)',
|
background:
|
||||||
|
'linear-gradient(var(--glass-surface-mid), var(--glass-surface-mid)) padding-box, ' +
|
||||||
|
'radial-gradient(at 0% 100%, var(--corner-light-warm) 0%, transparent 42%) border-box, ' +
|
||||||
|
'radial-gradient(at 100% 0%, var(--corner-light-cool) 0%, transparent 42%) border-box, ' +
|
||||||
|
'var(--chip-border-base) border-box',
|
||||||
|
border: '1px solid transparent',
|
||||||
backdropFilter: 'blur(var(--glass-blur-mid)) saturate(var(--glass-saturate))',
|
backdropFilter: 'blur(var(--glass-blur-mid)) saturate(var(--glass-saturate))',
|
||||||
WebkitBackdropFilter: 'blur(var(--glass-blur-mid)) saturate(var(--glass-saturate))',
|
WebkitBackdropFilter: 'blur(var(--glass-blur-mid)) saturate(var(--glass-saturate))',
|
||||||
boxShadow:
|
boxShadow: 'var(--rim-light-inner), var(--elevation-ambient)',
|
||||||
'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">
|
<div className="p-4 h-full flex flex-col w-full">
|
||||||
|
|
|
||||||
|
|
@ -312,18 +312,21 @@ export default function TopSearchBar({
|
||||||
// content directly.
|
// content directly.
|
||||||
className="px-4 sm:px-6 py-3 flex items-center gap-3 sm:gap-4 md:rounded-2xl"
|
className="px-4 sm:px-6 py-3 flex items-center gap-3 sm:gap-4 md:rounded-2xl"
|
||||||
style={{
|
style={{
|
||||||
background: 'var(--glass-surface-mid)',
|
// 2026-06-04 corner-border pass: same gradient-border
|
||||||
|
// technique as .glass-panel — the chip's fill clipped to
|
||||||
|
// padding-box, with border-box-clipped warm bottom-left +
|
||||||
|
// cool top-right radial highlights exposed through a 1px
|
||||||
|
// transparent border. The directional outer drop shadows
|
||||||
|
// from PR #115 are gone — corner catch-lights only now.
|
||||||
|
background:
|
||||||
|
'linear-gradient(var(--glass-surface-mid), var(--glass-surface-mid)) padding-box, ' +
|
||||||
|
'radial-gradient(at 0% 100%, var(--corner-light-warm) 0%, transparent 42%) border-box, ' +
|
||||||
|
'radial-gradient(at 100% 0%, var(--corner-light-cool) 0%, transparent 42%) border-box, ' +
|
||||||
|
'var(--chip-border-base) border-box',
|
||||||
|
border: '1px solid transparent',
|
||||||
backdropFilter: 'blur(12px) saturate(180%)',
|
backdropFilter: 'blur(12px) saturate(180%)',
|
||||||
WebkitBackdropFilter: 'blur(12px) saturate(180%)',
|
WebkitBackdropFilter: 'blur(12px) saturate(180%)',
|
||||||
// 2026-06-04 two-light-source pass: prepended edge-light
|
boxShadow: 'var(--rim-light-inner), var(--elevation-ambient)',
|
||||||
// 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
|
{/* Search affordance — read-only-ish input that opens the
|
||||||
|
|
|
||||||
|
|
@ -201,9 +201,10 @@ body {
|
||||||
|
|
||||||
/* Apply theme colors.
|
/* Apply theme colors.
|
||||||
The hearth gradient: two diagonal light sources that the floating
|
The hearth gradient: two diagonal light sources that the floating
|
||||||
chrome chips visually "respond" to via the --edge-light-warm /
|
chrome chips visually "respond" to via the --corner-light-warm /
|
||||||
--edge-light-cool design tokens (defined further down in :root /
|
--corner-light-cool design tokens (defined further down in :root /
|
||||||
[data-theme="dark"]).
|
[data-theme="dark"]; consumed as radial-gradient layers on each
|
||||||
|
chip's BORDER, not as outer drop shadows — see `.glass-panel`).
|
||||||
- Warm ember light source: bottom-left of the viewport.
|
- Warm ember light source: bottom-left of the viewport.
|
||||||
- Cool purpley-blue light source: top-right 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 base linear-gradient runs along the same 45deg diagonal between
|
||||||
|
|
@ -231,7 +232,7 @@ body {
|
||||||
),
|
),
|
||||||
/* Purpley-blue pool, top-right — secondary light source (replaces
|
/* Purpley-blue pool, top-right — secondary light source (replaces
|
||||||
the prior gold accent). Indigo→violet so the chip rims that
|
the prior gold accent). Indigo→violet so the chip rims that
|
||||||
respond to this source via --edge-light-cool read as cool. */
|
respond to this source via --corner-light-cool read as cool. */
|
||||||
radial-gradient(
|
radial-gradient(
|
||||||
ellipse 85% 65% at 100% -8%,
|
ellipse 85% 65% at 100% -8%,
|
||||||
rgba(99, 102, 241, 0.42) 0%,
|
rgba(99, 102, 241, 0.42) 0%,
|
||||||
|
|
@ -346,20 +347,32 @@ body {
|
||||||
--bg-secondary-rgb: 247, 243, 237;
|
--bg-secondary-rgb: 247, 243, 237;
|
||||||
--bg-tertiary-rgb: 240, 230, 214;
|
--bg-tertiary-rgb: 240, 230, 214;
|
||||||
|
|
||||||
/* Two-light-source edge glow tokens (2026-06-04 operator request:
|
/* Corner-border light tokens (2026-06-04 refinement of the prior
|
||||||
"let's have the corners or the edges of our sections respond as
|
two-light-source pass — operator feedback: "borders are
|
||||||
if those two are light sources").
|
reflecting the color, not necessarily the drop shadows behind
|
||||||
Each token is a complete box-shadow declaration with the offset
|
the cards. In fact, you could probably reduce those box shadows
|
||||||
pointing toward the matching light source — the colored shadow
|
quite a bit. At least they shouldn't span the entire edge of
|
||||||
bleeds outward from the chip's bottom-left edge (warm) and top-
|
the card. Just a subtle bit in the corner.").
|
||||||
right edge (cool), reading as light catching on the rim.
|
The prior `--edge-light-warm` / `--edge-light-cool` tokens were
|
||||||
Light theme alphas are softer; the dark theme override below
|
complete box-shadow declarations with offsets that spanned the
|
||||||
bumps them since the deeper substrate can absorb more saturation
|
entire bottom-left + top-right edges of every chip. They've
|
||||||
before the effect over-reads. Compose into chip shadow stacks
|
been retired. The replacement is a pair of plain RGBA colors
|
||||||
ahead of rim-light-inner + elevation tokens so the directional
|
consumed by radial-gradient layers in the chip's BACKGROUND
|
||||||
glow is the dominant edge cue. */
|
(border-box-clipped) — see `.glass-panel` below — so the
|
||||||
--edge-light-warm: -6px 6px 18px rgba(255, 110, 0, 0.16);
|
warm/cool light response now reads as a corner-concentrated
|
||||||
--edge-light-cool: 6px -6px 18px rgba(99, 102, 241, 0.12);
|
highlight ON the chip's 1px border, not as an outer drop
|
||||||
|
shadow extending into the body gradient.
|
||||||
|
The `--chip-border-base` is a faint diagonal white tint that
|
||||||
|
paints under the corner gradients so the rest of the rim isn't
|
||||||
|
completely invisible (gives the chip a sensible edge even far
|
||||||
|
from either light source). */
|
||||||
|
--corner-light-warm: rgba(255, 110, 0, 0.50);
|
||||||
|
--corner-light-cool: rgba(99, 102, 241, 0.38);
|
||||||
|
--chip-border-base: linear-gradient(
|
||||||
|
135deg,
|
||||||
|
rgba(255, 255, 255, 0.14) 0%,
|
||||||
|
rgba(255, 255, 255, 0.04) 100%
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Dark theme variables */
|
/* Dark theme variables */
|
||||||
|
|
@ -387,12 +400,18 @@ body {
|
||||||
--input-text: var(--input-text-dark);
|
--input-text: var(--input-text-dark);
|
||||||
--input-placeholder: var(--input-placeholder-dark);
|
--input-placeholder: var(--input-placeholder-dark);
|
||||||
|
|
||||||
/* Dark-theme edge glows — alphas bumped since the deeper substrate
|
/* Dark-theme corner-border colors — alphas bumped so the warm
|
||||||
can take more saturation before reading as garish, and so the
|
and cool catch lights read clearly against the deep substrate.
|
||||||
"lit by ember + lit by purple" effect carries on dark theme (the
|
See :root for the full rationale on the corner-vs-drop-shadow
|
||||||
default for first-time visitors). See :root for full rationale. */
|
refinement. The base white border tint drops in alpha here
|
||||||
--edge-light-warm: -8px 8px 26px rgba(255, 110, 30, 0.34);
|
because the deep canvas absorbs whites more readily. */
|
||||||
--edge-light-cool: 8px -8px 26px rgba(139, 92, 246, 0.28);
|
--corner-light-warm: rgba(255, 130, 30, 0.68);
|
||||||
|
--corner-light-cool: rgba(139, 92, 246, 0.58);
|
||||||
|
--chip-border-base: linear-gradient(
|
||||||
|
135deg,
|
||||||
|
rgba(255, 255, 255, 0.10) 0%,
|
||||||
|
rgba(255, 255, 255, 0.02) 100%
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Custom component styles - Fire-themed */
|
/* Custom component styles - Fire-themed */
|
||||||
|
|
@ -752,35 +771,55 @@ body {
|
||||||
the unprefixed form; Lightning CSS's autoprefixer adds the prefix
|
the unprefixed form; Lightning CSS's autoprefixer adds the prefix
|
||||||
per browserslist (ios_saf <18 still needs it). */
|
per browserslist (ios_saf <18 still needs it). */
|
||||||
/* Glass panels — the canonical floating-chrome surface. 2026-06-04
|
/* Glass panels — the canonical floating-chrome surface. 2026-06-04
|
||||||
two-light-source pass: `--edge-light-warm` (offset toward bottom-
|
corner-border pass (refines the prior two-light-source pass):
|
||||||
left) and `--edge-light-cool` (offset toward top-right) lead the
|
the warm + cool light response now paints on the chip's 1px
|
||||||
shadow stack so every glass surface picks up the directional rim
|
border using the multi-layer background + transparent-border
|
||||||
glows from the matching corners of the body gradient. Order
|
technique:
|
||||||
matters — directional glows must paint OUTSIDE the structural
|
1. linear-gradient(surface, surface) padding-box — the chip's
|
||||||
elevation shadow, so they sit at the top of the stack (CSS paints
|
translucent fill, clipped to the padding box so it doesn't
|
||||||
the LAST listed shadow lowest visually, but for box-shadow the
|
cover the 1px border ring.
|
||||||
list order doesn't matter for compositing — what matters is each
|
2. radial-gradient(at 0% 100%, warm) border-box — warm corner
|
||||||
shadow's geometry. They're listed warm→cool→rim→elevation as a
|
catch-light, anchored at the chip's bottom-left.
|
||||||
readability convention). */
|
3. radial-gradient(at 100% 0%, cool) border-box — cool corner
|
||||||
|
catch-light, anchored at the chip's top-right.
|
||||||
|
4. --chip-border-base border-box — faint diagonal white tint
|
||||||
|
under the corner gradients so the rest of the rim isn't
|
||||||
|
invisible (gives the chip a sensible edge far from either
|
||||||
|
light source).
|
||||||
|
The `border: 1px solid transparent` is what exposes those
|
||||||
|
border-box-clipped gradient layers as the visible rim.
|
||||||
|
Drop-shadow stack is now just rim-light-inner + elevation —
|
||||||
|
the directional warm/cool outer glows are gone per operator
|
||||||
|
feedback ("reduce those box shadows quite a bit"). */
|
||||||
.glass-panel {
|
.glass-panel {
|
||||||
background: var(--glass-surface-mid);
|
background:
|
||||||
|
linear-gradient(var(--glass-surface-mid), var(--glass-surface-mid))
|
||||||
|
padding-box,
|
||||||
|
radial-gradient(at 0% 100%, var(--corner-light-warm) 0%, transparent 42%)
|
||||||
|
border-box,
|
||||||
|
radial-gradient(at 100% 0%, var(--corner-light-cool) 0%, transparent 42%)
|
||||||
|
border-box,
|
||||||
|
var(--chip-border-base) border-box;
|
||||||
|
border: 1px solid transparent;
|
||||||
backdrop-filter: blur(12px) saturate(180%);
|
backdrop-filter: blur(12px) saturate(180%);
|
||||||
box-shadow:
|
box-shadow:
|
||||||
var(--edge-light-warm),
|
|
||||||
var(--edge-light-cool),
|
|
||||||
var(--rim-light-inner),
|
var(--rim-light-inner),
|
||||||
var(--rim-light-outer),
|
|
||||||
var(--elevation-ambient);
|
var(--elevation-ambient);
|
||||||
}
|
}
|
||||||
|
|
||||||
.glass-panel-strong {
|
.glass-panel-strong {
|
||||||
background: var(--glass-surface-high);
|
background:
|
||||||
|
linear-gradient(var(--glass-surface-high), var(--glass-surface-high))
|
||||||
|
padding-box,
|
||||||
|
radial-gradient(at 0% 100%, var(--corner-light-warm) 0%, transparent 42%)
|
||||||
|
border-box,
|
||||||
|
radial-gradient(at 100% 0%, var(--corner-light-cool) 0%, transparent 42%)
|
||||||
|
border-box,
|
||||||
|
var(--chip-border-base) border-box;
|
||||||
|
border: 1px solid transparent;
|
||||||
backdrop-filter: blur(20px) saturate(180%);
|
backdrop-filter: blur(20px) saturate(180%);
|
||||||
box-shadow:
|
box-shadow:
|
||||||
var(--edge-light-warm),
|
|
||||||
var(--edge-light-cool),
|
|
||||||
var(--rim-light-inner),
|
var(--rim-light-inner),
|
||||||
var(--rim-light-outer),
|
|
||||||
var(--elevation-pronounced);
|
var(--elevation-pronounced);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue