Phase 2 — Consumer UI redesign (light Calm-Focus, mobile-first, RTL)#12
Merged
Conversation
Groundwork for the Calm Focus, light-first, emerald-accent redesign. No
screen redesigned yet — the app looks the same except it now renders in
Rubik (which finally styles Arabic instead of an unstyled fallback).
- globals.css: semantic design tokens as CSS variables (background,
surface, foreground, muted, border, input, ring, primary + variants,
radius). Architected dark-ready — a future .dark {} overrides values
with no utility changes. Legacy neon vars kept temporarily (removed
screen-by-screen in P2.1-P2.7); transitional font aliases map the old
--font-playfair/-mono/-sans to Rubik so the in-between app is uniformly
Rubik, never a broken fallback.
- tailwind.config.ts: theme.extend wires the tokens (colors, fontFamily,
radius, soft/card shadows); darkMode: 'class' for the dark-ready path.
- layout.tsx: swap the three Latin-only Google fonts (Playfair/DM Mono/
DM Sans) for Rubik (subsets: latin + arabic); delete the duplicated
inline <style> color block (globals.css is now the single source).
- add lucide-react (MIT) for a consistent icon set.
Presentation-only; no API/auth/i18n/RTL logic touched; no locale strings
changed; no migration. Production build passes (en+ar generated, Rubik
arabic subset resolves); tsc --noEmit passes.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Owner
Author
🛡️ Fixor Security ReportRepository: Summary
No findings in this run — no business-logic vulnerabilities detected.
|
First consumers of the Calm Focus palette: the dashboard chrome goes light; content stays on the legacy dark surface until each screen is migrated (P2.2+), so un-redesigned screens' white text does not vanish. Primitives (hand-built on the existing cn(), token-only, no framework): - ui/Button (variants + sizes, 44px default tap target, buttonVariants helper for link styling), Card, Input, Badge, Sheet (controlled drawer; Escape + overlay close, aria-modal; no focus trap yet). Shell: - Desktop Sidebar rewritten in the light palette (surface, tokens, lucide icons, active = primary-subtle). Mobile drops the old checkbox-drawer hack for a slim top bar (brand + sign-out) plus a bottom tab bar (thumb-reachable, >=44px, safe-area padded for the Phase 8 Capacitor shell). - RTL now via Tailwind logical properties (start-0, border-e, ms-60) that auto-mirror under dir="rtl" -- cleaner than the prior isRtl branching. - Shared SignOutButton keeps the exact client-Supabase signOut + redirect in one place, used by both sidebar and mobile top bar. Presentation-only: auth/entitlement/redirect logic in the server layout preserved verbatim; no locale strings changed; no migration. tsc and a production build pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Restructure the dashboard home into a student home on light surfaces — the first CONTENT screen to leave the legacy dark panel. - Split into a thin server wrapper (page.tsx: auth + the 3 count queries + activity fetch, all unchanged) and a dumb, prop-driven <StudentHome/> presentational component (Phase 8 reuse). - Sections: welcome header, primary "Ask" entry, an inert streak placeholder (renders 0; Phase 5 wires real tracking), subject stats, subjects quick-access, and a restyled RecentActivity. - Root paints its own light canvas so every heading/label/card sits on a light surface with dark tokens — nothing inherits the layout's legacy text-white, so nothing vanishes. The dark <main> gutter closes when the whole layout flips light at the end of Phase 2. - RTL-safe: logical properties + rtl:-scale-x-100 on directional arrows. - Locale: home-only reword of talkAgentTitle out of terminal caps; add newSubject/streakLabel/streakUnit (en+ar). Shared newKb* keys untouched. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Switch the inert streak placeholder from a muted "0" to a ghost "—". A "0" asserts a live measurement that happens to read zero (and would read 0 even for a returning active student until Phase 5) — the same soft over-implication refused with "Unlimited"/"page citations". "—" reads as "not tracked yet". - streak prop is now number | null: null → ghost "—" (unit suppressed so it doesn't re-imply a days measurement); a real number renders normally, so Phase 5 just passes a value with no component change. Presentation-only; locale untouched. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Restyle the subjects screens and the upload zone to the light Calm-Focus palette. Presentation-only; data/upload wiring untouched. - knowledge/page.tsx → thin server wrapper (list fetch + ordering verbatim) feeding a new dumb <SubjectsList/> (prop-driven hrefs/labels, Phase 8 reuse). - knowledge/[id]/page.tsx is a client component, so it's restyled in place: the load effect, docs state, DropZone optimistic onSuccess, and statusColor mapping are preserved (status hexes swapped for AA-safe light tokens). - DropZone: restyle only. accept=".pdf,.docx,.pptx,.xlsx,.txt,.md" kept EXACTLY (still matches the "Supported" hint and the server ALLOWED_TYPES); handleFile, onDrop, the /api/ingest fetch, the state machine, and onSuccess are unchanged. Added an Upload affordance icon (idle state only) — no format implications. - Each screen paints its own light canvas so headings/cards/labels use dark tokens and nothing inherits the layout's legacy text-white. Directional arrows flip under RTL (rtl:-scale-x-100); language badge preserved. Locale untouched (diff-clean); shared newKb* keys intact for the agent screen. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Restyle the highest-logic screen to the light Calm-Focus palette. All engine logic is preserved verbatim — restyle only. - Sheet: ADD a focus trap (P2.4 commitment). Focus moves into the panel on open, Tab/Shift+Tab cycle within it, focus restores to the trigger on close; existing Escape + overlay-close + aria-modal kept. First real Sheet use. - KBSelector: modern chat layout — desktop keeps the persistent history column; mobile moves it into a Sheet drawer (start-side, RTL-aware) opened by a Menu button. Subject pills stay single-select (switch active subject + reset conversation) — never a cross-subject/multi-select search. Selection/mount/ fetch logic unchanged; the only additions are drawer open/close state. - ChatBox: restyle only — handleSend, the SSE reader loop, decodeCitations, the X-Conversation-Id / X-Citations header reads, scroll, and Cmd+Enter are byte-for-byte unchanged. - MessageBubble: light bubbles (emerald user / bordered assistant); markdown marks inherit the bubble color so they read on both. Citations still render [n] filename + a "filename · NN% match" tooltip — no page numbers. - agent/page.tsx → thin server wrapper; no-subjects case is the dumb <AgentEmptyState/> (Phase 8 reuse). - Each screen paints its own light canvas so nothing inherits the layout's legacy text-white. Locale: add agent.history (en+ar) for the drawer label; shared newKb* keys untouched. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ror (P2.4) Honesty fix (scoped exception to P2.4's presentation-only rule). The rate-limit 429 is sent as text/plain, but handleSend did `if (!res.ok) throw` → the catch rendered the generic "Connection error." — hiding the real reason AND implying a technical failure. A limited student would think the app is broken. Now the !res.ok branch reads the response body and renders THAT as the assistant message (falling back to the generic string only when the body is empty), then returns before the streaming path. Confined to that branch: the SSE stream loop, decodeCitations, and the X-Conversation-Id/X-Citations reads are untouched, and genuine network/stream failures still land in catch with the friendly fallback. Locale diff-clean: the message comes from the server; only the empty-body fallback reuses the existing connectionError string. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Restyle the new-subject form and the settings/plan screen to the light
Calm-Focus palette. Presentation-only; wiring preserved verbatim.
- new/page.tsx is a client component → restyled in place. handleSubmit is
untouched: the auth check, /api/check-limit fetch, and the tier-correct,
interpolated limit message (template = pro ? errorLimitPro : errorLimitFree;
replace('{limit}', limit)) are byte-for-byte preserved — no hardcoded number,
no free-plan wording leaking to Pro. Inputs use the light Input primitive /
field styling; native select arrow kept for a clear (RTL-correct) affordance.
- settings/page.tsx → thin server wrapper feeding a new dumb <SettingsPanel/>
(Phase 8 reuse). getEntitlement stays the sole tier source (never a raw
subscriptions read); isPro, the locale-aware renewal date, the /pricing
upgrade path, and the active-subscription text are all preserved. The user
email is present in the Account card (its intended home after being dropped
from mobile chrome and the home header).
- Each screen paints its own light canvas so nothing inherits the layout's
legacy text-white. Locale untouched (diff-clean); shared keys intact.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
First of three P2.6 commits. Migrate the auth pages to the light Calm-Focus palette; presentation-only, all wiring preserved verbatim. - login: `signInWithPassword` + `router.push`, form state, and the show/hide-password toggle are unchanged — only classNames/structure flipped to light (brand panel now emerald `bg-primary`, form on `bg-surface`, light inputs). RTL upgraded to logical properties (`border-e`, `end-3`, `text-start`). - signup: `signUp` + the `profiles` upsert (incl. `plan: 'free'`, `full_name`, `email`) + `router.push` unchanged; same light restyle. - Each page paints its OWN light canvas (`bg-background`) — the root `<body>` / `globals.css` dark surfaces are deliberately NOT touched (that's P2.7). - Locale `t.*` untouched (diff-clean); no migration. Also lands PROGRESS.md: register #17–19 (legal pages English-only; stale vocab/domains; non-functional contact form) + P2.6 split (a done, b/c remaining). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Second of three P2.6 commits. Migrate the two converting pages to the light Calm-Focus palette; presentation-only, all wiring preserved verbatim. - landing: every href unchanged — the three `/signup` CTAs (nav, hero cta1, bottom CTA), the nav `/pricing`+`/about`, `#how-it-works` (×2), and the footer privacy/terms/refund/Support(contact)/GitHub links. All `t.*` copy untouched. Hero terminal mock restyled to a light code card (traffic-light chrome kept). - pricing: the `initializePaddle` mount effect, the checkout `onClick` (getUser → login redirect → `/api/paddle/checkout` → `paddle?.Checkout.open`), and the free-plan `<Link href=/signup>` are byte-for-byte unchanged — only classNames flipped to light (Pro card `border-primary`, error → red-700). - Each page paints its OWN light canvas (`bg-background`); root `<body>` / `globals.css` NOT touched (P2.7). Locale `t.*` diff-clean; no migration. PROGRESS.md: register #20 (landing "Ready in 0.4s" is a hardcoded speed over-promise the real ingestion doesn't meet) + P2.6b marked done. #17/#18 extended to name the auth "Unlock your knowledge" tagline (i18n + stale-vocab). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Third of three P2.6 commits. Migrate the low-wiring content pages to light; presentation-only, content and wiring preserved verbatim. - about: restyle only; the `/signup` CTA + all `t.about.*` copy unchanged. - contact: mailto (`hello@tryknowflow.com`) + GitHub link preserved; the form is left HONESTLY INERT — `type="button"`, no onSubmit/handler added (register #19 wire-or-mailto-only is a later decision, not this restyle). Inputs restyled. - privacy / terms / refund: prose text is byte-identical to main (md5-verified); only the wrapper/headings flipped to light and the dead `prose prose-invert` classes dropped (no typography plugin installed). Content stays English under /ar by design — pre-existing, tracked as #17/#18, NOT a regression here. - Each page paints its own `bg-background` bridge; root `<body>` / `globals.css` NOT touched (P2.7). Locale `t.*` diff-clean; no migration. PROGRESS.md: P2.6c done → P2.6 COMPLETE (only P2.7 remains). #20 reclassified into the honesty/over-promise bucket (false speed claim, not i18n). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…7) — Phase 2 complete
The final flip + audit. Presentation-only in effect; no wiring/copy/locale change.
FLIP the three shared dark surfaces to the semantic light palette:
- dashboard `<main>` (dashboard/layout.tsx): bg-[var(--bg-color)]/text-white → bg-background/text-foreground.
- root `<body>` ([locale]/layout.tsx): same.
- globals.css `body {}`: var(--bg-color)/white → var(--background)/var(--foreground).
REMOVE every per-screen/per-page light-canvas bridge that compensated for the
dark root, now redundant:
- 6 dashboard screens (StudentHome, SubjectsList, SettingsPanel, AgentEmptyState,
knowledge/new, knowledge/[id]): drop the `rounded-2xl bg-background p-4 md:p-6`
self-canvas wrapper (was double-padding on the now-light main); the `<main>`
owns the canvas + padding. Stale "paints its own canvas" comments corrected.
- 9 public/auth pages: drop the redundant root `bg-background text-foreground`
(body provides it). Only the root className changed — all auth/Paddle/CTA
wiring untouched (verified: signInWithPassword, signUp + profiles upsert +
plan:'free', initializePaddle + checkout all intact).
PURGE the dead legacy tokens (confirmed zero references repo-wide first):
- --bg-color/--accent-color/--border-color/--muted-color/--input-bg
- transitional font aliases --font-playfair/--font-mono/--font-sans.
Audit: full sweep shows zero legacy tokens/hexes/`text-white` remain in src;
tsc clean; locale files not in the diff. PROGRESS.md: P2.7 done, #13 resolved,
Phase 2 code-complete (pending PR #12 merge).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
# Conflicts: # docs/PROGRESS.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Phase 2 — Consumer UI redesign (web, mobile-first)
Migrates the entire product from the legacy dark theme to the light "Calm Focus" palette, mobile-first, with Arabic/RTL as a first-class concern. Visually verified on the Vercel preview in Arabic (
/ar) — landing, dashboard, and Ask pages render correctly on light surfaces at desktop and mobile widths; RTL is mirrored (right sidebar, bottom tab bar in correct order); the streak shows the honest ghost—, not a misleading0; and the decided vocabulary (المواد / الملفات / اسأل / اسأل ملفاتك) displays correctly. Nothing broken.Merging rebuilds the production deployment (
tryknowflow.com) with the new design — intended, now that it's verified.What the redesign delivered
cn()) + mobile-first dashboard shell / sidebar / bottom nav; RTL via logical properties.StudentHome); honest ghost—streak placeholder (reads as not measured, not zero).SettingsPanel);<a>→<Link>upgrade CTA verified against Paddle init-on-mount./pricing.<main>, root<body>,globals.cssbody {}), removed every per-screen light-canvas bridge, and purged the dead legacy tokens (--bg-color/--accent-color/--border-color/--muted-color/--input-bg+--font-playfair/--font-mono/--font-sans). Full sweep: zero legacy tokens/hexes remain insrc.Honesty / correctness fixes made along the way
/api/agentrate-limit body is now shown to the user instead of a generic error (P2.4,b0c9aff).acceptmatches the real server allowlist (carried from P1.2b into P2.3).Explicitly deferred — still tracked in
docs/PROGRESS.md§4/api/ingest,/api/agent429 English-only).Document.file_type,Conversation.platform).t.*+ stale vocab / mixed contact domains (legal pages, auth tagline).Notes
main's in-flight docs: the resolved Supabase blocker (#21) and the new pre-launch backend item (#22), withsupabase-migration-runbook.mdmarked SUPERSEDED.docs/PROGRESS.mdPROGRESS conflict was resolved to keep both truths (Phase 2 complete and #21/#22).mainretains all individual P2.0–P2.7 commits. Merged without--adminso branch protection /enforce_adminsis honored (0 required approvals).🤖 Generated with Claude Code