Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/components/GlassyRecordCard.css
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@
}

:root[data-theme="light"] .glassy-record-card {
--record-row-hover: #f7faff;
--record-row-open: #f8fbff;
--record-row-hover: rgba(247, 250, 255, 0.24);
--record-row-open: rgba(248, 251, 255, 0.3);
--record-title-hover: #4f6ad7;
--record-meta-bg: #f7faff;
--record-meta-bg: rgba(247, 250, 255, 0.34);
--record-meta-text: #4f5f82;
--record-time-text: #6b7280;
}
Expand Down
6 changes: 3 additions & 3 deletions src/components/GlassySection.css
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@
--glassy-section-title: #1f2937;
--glassy-section-rule: rgba(79, 106, 215, 0.28);
--glassy-section-rule-soft: rgba(79, 106, 215, 0.05);
--glassy-tile-hover: #f7faff;
--glassy-tile-shine: rgba(255, 255, 255, 0.68);
--glassy-tile-hover: rgba(247, 250, 255, 0.26);
--glassy-tile-shine: rgba(255, 255, 255, 0.36);
--glassy-metric-label: #5b6578;
--glassy-metric-value: #27324a;
--glassy-status-bg: #f7faff;
--glassy-status-bg: rgba(247, 250, 255, 0.3);
--glassy-status-border: rgba(79, 106, 215, 0.2);
--glassy-status-text: #4f5f82;
--glassy-progress-track: #edf3ff;
Expand Down
54 changes: 54 additions & 0 deletions src/components/Surface.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
.vortex-surface--glass {
position: relative;
isolation: isolate;
background: var(--surface-glass-background);
}

.vortex-surface--glass:hover {
background: var(--surface-glass-hover-background);
}

.vortex-surface--ripple {
overflow: hidden;
}

.vortex-surface--ripple::before {
content: "";
position: absolute;
inset: 0;
z-index: 0;
pointer-events: none;
background:
radial-gradient(
circle 13rem at var(--surface-ripple-x, 50%) var(--surface-ripple-y, 50%),
var(--surface-ripple-core),
var(--surface-ripple-soft) 34%,
transparent 72%
),
radial-gradient(
circle 4rem at var(--surface-ripple-x, 50%) var(--surface-ripple-y, 50%),
var(--surface-ripple-glint),
transparent 70%
);
opacity: 0;
transition: opacity 180ms ease;
}

.vortex-surface--ripple > * {
position: relative;
z-index: 1;
}

.vortex-surface--ripple:hover::before {
opacity: var(--surface-ripple-opacity);
}

.vortex-surface--transparent {
background: transparent;
}

@media (prefers-reduced-motion: reduce) {
.vortex-surface--ripple::before {
transition: none;
}
}
49 changes: 44 additions & 5 deletions src/components/Surface.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
import * as React from "react";
import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/lib/utils";
import "./Surface.css";

type PolymorphicRef<C extends React.ElementType> =
React.ComponentPropsWithRef<C>["ref"];

