Deck chrome: neutral surfaces, borders and text (no navy leftovers)

- The study feed's progress header and bottom pager no longer use the old
  navy glass: new .study-chrome class uses the neutral surface token
  (same gray as the cards, #2f2f2f in dark), the neutral border
  (8% white in dark, #e5e5e5 in light) and a neutral shadow.
- Close tile, streak pill and XP pill now use --surface-sunken /
  --text-muted, matching the app's other buttons and chips; the close
  glyph is the shared XIcon.
- Bottom pager: counter in --text, arrows in --text-muted.
- .glass (mobile header) no longer has the hardcoded #101720 navy; it is
  now color-mix of the surface token. Removed the unused --color-night-*
  tokens and the last night- usage (create screen sticky bar).
- Hidden the 'Swipe up' hint on desktop, where it collided with the
  bottom pager.

New deck-chrome suite: 15/15 (computed surfaces/borders/text in both
themes, no navy); pwa 16/16, final-ux 12/12, security 8/8, contrast 20/20.
This commit is contained in:
Martin Dvořák 2026-10-07 09:06:18 +00:00
commit 9e4ecd3ee0
3 changed files with 23 additions and 20 deletions

View file

@ -9,7 +9,7 @@ import { celebrate } from "@/lib/confetti";
import type { Activity, Deck } from "@/lib/schemas";
import { recordAttempt } from "@/lib/storage";
import { cn } from "@/lib/utils";
import { BoltIcon, FlameIcon } from "@/components/icons";
import { BoltIcon, FlameIcon, XIcon } from "@/components/icons";
import { Button, ProgressBar } from "@/components/ui";
import { ResultsScreen } from "./ResultsScreen";
@ -147,14 +147,14 @@ export function StudyFeed({ deck }: { deck: Deck }) {
<div className="frost-bg fixed inset-0 flex flex-col">
{/* Chrome ---------------------------------------------------- */}
<header className="pt-safe absolute inset-x-0 top-0 z-30 px-3">
<div className="glass mx-auto max-w-xl space-y-1.5 rounded-2xl px-3 py-2">
<div className="study-chrome mx-auto max-w-xl space-y-1.5 rounded-2xl px-3 py-2">
<div className="flex items-center gap-3">
<Link
href="/"
aria-label="Back to your library"
className="grid size-9 shrink-0 place-items-center rounded-xl bg-white/80 text-sm font-bold text-frost-800 transition hover:bg-white dark:bg-white/10 dark:text-frost-100"
className="grid size-9 shrink-0 place-items-center rounded-xl bg-[var(--surface-sunken)] text-[var(--text)] transition hover:bg-[var(--hover)]"
>
✕
<XIcon className="size-4" />
</Link>
<div className="min-w-0 flex-1">
<ProgressBar
@ -169,7 +169,7 @@ export function StudyFeed({ deck }: { deck: Deck }) {
"inline-flex items-center gap-1 rounded-xl px-2 py-1 text-xs font-extrabold transition",
streak >= 3
? "tint-peach"
: "glass-chip text-frost-600 dark:text-frost-200",
: "bg-[var(--surface-sunken)] text-[var(--text-muted)]",
)}
title={`Answer streak: ${streak}`}
aria-label={`Answer streak: ${streak}`}
@ -178,7 +178,7 @@ export function StudyFeed({ deck }: { deck: Deck }) {
{streak}
</span>
<span
className="inline-flex items-center gap-1 rounded-xl bg-frost-500/15 px-2 py-1 text-xs font-extrabold text-frost-800 dark:text-frost-100"
className="inline-flex items-center gap-1 rounded-xl bg-[var(--surface-sunken)] px-2 py-1 text-xs font-extrabold text-[var(--text-muted)]"
title={`XP earned: ${xp}`}
aria-label={`XP earned: ${xp}`}
>
@ -187,7 +187,7 @@ export function StudyFeed({ deck }: { deck: Deck }) {
</span>
</div>
</div>
<div className="flex items-center justify-between gap-2 text-[11px] font-semibold text-frost-600 dark:text-frost-300">
<div className="flex items-center justify-between gap-2 text-[11px] font-semibold text-[var(--text-muted)]">
<span className="min-w-0 truncate">{deck.title}</span>
<span className="shrink-0">
{retryMode ? "Retry · " : ""}
@ -250,7 +250,7 @@ export function StudyFeed({ deck }: { deck: Deck }) {
initial={{ opacity: 0, y: 12 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0 }}
className="pointer-events-none absolute inset-x-0 bottom-6 z-20 flex justify-center"
className="pointer-events-none absolute inset-x-0 bottom-6 z-20 flex justify-center sm:hidden"
>
<span className="rounded-full bg-frost-950/70 px-4 py-2 text-xs font-semibold text-white backdrop-blur">
Swipe up for the next activity ↑
@ -261,11 +261,11 @@ export function StudyFeed({ deck }: { deck: Deck }) {
{/* Desktop next/prev buttons --------------------------------- */}
<div className="pointer-events-none absolute inset-x-0 bottom-0 z-20 hidden justify-center pb-4 sm:flex">
<div className="glass pointer-events-auto flex items-center gap-2 rounded-2xl px-2 py-1.5">
<div className="study-chrome pointer-events-auto flex items-center gap-2 rounded-2xl px-2 py-1.5">
<Button variant="ghost" size="sm" onClick={() => goTo(index - 1)} disabled={index === 0} aria-label="Previous activity">
↑
</Button>
<span className="px-2 text-xs font-semibold text-frost-600 dark:text-frost-300">
<span className="px-2 text-xs font-semibold text-[var(--text)]">
{index + 1} / {slideCount}
</span>
<Button variant="ghost" size="sm" onClick={() => goTo(index + 1)} disabled={index >= slideCount - 1} aria-label="Next activity">