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:
parent
f98795436d
commit
9e4ecd3ee0
3 changed files with 23 additions and 20 deletions
|
|
@ -35,12 +35,6 @@
|
|||
--color-aurora-lilac: #c3b6f0;
|
||||
--color-aurora-peach: #f6cdb4;
|
||||
|
||||
--color-night-50: #f6f9fc;
|
||||
--color-night-700: #1d2733;
|
||||
--color-night-800: #151d27;
|
||||
--color-night-900: #101720;
|
||||
--color-night-950: #0a1017;
|
||||
|
||||
--font-sans: -apple-system, BlinkMacSystemFont, ui-sans-serif, system-ui,
|
||||
"Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif,
|
||||
"Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji";
|
||||
|
|
@ -302,11 +296,20 @@ body {
|
|||
/* Tailwind emits both the prefixed and standard properties; hand-written
|
||||
backdrop-filter gets minified down to -webkit- only, which paints nothing. */
|
||||
@apply backdrop-blur-xl backdrop-saturate-150;
|
||||
background: color-mix(in oklab, white 68%, transparent);
|
||||
background: color-mix(in oklab, var(--surface) 70%, transparent);
|
||||
border-bottom: 1px solid var(--hairline);
|
||||
}
|
||||
.dark .glass {
|
||||
background: color-mix(in oklab, #101720 70%, transparent);
|
||||
|
||||
/* Study-feed chrome (progress header + bottom pager): the same neutral
|
||||
surface as the cards, with a neutral border and shadow. */
|
||||
.study-chrome {
|
||||
@apply backdrop-blur-xl backdrop-saturate-150;
|
||||
background: color-mix(in oklab, var(--surface) 88%, transparent);
|
||||
border: 1px solid var(--hairline);
|
||||
box-shadow: var(--shadow-card);
|
||||
}
|
||||
.dark .study-chrome {
|
||||
border-color: var(--hairline-soft);
|
||||
}
|
||||
|
||||
.card {
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -719,7 +719,7 @@ export function UploadScreen() {
|
|||
</div>
|
||||
</section>
|
||||
|
||||
<div className="sticky bottom-[calc(env(safe-area-inset-bottom,0px)+4.6rem)] z-20 -mx-4 border-t border-[var(--hairline)] bg-white/65 px-4 py-3 backdrop-blur-2xl dark:bg-night-950/70 sm:bottom-0 sm:mx-0 sm:rounded-[1.35rem] sm:border sm:px-5">
|
||||
<div className="sticky bottom-[calc(env(safe-area-inset-bottom,0px)+4.6rem)] z-20 -mx-4 border-t border-[var(--hairline)] bg-white/65 px-4 py-3 backdrop-blur-2xl dark:bg-[color-mix(in_oklab,var(--surface)_70%,transparent)] sm:bottom-0 sm:mx-0 sm:rounded-[1.35rem] sm:border sm:px-5">
|
||||
<div className="flex flex-wrap items-center justify-between gap-3">
|
||||
<p className="text-[12.5px] text-[var(--text-subtle)]">
|
||||
{documentsBusy
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue