One-pill study chrome, toggling chat pickers, readable homework steps
UI batch from feedback: - The study/review/exam/homework chrome is now a single 58px pill: round close button, title + position over the progress bar, chips (or the exam timer) at the far end — everything on the centre line, so nothing crowds the rounded corners any more. Homework guide gets the same recipe. - The immersive feeds carry z-[45] so they paint over the app chrome (on /exam the header used to cover the top of the chrome), and the page chrome behind an open overlay (.app-header, .segmented, .tabbar) is hidden while the transparent overlay is up, so it can no longer ghost through the glass. The guide's disclaimer moved inside the overlay with it. - Chat: the context and model chips toggle their own popover (pressed state, aria-expanded), opening one closes the other, a press outside closes it — no more being forced to pick something to get out. - Homework: the model's plain-text step explanations/hints/verdicts keep their line breaks (whitespace-pre-wrap) — a step used to collapse into one run-on paragraph with the whole solution inside it; the guide prompt now says the explanation is coaching, 2-4 sentences. - The four glacier blobs are at 25% of their old opacity (0.045 light, 0.1 dark). Tests: phase-2 chrome geometry + exam layering checks (62), chat desktop picker checks (101), the standing suites all green. README: decisions 54-56, decision 23 updated. SW -> freezmo-v44.
This commit is contained in:
parent
33c0ad1ed0
commit
9d204b85be
16 changed files with 314 additions and 118 deletions
|
|
@ -238,54 +238,61 @@ export function StudyFeed({ deck }: { deck: Deck }) {
|
|||
const progressMax = slideCount;
|
||||
|
||||
return (
|
||||
<div className="frost-bg fixed inset-0 flex flex-col fade-in-mobile">
|
||||
<div className="frost-bg overlay-open fixed inset-0 z-[45] flex flex-col fade-in-mobile">
|
||||
{/* Chrome ---------------------------------------------------- */}
|
||||
{/* One pill: round close button, title + position above the bar, and
|
||||
the streak/xp chips at the other end. Everything sits on the pill's
|
||||
centre line with even padding, so nothing crowds the rounded ends. */}
|
||||
<header className="pt-safe absolute inset-x-0 top-0 z-30 px-3">
|
||||
<div className="study-chrome mx-auto max-w-xl space-y-1.5 rounded-full px-3 py-2">
|
||||
<div className="flex items-center gap-3">
|
||||
<Link
|
||||
href="/"
|
||||
aria-label={t("feed.back")}
|
||||
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
|
||||
value={progressValue}
|
||||
max={progressMax}
|
||||
label={t("feed.activityOf", { n: progressValue, total: progressMax })}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex shrink-0 items-center gap-1.5">
|
||||
<span
|
||||
className={cn(
|
||||
"inline-flex items-center gap-1 rounded-xl px-2 py-1 text-xs font-extrabold transition",
|
||||
streak >= 3
|
||||
? "tint-peach"
|
||||
: "bg-[var(--surface-sunken)] text-[var(--text-muted)]",
|
||||
)}
|
||||
title={t("feed.streak", { n: streak })}
|
||||
aria-label={t("feed.streak", { n: streak })}
|
||||
>
|
||||
<FlameIcon className="size-3.5" />
|
||||
{streak}
|
||||
<div className="study-chrome mx-auto flex max-w-xl items-center gap-2.5 rounded-full px-2.5 py-2">
|
||||
<Link
|
||||
href="/"
|
||||
aria-label={t("feed.back")}
|
||||
title={t("feed.back")}
|
||||
className="grid size-10 shrink-0 place-items-center rounded-full bg-[var(--surface-sunken)] text-[var(--text)] transition hover:bg-[var(--hover)]"
|
||||
>
|
||||
<XIcon className="size-4" />
|
||||
</Link>
|
||||
|
||||
<div className="min-w-0 flex-1">
|
||||
<div className="flex items-baseline justify-between gap-3">
|
||||
<span className="min-w-0 truncate text-[13px] font-semibold leading-tight text-[var(--text)]">
|
||||
{currentDeck.title}
|
||||
</span>
|
||||
<span
|
||||
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={t("feed.xp", { n: xp })}
|
||||
aria-label={t("feed.xp", { n: xp })}
|
||||
>
|
||||
<BoltIcon className="size-3.5" />
|
||||
{xp}
|
||||
<span className="shrink-0 text-[11.5px] font-bold tabular-nums text-[var(--text-muted)]">
|
||||
{retryMode ? t("feed.retry") : null}
|
||||
{Math.min(index + 1, total)}/{total}
|
||||
</span>
|
||||
</div>
|
||||
<ProgressBar
|
||||
className="mt-1.5"
|
||||
value={progressValue}
|
||||
max={progressMax}
|
||||
label={t("feed.activityOf", { n: progressValue, total: progressMax })}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex items-center justify-between gap-2 text-[11px] font-semibold text-[var(--text-muted)]">
|
||||
<span className="min-w-0 truncate">{currentDeck.title}</span>
|
||||
<span className="shrink-0">
|
||||
{retryMode ? t("feed.retry") : ""}
|
||||
{Math.min(index + 1, total)}/{total}
|
||||
|
||||
<div className="flex shrink-0 items-center gap-1.5">
|
||||
<span
|
||||
className={cn(
|
||||
"inline-flex items-center gap-1 rounded-full px-2.5 py-1 text-xs font-extrabold tabular-nums transition",
|
||||
streak >= 3
|
||||
? "tint-peach"
|
||||
: "bg-[var(--surface-sunken)] text-[var(--text-muted)]",
|
||||
)}
|
||||
title={t("feed.streak", { n: streak })}
|
||||
aria-label={t("feed.streak", { n: streak })}
|
||||
>
|
||||
<FlameIcon className="size-3.5" />
|
||||
{streak}
|
||||
</span>
|
||||
<span
|
||||
className="inline-flex items-center gap-1 rounded-full bg-[var(--surface-sunken)] px-2.5 py-1 text-xs font-extrabold tabular-nums text-[var(--text-muted)]"
|
||||
title={t("feed.xp", { n: xp })}
|
||||
aria-label={t("feed.xp", { n: xp })}
|
||||
>
|
||||
<BoltIcon className="size-3.5" />
|
||||
{xp}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue