Skip to content

feat(ch08): A1 sign-in + A4 OTP screens per Figma baseline - #24

Open
lemone112 wants to merge 1 commit into
mainfrom
feat/ch08-login-otp-v2
Open

feat(ch08): A1 sign-in + A4 OTP screens per Figma baseline#24
lemone112 wants to merge 1 commit into
mainfrom
feat/ch08-login-otp-v2

Conversation

@lemone112

Copy link
Copy Markdown
Contributor

Summary

Screens A1 (sign-in) and A4 (email OTP) per Figma taste-SSOT (file vFWveYl6n4pLqSut3GFQxk). Recreates closed PR #23 against main after its base branch (design/figma-baseline-reconcile) was merged+deleted.

All review findings from PR #23 (design-reconciler) are closed in the squashed commit: R2 CTA strong-member, R3 ink-faint wordmark, R4 @theme dedupe, R5 13px essential text, owner deltas (size=control on 5 buttons, single icons module).

Screens

A1 (frames 1552:3908 / 1564:7602 / 1564:7506):

  • AuthShell 480px r24 card, 4-layer shadow-card, 48/48/24 padding, 384px content column
  • Logo tile 48x48 r12 accent+gradient, -24px overlap on card top
  • Header: title 20px SemiBold (--lab-text-title) + subtitle 16px label-s
  • Social 2-up 184x48 (Yandex/Telegram brand SVG in public/brand/) + Passkeys full-width
  • Divider: hairline — "или" — hairline
  • Floating-label email input h48 r12
  • Primary CTA "Получить код" (bg-accent-finish on --lab-accent-blue-strong with gradient+inset; white label ≥4.5:1)
  • States: empty (CTA disabled) / filled / error (border + 13px helper role=alert) / loading (spinner aria-busy)
  • Footer: hairline + "Защищено через" + wordmark (tinted --lab-ink-faint, logotype exemption) + "© 2026 Labpics"

A4 (frame 1563:7321):

  • Same shell, no logo tile
  • 6-cell masked OTP via single hidden input (inputmode=numeric, autocomplete=one-time-code, paste-fill, auto-submit@6)
  • Resend CountdownLink 60s aria-live=polite
  • Back button to /auth/login
  • Error: cell border error + 13px helper role=alert (essential text per DESIGN.md §3.2)

Server seam

Typed server-action stubs (ch02 wires transport when identity ports land):

  • requestOtpCode(email): {ok:true} | {ok:false; code:'not_found'|'rate_limited'}
  • verifyOtpCode(email, code): {ok:true} | {ok:false; code:'invalid'|'expired'|'locked'}

Gates (verified before push)

  • bun test: 392/0 (incl. packages/ui rubric 130/0)
  • tsc --noEmit: clean across all 9 workspaces
  • biome check: clean
  • next build: green

Token purity (rubric-enforced)

  • Everything reads var(--lab-*); no raw hex/rgb/hsl in TSX/CSS
  • Brand hex isolated in public/brand/*.svg only (Yandex #FC3F1D, Telegram gradient) — .svg files excluded from rubric scan
  • Flask mark + wordmark + icons inline currentColor
  • Transitions named-only (no transition-all), motion tokens
  • Interactive state matrix per DESIGN.md §6.3: default/hover/active(.97)/focus-visible(2px outline)/disabled/loading(aria-busy)
  • prefers-reduced-motion via token collapse in tokens.css

Known issue

Full-repo bun test crashes in apps/api on cpu-features NAPI in WSL bun 1.3.14 when TEST_DATABASE_URL is unset (oven-sh/bun#18546). With TEST_DATABASE_URL pointing to Postgres 17 container the suite passes. CI unaffected (github-hosted ubuntu-latest doesn't hit this).

Stacking

Base: main (after PR #21 + #22 merge). Replaces PR #23 (auto-closed when its base was merged+deleted).

AuthShell: 480px card r24, 4-layer shadow-card, 48/48/24 padding, 384px
content column, -24 logo tile overlap, full-bleed hairlines. Wordmark
footer tinted with decorative --lab-ink-faint (WCAG logotype exemption);
"(c) 2026 Labpics" caption below.

A1 (frames 1552:3908 / 1564:7602 / 1564:7506):
- Header: title 20px SemiBold + subtitle 16px label-s
- Social 2-up 184x48 (Yandex/Telegram brand SVG in public/brand/)
- Passkeys full-width secondary button
- Hairline - "ili" - hairline divider
- Floating-label email input h48 r12
- Primary CTA "Poluchit kod" (bg-accent-finish on --lab-accent-blue-strong
  with gradient+inset; white label >=4.5:1)
- States: empty (CTA disabled) / filled / error (border + 13px helper
  role=alert) / loading (spinner aria-busy)

A4 (frame 1563:7321):
- Same shell, no logo tile
- 6-cell masked OTP via single hidden input (inputmode=numeric,
  autocomplete=one-time-code, paste-fill, auto-submit@6)
- Resend CountdownLink 60s aria-live=polite
- Back button to /auth/login
- Error: cell border error + 13px helper role=alert

Server seam: typed stubs requestOtpCode/verifyOtpCode (ch02 wires transport).

Token purity (rubric-enforced):
- var(--lab-*) only; no raw hex/rgb/hsl in TSX/CSS
- Brand hex isolated in public/brand/*.svg only
- Flask/wordmark/icons inline currentColor
- transitions named-only; no transition-all
- Interactive state matrix per DESIGN.md 6.3: default/hover/active(.97)/
  focus-visible(2px outline)/disabled/loading(aria-busy)

Base: main (after PR 21+22 merge)
@coderabbitai

coderabbitai Bot commented Aug 15, 2026

Copy link
Copy Markdown

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 23 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 0964e0a0-2861-48f7-aa48-bf54ac707925

📥 Commits

Reviewing files that changed from the base of the PR and between e5c9d4a and 508393d.

⛔ Files ignored due to path filters (2)
  • apps/web/public/brand/telegram.svg is excluded by !**/*.svg
  • apps/web/public/brand/yandex.svg is excluded by !**/*.svg
📒 Files selected for processing (11)
  • apps/web/src/app/auth/login/actions.ts
  • apps/web/src/app/auth/login/login-flow.tsx
  • apps/web/src/app/auth/login/page.tsx
  • apps/web/src/app/globals.css
  • apps/web/src/components/auth/auth-shell.tsx
  • apps/web/src/components/auth/brand.tsx
  • apps/web/src/components/auth/countdown-resend.tsx
  • apps/web/src/components/auth/otp-field.tsx
  • apps/web/src/components/auth/spinner.tsx
  • apps/web/src/components/auth/text-field.tsx
  • apps/web/src/components/primitives/button.tsx

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant