Improve activity banner light theme styling
All checks were successful
Automated Container Build / build-and-push (push) Successful in 1m17s

This commit is contained in:
Elijah 2026-07-29 14:14:41 -07:00
parent 32bce673ac
commit 3cf20514f4

View file

@ -18,11 +18,11 @@ interface ActivitySummary {
} }
const levelClasses = [ const levelClasses = [
"bg-white/10", "bg-text-heading/8 dark:bg-white/10",
"bg-primary/45", "bg-primary/30 dark:bg-primary/45",
"bg-primary", "bg-primary/70 dark:bg-primary",
"bg-accent", "bg-accent/75 dark:bg-accent",
"bg-[#fbbf24]", "bg-[#e9a91b] dark:bg-[#fbbf24]",
] as const; ] as const;
export function ActivityBanner({ onNewClass }: { onNewClass: () => void }) { export function ActivityBanner({ onNewClass }: { onNewClass: () => void }) {
@ -40,25 +40,26 @@ export function ActivityBanner({ onNewClass }: { onNewClass: () => void }) {
}, []); }, []);
return ( return (
<section className="relative mb-10 overflow-hidden rounded-[2rem] bg-[#172033] px-5 py-7 text-white shadow-[var(--shadow-card)] sm:px-8 sm:py-9 dark:bg-[#111827]"> <section className="relative mb-10 overflow-hidden rounded-[2rem] border border-border-light bg-bg-surface px-5 py-7 text-text-heading shadow-[var(--shadow-card)] sm:px-8 sm:py-9 dark:border-white/5 dark:bg-[#111827] dark:text-white">
<div className="absolute -right-16 -top-24 h-64 w-64 rounded-full bg-primary/70 blur-3xl" /> <div className="absolute inset-x-0 top-0 h-1 bg-gradient-to-r from-primary via-primary-light to-accent dark:hidden" />
<div className="absolute -bottom-28 right-1/3 h-52 w-52 rounded-full bg-accent/35 blur-3xl" /> <div className="absolute -right-16 -top-24 h-64 w-64 rounded-full bg-primary/12 blur-3xl dark:bg-primary/70" />
<div className="absolute -bottom-28 right-1/3 h-52 w-52 rounded-full bg-accent/10 blur-3xl dark:bg-accent/35" />
<div className="relative mb-6 flex items-center justify-between gap-4"> <div className="relative mb-6 flex items-center justify-between gap-4">
<div> <div>
<p className="text-xs font-bold uppercase tracking-[0.22em] text-white/55">Personal library</p> <p className="text-xs font-bold uppercase tracking-[0.22em] text-primary dark:text-white/55">Personal library</p>
<h1 className="editorial-title mt-1 text-3xl text-white sm:text-4xl">Study activity</h1> <h1 className="editorial-title mt-1 text-3xl text-text-heading sm:text-4xl dark:text-white">Study activity</h1>
</div> </div>
<button onClick={onNewClass} className="inline-flex min-h-11 shrink-0 items-center justify-center gap-2 rounded-xl bg-white px-4 text-sm font-bold text-[#172033] shadow-lg transition-transform hover:-translate-y-0.5 sm:min-h-12 sm:px-5"> <button onClick={onNewClass} className="inline-flex min-h-11 shrink-0 items-center justify-center gap-2 rounded-xl bg-primary px-4 text-sm font-bold text-white shadow-md transition-[background-color,transform,box-shadow] hover:-translate-y-0.5 hover:bg-primary-hover hover:shadow-lg sm:min-h-12 sm:px-5 dark:bg-white dark:text-[#172033] dark:hover:bg-white/90">
<span className="text-xl leading-none">+</span> New class <span className="text-xl leading-none">+</span> New class
</button> </button>
</div> </div>
{error && ( {error && (
<div className="relative rounded-xl border border-white/15 bg-white/8 px-4 py-5 text-sm text-white/70" role="alert"> <div className="relative rounded-xl border border-error/20 bg-error-bg px-4 py-5 text-sm text-error dark:border-white/15 dark:bg-white/8 dark:text-white/70" role="alert">
Study activity could not be loaded. Your library is still available below. Study activity could not be loaded. Your library is still available below.
</div> </div>
)} )}
{!summary && !error && <div className="relative h-52 animate-subtle-pulse rounded-2xl bg-white/8" />} {!summary && !error && <div className="relative h-52 animate-subtle-pulse rounded-2xl bg-bg-surface-alt/70 dark:bg-white/8" />}
{summary && ( {summary && (
<div className="relative grid gap-6 xl:grid-cols-[minmax(0,1fr)_10rem] xl:items-center"> <div className="relative grid gap-6 xl:grid-cols-[minmax(0,1fr)_10rem] xl:items-center">
<div className="min-w-0"> <div className="min-w-0">
@ -87,14 +88,14 @@ function ActivityHeatmap({ days, today }: { days: DailyActivity[]; today: string
return ( return (
<div> <div>
<div className="relative mb-2 h-12"> <div className="relative mb-2 h-12">
<p className="absolute bottom-0 left-0 text-xs font-semibold text-white/55">Last 53 weeks · Arizona time</p> <p className="absolute bottom-0 left-0 text-xs font-semibold text-text-secondary dark:text-white/55">Last 53 weeks · Arizona time</p>
<div className="absolute right-0 top-0"> <div className="absolute right-0 top-0">
{activeDay && <DayTooltip day={activeDay} />} {activeDay && <DayTooltip day={activeDay} />}
</div> </div>
</div> </div>
<div ref={scrollRef} className="overflow-x-auto pb-2 [scrollbar-color:rgba(255,255,255,.25)_transparent]"> <div ref={scrollRef} className="overflow-x-auto pb-2 [scrollbar-color:var(--color-border)_transparent] dark:[scrollbar-color:rgba(255,255,255,.25)_transparent]">
<div className="grid w-max grid-cols-[2rem_auto] gap-2"> <div className="grid w-max grid-cols-[2rem_auto] gap-2">
<div className="pt-6 text-[10px] font-semibold leading-[15px] text-white/45" aria-hidden> <div className="pt-6 text-[10px] font-semibold leading-[15px] text-text-muted dark:text-white/45" aria-hidden>
<div className="h-[15px]" /> <div className="h-[15px]" />
<div>Mon</div> <div>Mon</div>
<div className="h-[15px]" /> <div className="h-[15px]" />
@ -103,7 +104,7 @@ function ActivityHeatmap({ days, today }: { days: DailyActivity[]; today: string
<div>Fri</div> <div>Fri</div>
</div> </div>
<div> <div>
<div className="mb-2 flex h-4 gap-[3px] text-[10px] font-semibold text-white/45" aria-hidden> <div className="mb-2 flex h-4 gap-[3px] text-[10px] font-semibold text-text-muted dark:text-white/45" aria-hidden>
{weeks.map((week, index) => ( {weeks.map((week, index) => (
<div key={week[0]?.date ?? index} className="w-3"> <div key={week[0]?.date ?? index} className="w-3">
{getMonthLabel(week, weeks[index - 1])} {getMonthLabel(week, weeks[index - 1])}
@ -125,7 +126,7 @@ function ActivityHeatmap({ days, today }: { days: DailyActivity[]; today: string
onFocus={() => setActiveDay(day)} onFocus={() => setActiveDay(day)}
onBlur={() => setActiveDay(null)} onBlur={() => setActiveDay(null)}
onClick={() => setActiveDay((current) => current?.date === day.date ? null : day)} onClick={() => setActiveDay((current) => current?.date === day.date ? null : day)}
className={`h-3 w-3 rounded-[3px] border border-white/8 ${levelClasses[day.level]} focus-visible:z-10 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white`} className={`h-3 w-3 rounded-[3px] border border-text-heading/6 ${levelClasses[day.level]} focus-visible:z-10 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary dark:border-white/8 dark:focus-visible:outline-white`}
/> />
))} ))}
</div> </div>
@ -134,9 +135,9 @@ function ActivityHeatmap({ days, today }: { days: DailyActivity[]; today: string
</div> </div>
</div> </div>
</div> </div>
<div className="mt-2 flex items-center justify-end gap-1.5 text-[10px] font-semibold text-white/45" aria-label="Activity intensity from less to more"> <div className="mt-2 flex items-center justify-end gap-1.5 text-[10px] font-semibold text-text-muted dark:text-white/45" aria-label="Activity intensity from less to more">
<span>Less</span> <span>Less</span>
{levelClasses.map((className, index) => <span key={index} className={`h-3 w-3 rounded-[3px] border border-white/8 ${className}`} />)} {levelClasses.map((className, index) => <span key={index} className={`h-3 w-3 rounded-[3px] border border-text-heading/6 dark:border-white/8 ${className}`} />)}
<span>More</span> <span>More</span>
</div> </div>
</div> </div>
@ -151,25 +152,25 @@ function DayTooltip({ day }: { day: DailyActivity }) {
year: "numeric", year: "numeric",
}); });
return ( return (
<div role="tooltip" className="rounded-lg border border-white/15 bg-[#0d1422] px-3 py-2 text-right text-xs shadow-xl"> <div role="tooltip" className="rounded-lg border border-border bg-bg-surface px-3 py-2 text-right text-xs shadow-xl dark:border-white/15 dark:bg-[#0d1422]">
<div className="font-bold text-white">{formatted} · {day.total} total</div> <div className="font-bold text-text-heading dark:text-white">{formatted} · {day.total} total</div>
<div className="mt-0.5 text-white/60">{day.flashcards} flashcards · {day.questions} questions · {day.arcade} arcade groups</div> <div className="mt-0.5 text-text-secondary dark:text-white/60">{day.flashcards} flashcards · {day.questions} questions · {day.arcade} arcade groups</div>
</div> </div>
); );
} }
function StreakDisplay({ streak }: { streak: number }) { function StreakDisplay({ streak }: { streak: number }) {
const size = 24 + Math.min(streak, 30) * 0.6; const size = 24 + Math.min(streak, 30) * 0.6;
const color = streak === 0 ? "text-white/30" : streak < 7 ? "text-accent" : streak < 30 ? "text-[#ff7a36]" : "text-[#fbbf24]"; const color = streak === 0 ? "text-text-muted dark:text-white/30" : streak < 7 ? "text-accent" : streak < 30 ? "text-[#e6602f] dark:text-[#ff7a36]" : "text-[#d4930d] dark:text-[#fbbf24]";
return ( return (
<div className="flex items-center justify-center gap-4 rounded-2xl border border-white/12 bg-white/7 px-5 py-4 xl:flex-col xl:gap-2 xl:text-center"> <div className="flex items-center justify-center gap-4 rounded-2xl border border-primary/15 bg-bg-callout/70 px-5 py-4 shadow-sm xl:flex-col xl:gap-2 xl:text-center dark:border-white/12 dark:bg-white/7 dark:shadow-none">
<svg viewBox="0 0 24 24" aria-hidden className={`shrink-0 fill-current ${color}`} style={{ width: size, height: size }}> <svg viewBox="0 0 24 24" aria-hidden className={`shrink-0 fill-current ${color}`} style={{ width: size, height: size }}>
<path d="M13.5 2.1c.4 3.1-1.4 4.5-2.6 6.1-1 1.3-1.5 2.4-.8 4.1.5-1.4 1.5-2.3 2.5-3.2 1.8 1.6 3.4 3.6 3.4 6.3 0 2.5-1.7 4.6-4 4.6s-4-2-4-4.6c0-1.2.4-2.3 1-3.3-2.4 1.3-4 3.7-4 6.3 0 3.1 2.8 5.6 7 5.6s7-2.7 7-6.7c0-5.6-3.4-10.3-5.5-15.2Z" /> <path d="M13.5 2.1c.4 3.1-1.4 4.5-2.6 6.1-1 1.3-1.5 2.4-.8 4.1.5-1.4 1.5-2.3 2.5-3.2 1.8 1.6 3.4 3.6 3.4 6.3 0 2.5-1.7 4.6-4 4.6s-4-2-4-4.6c0-1.2.4-2.3 1-3.3-2.4 1.3-4 3.7-4 6.3 0 3.1 2.8 5.6 7 5.6s7-2.7 7-6.7c0-5.6-3.4-10.3-5.5-15.2Z" />
</svg> </svg>
<div> <div>
<div className="text-3xl font-extrabold">{streak}</div> <div className="text-3xl font-extrabold">{streak}</div>
<div className="text-xs font-semibold text-white/55">day streak</div> <div className="text-xs font-semibold text-text-secondary dark:text-white/55">day streak</div>
<div className="mt-1 text-[10px] text-white/40">20 activities per day</div> <div className="mt-1 text-[10px] text-text-muted dark:text-white/40">20 activities per day</div>
</div> </div>
</div> </div>
); );