Viewport:
- Add `viewport` export with `viewport-fit=cover` (enables CSS safe-area-inset-*
on bezel-less iOS/Android) and `interactive-widget=resizes-content` (prevents
layout jumps from virtual keyboard open/close)
iOS zoom prevention:
- input.tsx, textarea.tsx: change text-sm (14px) → text-base sm:text-sm (16px)
on mobile; iOS Safari auto-zooms any input with font-size < 16px
Touch targets:
- button.tsx: default h-10 → h-11 (44px), sm h-8 → h-9 (36px), icon h-10→h-11
matching the 44×44px iOS HIG and WCAG 2.5.5 minimum
- Add touch-manipulation to buttons, inputs, textarea to eliminate 300ms tap delay
Dialog → mobile bottom sheet:
- On mobile (< 640px): anchored to bottom with full width, rounded top corners,
slide-in-from-bottom / slide-out-to-bottom animation, drag handle affordance,
max-h-[90svh] + overflow-y-auto to prevent viewport overflow
- Safe area padding: pb-[max(1.25rem,env(safe-area-inset-bottom))]
- On desktop (sm+): unchanged centered modal with zoom animation
- Close button gets a 32×32 tap area on mobile
Mobile navigation:
- New bottom-nav.tsx: persistent 3-tab bottom bar (مسیر/مرکز/لیگ) shown below
md: breakpoint, hidden on desktop; 56px height + safe-area-inset-bottom;
active tab gets heavier stroke and scale
- Only shown for authenticated non-admin users
- app-shell.tsx: injects BottomNav; main content gets dynamic padding-bottom to
clear the bar (56px + safe area) on mobile, reverts to py-10 on md:
- Footer: safe-area-inset-bottom padding so content clears iPhone home indicator
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Task 4 — Event Registration Confirmation (glassmorphism removal):
- Replace translucent gradient + backdrop-blur-md toast in use-realtime.tsx
with a solid bg-card container, full-opacity border, and a colored
left accent bar — high contrast, readable in all themes, no blur
Task 5 — Video player UX (within anti-cheat constraints):
- Keyboard shortcuts: Space (play/pause), M (mute), ← (seek back 10s),
F (fullscreen) — active globally, disabled when an input is focused
- Fullscreen button added to the control bar (F key shortcut)
- Volume slider (0–100%) replaces mute-only toggle; volume is persisted
to localStorage across sessions under key `pargar:volume`
- Buffer range visualized as a translucent white bar behind the playback
progress track so users see how much is buffered
- Exponential backoff auto-retry on video error: 1s, 2s, 4s … 30s cap;
retry count shown in error message; manual retry clears the timer
- Speed controls (0.75x–2x) are intentionally absent: the verified-watch
anti-cheat locks playbackRate=1; changing it would break the heartbeat
accumulation that gates quiz unlock and certification
- HLS/ABR requires backend FFmpeg transcoding; the player is structured
so swapping src=mp4 → src=.m3u8 + hls.js is a one-file change when
the backend pipeline is ready
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- safe-markdown: add `cancelled` flag to async useEffect; no more
setState after unmount when component is destroyed mid-import
- rich-editor: same cleanup for preview tab effect; also remove dead
`prose prose-sm max-w-none` classes (Tailwind Typography not installed)
and replace with explicit arbitrary-selector markdown styling that
actually renders using existing design tokens
- profile-certificate-slot: drop dead `ORDER_LABEL`, `order` variable,
and `physicalOrder` from `MineCertificateResponse`; physical orders
are disabled — these were leftover references causing lint noise
- learning-panel: change `issuingCert: boolean` → `issuingCertFor:
number | null` so only the targeted user's button shows a spinner;
a boolean shared across all users caused the wrong row to animate
when the admin switched selected users mid-request
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Cast editor.storage to any for tiptap-markdown's getMarkdown (untyped extension storage)
- Replace setContent(value, false) with setContent(value, { emitUpdate: false }) for TipTap v3 API
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Keep Next on the patched 15.5 line instead of the Next 16 Dependabot bump, and move OpenTelemetry and gRPC to the versions that close the open Go alerts.