feat: add warm sand theme colors and light / dark mode toggle (#302)

This commit was merged in pull request #302.
This commit is contained in:
Arjun Patel
2026-06-21 10:56:59 -07:00
committed by GitHub
parent 3d80ac2993
commit d14cec5885
43 changed files with 540 additions and 347 deletions
@@ -97,18 +97,18 @@ export function StreamMembersOverlay({
return createPortal(
<div className="fixed inset-0 z-[100]">
<div
className="absolute inset-0 bg-black/60 backdrop-blur-sm"
className="bg-scrim/60 absolute inset-0 backdrop-blur-sm"
onClick={onClose}
/>
<div className="absolute left-1/2 top-1/2 flex max-h-[80vh] w-full max-w-sm -translate-x-1/2 -translate-y-1/2 flex-col overflow-hidden rounded-2xl border border-white/10 bg-white/5 p-6 shadow-2xl backdrop-blur-xl">
<div className="bg-popover/95 text-popover-foreground border-border absolute left-1/2 top-1/2 flex max-h-[80vh] w-full max-w-sm -translate-x-1/2 -translate-y-1/2 flex-col overflow-hidden rounded-2xl border p-6 shadow-2xl backdrop-blur-xl">
{/* Header */}
<div className="mb-4 flex items-center justify-between">
<h2 className="text-sm font-semibold text-white/70">Members</h2>
<h2 className="text-sm font-semibold">Members</h2>
<KeyHint
keys="Esc"
onClick={onClose}
title="Close (or press Esc)"
className="text-xs text-white/30"
className="text-muted-foreground text-xs"
>
to close
</KeyHint>
@@ -116,11 +116,11 @@ export function StreamMembersOverlay({
{/* Visibility */}
<section className="mb-4">
<h3 className="mb-2 text-[10px] font-medium uppercase tracking-widest text-white/30">
<h3 className="text-muted-foreground mb-2 text-[10px] font-medium uppercase tracking-widest">
Visibility
</h3>
{isCreator ? (
<div className="grid grid-cols-2 gap-1 rounded-lg bg-white/5 p-1">
<div className="bg-muted grid grid-cols-2 gap-1 rounded-lg p-1">
<VisibilityPill
active={visibility.mode === 'network'}
icon={<Globe className="size-3.5" />}
@@ -135,15 +135,15 @@ export function StreamMembersOverlay({
/>
</div>
) : (
<div className="flex items-center gap-2 text-sm text-white/70">
<div className="text-foreground flex items-center gap-2 text-sm">
{visibility.mode === 'network' ? (
<>
<Globe className="size-3.5 text-white/40" />
<Globe className="text-muted-foreground size-3.5" />
<span>Everyone in {network?.name ?? 'network'}</span>
</>
) : (
<>
<Lock className="size-3.5 text-white/40" />
<Lock className="text-muted-foreground size-3.5" />
<span>{memberIds.length} specific people</span>
</>
)}
@@ -153,9 +153,11 @@ export function StreamMembersOverlay({
{/* Member list */}
<section className="flex min-h-0 flex-1 flex-col">
<h3 className="mb-2 text-[10px] font-medium uppercase tracking-widest text-white/30">
<h3 className="text-muted-foreground mb-2 text-[10px] font-medium uppercase tracking-widest">
{visibility.mode === 'network' ? 'Has access' : 'People'}{' '}
<span className="ml-1 text-white/20">{memberIds.length}</span>
<span className="text-muted-foreground ml-1">
{memberIds.length}
</span>
</h3>
<ScrollArea className="min-h-0 flex-1">
<ul className="flex flex-col gap-0.5 pr-2">
@@ -167,7 +169,7 @@ export function StreamMembersOverlay({
return (
<li
key={id}
className="group flex items-center gap-2.5 rounded px-2 py-1.5 text-sm text-white/70"
className="text-foreground group flex items-center gap-2.5 rounded px-2 py-1.5 text-sm"
>
<HumanAvatar
size="sm"
@@ -178,13 +180,13 @@ export function StreamMembersOverlay({
<span
className={cn(
'flex-1 truncate',
!display.exists && 'italic text-white/40',
!display.exists && 'text-muted-foreground italic',
)}
>
{display.displayName}
</span>
{isCreatorRow && (
<span className="text-[10px] uppercase tracking-wider text-white/30">
<span className="text-muted-foreground text-[10px] uppercase tracking-wider">
Creator
</span>
)}
@@ -192,7 +194,7 @@ export function StreamMembersOverlay({
<button
type="button"
onClick={() => removeMember(id)}
className="rounded p-1 text-white/30 opacity-0 transition-opacity hover:bg-white/10 hover:text-white/70 group-hover:opacity-100"
className="text-muted-foreground hover:bg-accent hover:text-foreground rounded p-1 opacity-0 transition-opacity group-hover:opacity-100"
aria-label={`Remove ${display.displayName}`}
>
<X className="size-3.5" />
@@ -209,8 +211,8 @@ export function StreamMembersOverlay({
{isCreator &&
visibility.mode === 'custom' &&
availableToAdd.length > 0 && (
<section className="mt-4 border-t border-white/5 pt-4">
<h3 className="mb-2 flex items-center gap-1.5 text-[10px] font-medium uppercase tracking-widest text-white/30">
<section className="border-border mt-4 border-t pt-4">
<h3 className="text-muted-foreground mb-2 flex items-center gap-1.5 text-[10px] font-medium uppercase tracking-widest">
<UserPlus className="size-3" />
Add people
</h3>
@@ -222,7 +224,7 @@ export function StreamMembersOverlay({
type="button"
onClick={() => addMember(human.id)}
className={cn(
'flex w-full items-center gap-2.5 rounded px-2 py-1.5 text-left text-sm text-white/70 transition-colors hover:bg-white/5',
'text-foreground hover:bg-accent flex w-full items-center gap-2.5 rounded px-2 py-1.5 text-left text-sm transition-colors',
)}
>
<HumanAvatar
@@ -234,7 +236,7 @@ export function StreamMembersOverlay({
<span className="flex-1 truncate">
{human.email_prefix}
</span>
<UserPlus className="size-3.5 text-white/30" />
<UserPlus className="text-muted-foreground size-3.5" />
</button>
</li>
))}
@@ -246,7 +248,7 @@ export function StreamMembersOverlay({
{isCreator &&
visibility.mode === 'custom' &&
availableToAdd.length === 0 && (
<p className="mt-4 text-center text-xs text-white/30">
<p className="text-muted-foreground mt-4 text-center text-xs">
<Users className="mr-1 inline size-3" />
Everyone in the network is already a member
</p>
@@ -275,8 +277,8 @@ function VisibilityPill({
className={cn(
'flex items-center justify-center gap-1.5 rounded-md px-2 py-1.5 text-xs transition-colors',
active
? 'bg-white/10 text-white/90'
: 'text-white/50 hover:text-white/80',
? 'bg-background text-foreground shadow-sm'
: 'text-muted-foreground hover:text-foreground',
)}
>
{icon}