const surfaceVariants = cva(
"border bg-cover bg-no-repeat ring-1 ring-inset transition-colors duration-150",
"vortex-surface border bg-cover bg-no-repeat ring-1 ring-inset transition-colors duration-150",
{
variants: {
variant: {
panel:
"border-[color:var(--surface-glass-border)] bg-[color:var(--surface-glass-bg)] ring-[color:var(--surface-glass-ring)] hover:border-[color:var(--surface-glass-hover-border)] hover:bg-[color:var(--surface-glass-hover-bg)] supports-[backdrop-filter]:backdrop-blur-md supports-[backdrop-filter]:backdrop-saturate-150",
"vortex-surface--glass border-[color:var(--surface-glass-border)] ring-[color:var(--surface-glass-ring)] hover:border-[color:var(--surface-glass-hover-border)] supports-[backdrop-filter]:backdrop-blur-md supports-[backdrop-filter]:backdrop-saturate-150",
panelAlt:
"border-[color:var(--surface-glass-border)] bg-[color:var(--surface-glass-bg)] ring-[color:var(--surface-glass-ring)] hover:border-[color:var(--surface-glass-hover-border)] hover:bg-[color:var(--surface-glass-hover-bg)] supports-[backdrop-filter]:backdrop-blur-md supports-[backdrop-filter]:backdrop-saturate-150",
"vortex-surface--glass border-[color:var(--surface-glass-border)] ring-[color:var(--surface-glass-ring)] hover:border-[color:var(--surface-glass-hover-border)] supports-[backdrop-filter]:backdrop-blur-md supports-[backdrop-filter]:backdrop-saturate-150",
glass:
"border-[color:var(--surface-glass-border)] bg-[color:var(--surface-glass-bg)] ring-[color:var(--surface-glass-ring)] hover:border-[color:var(--surface-glass-hover-border)] hover:bg-[color:var(--surface-glass-hover-bg)] supports-[backdrop-filter]:backdrop-blur-md supports-[backdrop-filter]:backdrop-saturate-150",
transparent: "bg-transparent",
"vortex-surface--glass border-[color:var(--surface-glass-border)] ring-[color:var(--surface-glass-ring)] hover:border-[color:var(--surface-glass-hover-border)] supports-[backdrop-filter]:backdrop-blur-md supports-[backdrop-filter]:backdrop-saturate-150",
transparent: "vortex-surface--transparent",
},
radius: {
md: "rounded-lg",
Expand Down Expand Up @@ -73,6 +74,8 @@ const SurfaceImpl = React.forwardRef(function Surface(
{
as,
className,
onPointerLeave,
onPointerMove,
variant,
radius,
shadow,
Expand All @@ -82,13 +85,49 @@ const SurfaceImpl = React.forwardRef(function Surface(
ref: React.ForwardedRef<Element>,
) {
const Comp = as ?? "div";
const hasRipple = variant !== "transparent";

const handlePointerMove = React.useCallback(
(event: React.PointerEvent<Element>) => {
onPointerMove?.(event);
if (!hasRipple) return;

const target = event.currentTarget as HTMLElement;
const rect = target.getBoundingClientRect();
target.style.setProperty(
"--surface-ripple-x",
`${event.clientX - rect.left}px`,
);
target.style.setProperty(
"--surface-ripple-y",
`${event.clientY - rect.top}px`,
);
},
[hasRipple, onPointerMove],
);

const handlePointerLeave = React.useCallback(
(event: React.PointerEvent<Element>) => {
onPointerLeave?.(event);
if (!hasRipple) return;

const target = event.currentTarget as HTMLElement;
target.style.removeProperty("--surface-ripple-x");
target.style.removeProperty("--surface-ripple-y");
},
[hasRipple, onPointerLeave],
);

return (
<Comp
ref={ref}
className={cn(
surfaceVariants({ variant, radius, shadow, borderStyle }),
hasRipple && "vortex-surface--ripple",
className,
)}
onPointerLeave={handlePointerLeave}
onPointerMove={handlePointerMove}
{...props}
/>
);
Expand Down
74 changes: 57 additions & 17 deletions src/styles/base.css
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
--bg: #f2f5ff; /* app shell background */
--page: #eaf0ff; /* page container background */
--bg-accent: #e8efff; /* navbar */
--panel: rgba(249, 251, 255, 0.78); /* main containers */
--panel-alt: rgba(242, 247, 255, 0.66); /* tiles/inputs */
--panel: rgba(249, 251, 255, 0.32); /* main containers */
--panel-alt: rgba(242, 247, 255, 0.22); /* tiles/inputs */
--text: #111827;
--muted: #5d6475;
/* Primary is derived from sidebar hue but intentionally less saturated. */
Expand Down Expand Up @@ -36,13 +36,35 @@
--shadow-control: 0 10px 22px rgba(17, 24, 39, 0.08);
--glass-border: rgba(255, 255, 255, 0.42);
--glass-border-strong: rgba(255, 255, 255, 0.62);
--surface-glass-bg: rgba(249, 251, 255, 0.86);
--surface-glass-border: rgba(79, 106, 215, 0.24);
--surface-glass-ring: rgba(79, 106, 215, 0.16);
--surface-glass-hover-bg: rgba(249, 251, 255, 0.94);
--surface-glass-bg: rgba(249, 251, 255, 0.18);
--surface-glass-border: rgba(79, 106, 215, 0.34);
--surface-glass-ring: rgba(79, 106, 215, 0.2);
--surface-glass-highlight: rgba(255, 255, 255, 0.18);
--surface-glass-tint: rgba(111, 168, 255, 0.1);
--surface-glass-background:
linear-gradient(180deg, var(--surface-glass-highlight), transparent 58%),
linear-gradient(135deg, var(--surface-glass-tint), transparent 66%),
var(--surface-glass-bg);
--surface-glass-hover-bg: rgba(249, 251, 255, 0.28);
--surface-glass-hover-background:
linear-gradient(
180deg,
color-mix(in srgb, var(--surface-glass-highlight), white 14%),
transparent 58%
),
linear-gradient(
135deg,
color-mix(in srgb, var(--surface-glass-tint), var(--primary) 16%),
transparent 66%
),
var(--surface-glass-hover-bg);
--surface-glass-hover-border: rgba(79, 106, 215, 0.36);
--control-glass-bg: rgba(249, 251, 255, 0.76);
--control-glass-hover-bg: rgba(249, 251, 255, 0.9);
--surface-ripple-core: rgba(111, 168, 255, 0.24);
--surface-ripple-soft: rgba(91, 194, 181, 0.12);
--surface-ripple-glint: rgba(255, 255, 255, 0.24);
--surface-ripple-opacity: 0.9;
--control-glass-bg: rgba(249, 251, 255, 0.26);
--control-glass-hover-bg: rgba(249, 251, 255, 0.36);
--tint-primary: rgba(111, 168, 255, 0.06);
--tint-primary-strong: rgba(111, 168, 255, 0.1);

Expand Down Expand Up @@ -89,21 +111,27 @@
--bg: #ffffff;
--page: #ffffff;
--bg-accent: #ffffff;
--panel: rgba(255, 255, 255, 0.82);
--panel-alt: rgba(255, 255, 255, 0.68);
--panel: rgba(248, 250, 255, 0.28);
--panel-alt: rgba(241, 246, 255, 0.2);
--text: #111827;
--muted: #6b7280;
--border: rgba(17, 24, 39, 0.14);
--veil: rgba(17, 24, 39, 0.45);
--glass-border: rgba(255, 255, 255, 0.55);
--glass-border-strong: rgba(255, 255, 255, 0.72);
--surface-glass-bg: rgba(255, 255, 255, 0.88);
--surface-glass-border: rgba(79, 106, 215, 0.22);
--surface-glass-ring: rgba(79, 106, 215, 0.16);
--surface-glass-hover-bg: rgba(255, 255, 255, 0.96);
--surface-glass-hover-border: rgba(79, 106, 215, 0.34);
--control-glass-bg: rgba(255, 255, 255, 0.78);
--control-glass-hover-bg: rgba(255, 255, 255, 0.92);
--surface-glass-bg: rgba(248, 250, 255, 0.16);
--surface-glass-border: rgba(79, 106, 215, 0.34);
--surface-glass-ring: rgba(79, 106, 215, 0.22);
--surface-glass-highlight: rgba(255, 255, 255, 0.22);
--surface-glass-tint: rgba(111, 168, 255, 0.08);
--surface-glass-hover-bg: rgba(248, 250, 255, 0.28);
--surface-glass-hover-border: rgba(79, 106, 215, 0.46);
--surface-ripple-core: rgba(111, 168, 255, 0.22);
--surface-ripple-soft: rgba(91, 194, 181, 0.1);
--surface-ripple-glint: rgba(255, 255, 255, 0.26);
--surface-ripple-opacity: 0.9;
--control-glass-bg: rgba(248, 250, 255, 0.22);
--control-glass-hover-bg: rgba(248, 250, 255, 0.34);
--shadow-card: 0 18px 44px rgba(17, 24, 39, 0.09);
--shadow-popover: 0 22px 60px rgba(17, 24, 39, 0.16);
--shadow-tile: 0 14px 34px rgba(17, 24, 39, 0.09);
Expand Down Expand Up @@ -135,8 +163,14 @@
--surface-glass-bg: rgba(6, 9, 14, 0.72);
--surface-glass-border: rgba(255, 255, 255, 0.12);
--surface-glass-ring: rgba(111, 168, 255, 0.24);
--surface-glass-highlight: rgba(255, 255, 255, 0.08);
--surface-glass-tint: rgba(111, 168, 255, 0.06);
--surface-glass-hover-bg: rgba(12, 18, 28, 0.82);
--surface-glass-hover-border: rgba(111, 168, 255, 0.32);
--surface-ripple-core: rgba(111, 168, 255, 0.18);
--surface-ripple-soft: rgba(91, 194, 181, 0.08);
--surface-ripple-glint: rgba(255, 255, 255, 0.08);
--surface-ripple-opacity: 0.75;
--control-glass-bg: rgba(10, 14, 22, 0.72);
--control-glass-hover-bg: rgba(15, 22, 34, 0.82);
--shadow-card: 0 18px 44px rgba(0, 0, 0, 0.72);
Expand Down Expand Up @@ -195,8 +229,14 @@
--surface-glass-bg: rgba(29, 8, 2, 0.74);
--surface-glass-border: rgba(255, 187, 104, 0.16);
--surface-glass-ring: rgba(255, 138, 31, 0.28);
--surface-glass-highlight: rgba(255, 209, 102, 0.09);
--surface-glass-tint: rgba(255, 104, 0, 0.08);
--surface-glass-hover-bg: rgba(49, 15, 4, 0.84);
--surface-glass-hover-border: rgba(255, 138, 31, 0.42);
--surface-ripple-core: rgba(255, 138, 31, 0.2);
--surface-ripple-soft: rgba(255, 61, 0, 0.1);
--surface-ripple-glint: rgba(255, 209, 102, 0.12);
--surface-ripple-opacity: 0.8;
--control-glass-bg: rgba(38, 11, 3, 0.74);
--control-glass-hover-bg: rgba(59, 18, 5, 0.86);
--shadow-card: 0 18px 44px rgba(0, 0, 0, 0.78);
Expand Down
Loading