Mounts a billing-state pill in the topbar that reads useTrialBanner() and
renders the appropriate label / tone / CTA per spec:
- pristine / warning → "Pro trial · Nd" (info → warning amber as days drop)
- urgent → "Pro trial · today" (warning amber, semibold)
- expired → "Trial expired — pick a plan" → /account/billing/select-plan
- paid → planBilling.display_name (quiet)
- complimentary → "Complimentary Pro" (accent, no CTA)
- past_due → "Payment failed — update card" → /account/billing
- canceled → "Reactivate" → /account/billing/select-plan
- null → hidden
Uses existing design-system tokens only (text-info/bg-info-dim,
text-warning/bg-warning-dim, text-danger/bg-danger-dim, text-accent/
bg-accent-dim, text-muted-foreground/bg-elevated). Clickable variants
render as react-router-dom <Link>s and are keyboard-focusable with an
accent focus-visible ring. Mobile collapses the label to a clock icon
with a title attribute carrying the full text.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Wires up the soft 7-day email-verification grace period UX.
- EmailVerificationBanner now uses the design-system warning tokens
(bg-warning-dim / text-warning) and hides itself once the grace
period expires, so the wall takes over without double-messaging.
- EmailVerificationWall picks up data-testids on the resend and
sign-out CTAs.
- VerifyEmailPage gains a single-fire useRef guard (so React 19
strict-mode double-invoke doesn't burn the token), an
already-verified short-circuit that skips the API call, success
state with auth-store refresh + redirect to /?verified=1, and
an error state with a resend CTA.
Tests: banner hides past day-7, banner resend triggers API call,
verify success refreshes + redirects, verify short-circuits when
already verified, single-fire guard holds across remount.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>