Next stage
This commit is contained in:
@@ -0,0 +1,200 @@
|
||||
{
|
||||
"project": "Portfolio — Login Screen Rework",
|
||||
"branchName": "ralph/login-screen-rework",
|
||||
"description": "Rework the login screen: responsive sizing, dashboard style alignment, CVMIS rebrand, animated capsule logo, live blurred dashboard background, connection status indicator UX, button pulse, and dissolve transition.",
|
||||
"userStories": [
|
||||
{
|
||||
"id": "US-001",
|
||||
"title": "Skip to login phase for dev iteration",
|
||||
"description": "As a developer, I want to skip boot/ECG and land directly on the login screen so I can iterate on login changes quickly.",
|
||||
"acceptanceCriteria": [
|
||||
"In src/App.tsx, change the initial Phase state from 'boot' to 'login'",
|
||||
"The boot, ECG, and login phases remain in code — only the initial state changes",
|
||||
"App loads directly to the login screen on refresh",
|
||||
"Typecheck passes"
|
||||
],
|
||||
"priority": 1,
|
||||
"passes": true,
|
||||
"notes": "Temporary — final story reverts this. Phase state is on line 47 of App.tsx."
|
||||
},
|
||||
{
|
||||
"id": "US-002",
|
||||
"title": "Create CvmisLogo React SVG component",
|
||||
"description": "As a developer, I need a reusable CvmisLogo component that renders the CVMIS capsule logo from cvmis-logo.svg, supporting both static and animated modes.",
|
||||
"acceptanceCriteria": [
|
||||
"Create src/components/CvmisLogo.tsx as a React component",
|
||||
"Component accepts props: size (number, controls height in px), animated (boolean, default false), className (optional string)",
|
||||
"SVG paths are inlined from cvmis-logo.svg — three <g> groups: capsule-rx (teal #0b7979), capsule-terminal (amber #d97706), capsule-data (green #059669)",
|
||||
"The SVG viewBox is preserved so the logo scales correctly at any size",
|
||||
"When animated=false, all three capsules render in their final fanned-out positions (matching the original SVG layout)",
|
||||
"When animated=true, the component plays a two-phase reveal using framer-motion: Phase 1 (Rise ~500ms): green data capsule scales from 0 to 1 and translates upward into center position, other capsules hidden. Phase 2 (Fan-out ~500ms): all three capsules appear and rotate/translate to their final fanned-out positions with staggered easing",
|
||||
"Animation reference: LogoReveal/frame 1-5.jpg — frame 1-3 show green capsule rising, frame 4-5 show all three fanning out",
|
||||
"Each capsule group uses transform-origin at its base/bottom so fan-out looks like cards spreading from a hand",
|
||||
"prefers-reduced-motion: skip animation, render final state immediately",
|
||||
"Typecheck passes"
|
||||
],
|
||||
"priority": 2,
|
||||
"passes": true,
|
||||
"notes": "The SVG uses a transform with scale(0.05, -0.05) and translate — you'll need to simplify the viewBox and transforms for React. The three <g> IDs are capsule-rx, capsule-terminal, capsule-data. Framer Motion is already installed (11.15.0). Look at LogoReveal/frame 1-5.jpg for the animation sequence. The fan-out in frames 4-5 shows: teal Rx tilts left, amber terminal stays center, green data tilts right."
|
||||
},
|
||||
{
|
||||
"id": "US-003",
|
||||
"title": "Responsive login card sizing and dashboard style alignment",
|
||||
"description": "As a visitor on a 1440p or 4K display, I want the login card to be proportionate to my screen and styled consistently with the GP dashboard.",
|
||||
"acceptanceCriteria": [
|
||||
"Login card width changes from fixed 320px to responsive: clamp(320px, 28vw, 480px)",
|
||||
"Card padding scales from fixed 32px to clamp(24px, 2.5vw, 40px)",
|
||||
"Input field font size scales proportionally (minimum 13px, up to 15px on large viewports)",
|
||||
"Button font size scales proportionally (minimum 14px, up to 16px)",
|
||||
"Label font size scales proportionally (minimum 12px, up to 14px)",
|
||||
"Card uses dashboard color tokens via CSS variables: background var(--surface), border color var(--border-card) or #E4EDEB, text colors var(--text-primary) and var(--text-secondary)",
|
||||
"Input fields use var(--accent) (#0D6E6E) for focus border, #E4EDEB for default border, var(--bg-dashboard) for inactive background",
|
||||
"Card shadow uses the project shadow tokens: 0 1px 2px rgba(26,43,42,0.05) resting, 0 2px 8px rgba(26,43,42,0.08) elevated",
|
||||
"Card border radius remains 12px",
|
||||
"Card still looks good on mobile (≤480px) — should not exceed viewport width minus 32px margin",
|
||||
"Typecheck passes",
|
||||
"Verify in browser using dev-browser skill"
|
||||
],
|
||||
"priority": 3,
|
||||
"passes": true,
|
||||
"notes": "LoginScreen.tsx currently uses inline styles with hardcoded colors (#E5E7EB borders, #64748B text, etc). Replace these with the dashboard CSS custom properties defined in index.css (--surface, --accent, --border, --text-primary, --text-secondary, --text-tertiary). Font family vars: var(--font-ui) for labels/buttons, var(--font-geist-mono) for input monospace."
|
||||
},
|
||||
{
|
||||
"id": "US-004",
|
||||
"title": "Rebrand to CVMIS and integrate animated logo",
|
||||
"description": "As the portfolio owner, I want the login to say CVMIS with the capsule logo replacing the Shield icon.",
|
||||
"acceptanceCriteria": [
|
||||
"Title text changed from 'CareerRecord PMR' to 'CVMIS'",
|
||||
"Subtitle changed from 'Clinical Information System' to 'CV Management Information System'",
|
||||
"The Shield icon import and its teal background container are removed from the branding section",
|
||||
"CvmisLogo component is imported and rendered in the branding section with animated=true",
|
||||
"Logo height is proportional to the responsive card size (roughly 48-64px depending on viewport, use clamp)",
|
||||
"Logo animation completes before the typing animation starts — adjust the startLoginSequence delay (currently 400ms) to account for logo animation duration (~1000ms total)",
|
||||
"Footer text 'Secure clinical system login' remains unchanged",
|
||||
"prefers-reduced-motion: logo shows instantly in final state, typing starts after original 400ms delay",
|
||||
"Typecheck passes",
|
||||
"Verify in browser using dev-browser skill"
|
||||
],
|
||||
"priority": 4,
|
||||
"passes": true,
|
||||
"notes": "The Shield icon is at LoginScreen.tsx lines 213-218. The logo animation is ~1000ms (500ms rise + 500ms fan-out). Increase the startLoginSequence delay from 400ms to ~1500ms (400ms card entrance + 1000ms logo + 100ms pause). CvmisLogo component from US-002."
|
||||
},
|
||||
{
|
||||
"id": "US-005",
|
||||
"title": "Replace Home icon with CVMIS logo on TopBar",
|
||||
"description": "As a visitor on the dashboard, I want to see the CVMIS brand logo in the top-left corner instead of the generic Home icon.",
|
||||
"acceptanceCriteria": [
|
||||
"In src/components/TopBar.tsx, remove the Home import from lucide-react",
|
||||
"Import CvmisLogo from ./CvmisLogo",
|
||||
"Replace the <Home> element with <CvmisLogo size={24} /> (static, no animation)",
|
||||
"Logo colors match SVG source: teal #0b7979, amber #d97706, green #059669",
|
||||
"Logo maintains aspect ratio and fits within the TopBar height",
|
||||
"The 'Headhunt Medical Center' brand text and all other TopBar elements remain unchanged",
|
||||
"Typecheck passes",
|
||||
"Verify in browser using dev-browser skill"
|
||||
],
|
||||
"priority": 5,
|
||||
"passes": true,
|
||||
"notes": "TopBar.tsx line 57-61 has the Home icon. Simple swap — CvmisLogo with animated=false (the default). If Home is the only lucide icon used in the import, clean up the import. Check: Search is also imported from lucide-react on line 2."
|
||||
},
|
||||
{
|
||||
"id": "US-006",
|
||||
"title": "Render live dashboard behind login with blur overlay",
|
||||
"description": "As a visitor, I want to see the GP dashboard blurred behind the login card, creating visual continuity.",
|
||||
"acceptanceCriteria": [
|
||||
"In App.tsx, during the 'login' phase, render DashboardLayout underneath the login overlay (both visible simultaneously)",
|
||||
"DashboardLayout is wrapped in DetailPanelProvider (as it is in the 'pmr' phase)",
|
||||
"DashboardLayout renders at scroll position 0 (showing patient summary header area)",
|
||||
"LoginScreen becomes an overlay: fixed position, full viewport, semi-transparent background rgba(240, 245, 244, 0.7) with backdrop-filter: blur(20px)",
|
||||
"Dashboard content is non-interactive while login overlay is present (the overlay captures all pointer events)",
|
||||
"The login card remains centered on top of the blurred overlay",
|
||||
"backdrop-filter blur is constant from the moment login appears (no ease-in)",
|
||||
"prefers-reduced-motion: blur still applies (static visual treatment), only entrance animations are skipped",
|
||||
"Typecheck passes",
|
||||
"Verify in browser using dev-browser skill"
|
||||
],
|
||||
"priority": 6,
|
||||
"passes": true,
|
||||
"notes": "Currently App.tsx renders phases exclusively (only one at a time). Change so that login phase renders: <DetailPanelProvider><DashboardLayout /></DetailPanelProvider> + <LoginScreen overlay on top>. LoginScreen.tsx already has 'fixed inset-0 z-50' — just change its backgroundColor from solid #1A2B2A to the semi-transparent value with backdrop-filter. Consider adding will-change: backdrop-filter for performance."
|
||||
},
|
||||
{
|
||||
"id": "US-007",
|
||||
"title": "Connection status indicator with animated dots and typing-linked timing",
|
||||
"description": "As a visitor, I want to see a clear red-to-green status transition tied to the typing sequence, not an arbitrary timer.",
|
||||
"acceptanceCriteria": [
|
||||
"Status indicator LED dot size increased from 6px to 10px",
|
||||
"LED dot has a subtle glow effect: box-shadow 0 0 6px 1px in the LED color (red or green)",
|
||||
"Status text size increased from 10px to 12px",
|
||||
"Initial state: RED LED + 'Awaiting secure connection' in red (#DC2626) with animated trailing dots",
|
||||
"The trailing dots animate: dots cycle through '.', '..', '...' repeating every ~1.5 seconds",
|
||||
"Remove the existing independent 2000ms connectionTimeout timer",
|
||||
"Instead, connection transitions to green exactly 500ms after typingComplete becomes true",
|
||||
"Green state: GREEN LED (#059669) + 'Secure connection established, awaiting login' in green",
|
||||
"Transition between red and green states has a smooth 300ms color/shadow transition",
|
||||
"prefers-reduced-motion: no dot cycling animation, state changes happen instantly",
|
||||
"Typecheck passes",
|
||||
"Verify in browser using dev-browser skill"
|
||||
],
|
||||
"priority": 7,
|
||||
"passes": true,
|
||||
"notes": "The connectionTimeout is set on line 117 of LoginScreen.tsx (2000ms independent timer). Remove it and add a useEffect that watches typingComplete — when true, setTimeout 500ms then setConnectionState('connected'). The dot animation can use a simple interval cycling dotCount 0→1→2→0. The LED glow box-shadow: '0 0 6px 1px rgba(220,38,38,0.4)' for red, '0 0 6px 1px rgba(5,150,105,0.4)' for green."
|
||||
},
|
||||
{
|
||||
"id": "US-008",
|
||||
"title": "Login button pulse animation on activation",
|
||||
"description": "As a visitor, I want the login button to pulse subtly when it becomes clickable so I know to click it.",
|
||||
"acceptanceCriteria": [
|
||||
"Add a CSS @keyframes animation 'login-pulse' in index.css: scale 1 → 1.03 → 1, ease-in-out, duration 1.5s",
|
||||
"When canLogin becomes true (button enabled), apply the pulse animation repeating every 3 seconds (1.5s animation + 1.5s pause via animation-delay or longer duration with keyframe percentages)",
|
||||
"Pulse animation stops when button is hovered (animation: none on hover)",
|
||||
"Pulse animation stops immediately on click (remove animation class on buttonPressed)",
|
||||
"Button opacity transitions from 0.6 to 1.0 when enabled (existing behavior, preserve)",
|
||||
"prefers-reduced-motion: no pulse animation, button just becomes enabled with opacity 1",
|
||||
"Button still receives keyboard focus when it becomes enabled (existing behavior)",
|
||||
"Typecheck passes",
|
||||
"Verify in browser using dev-browser skill"
|
||||
],
|
||||
"priority": 8,
|
||||
"passes": true,
|
||||
"notes": "The canLogin variable is on line 43 of LoginScreen.tsx. Add a CSS class 'login-pulse-active' that applies the animation, and conditionally apply it when canLogin && !buttonPressed && !buttonHovered. The @keyframes could use: 0%,100% { transform: scale(1) } 50% { transform: scale(1.03) } with animation: login-pulse 1.5s ease-in-out infinite and a wrapper that adds 1.5s gaps (or use 0%,35%,65%,100% keyframe percentages to build in the pause)."
|
||||
},
|
||||
{
|
||||
"id": "US-009",
|
||||
"title": "Login dissolve transition to reveal dashboard",
|
||||
"description": "As a visitor, I want the login card and blur overlay to dissolve smoothly on login, revealing the dashboard underneath.",
|
||||
"acceptanceCriteria": [
|
||||
"On login click: existing pressed state + loading spinner behavior is preserved",
|
||||
"After loading spinner phase, the login card fades out (opacity 0) with slight scale up (1.03)",
|
||||
"Simultaneously, the overlay backdrop-filter blur animates from 20px to 0px",
|
||||
"Overlay background opacity fades from 0.7 to 0",
|
||||
"Total dissolve duration: ~600ms from card exit to fully revealed dashboard",
|
||||
"After dissolve completes, the login overlay is removed from DOM and dashboard becomes interactive",
|
||||
"In App.tsx, transition from login to pmr phase after the overlay dissolve completes (use a callback from LoginScreen)",
|
||||
"prefers-reduced-motion: instant transition, no dissolve animation",
|
||||
"Typecheck passes",
|
||||
"Verify in browser using dev-browser skill"
|
||||
],
|
||||
"priority": 9,
|
||||
"passes": true,
|
||||
"notes": "Currently LoginScreen has isExiting state that scales card to 1.03 and fades to opacity 0 (line 163). Extend this to also animate the overlay container. The overlay is the outer div with 'fixed inset-0' — animate its backdrop-filter and background-color. Use framer-motion animate for coordinated exit. The onComplete callback should fire after the full dissolve, not after the card fade."
|
||||
},
|
||||
{
|
||||
"id": "US-010",
|
||||
"title": "Re-enable boot sequence",
|
||||
"description": "As a user, I want the full boot → ECG → login → dashboard experience restored.",
|
||||
"acceptanceCriteria": [
|
||||
"In src/App.tsx, change the initial Phase state back from 'login' to 'boot'",
|
||||
"Boot → ECG → Login → Dashboard sequence works end to end",
|
||||
"Login screen shows blurred dashboard behind it",
|
||||
"Logo animation plays, typing animation follows, connection indicator transitions, button pulses",
|
||||
"Clicking login dissolves the overlay to reveal the dashboard",
|
||||
"No other changes to App.tsx beyond reverting the initial state",
|
||||
"Typecheck passes",
|
||||
"Verify in browser using dev-browser skill: app starts at boot, progresses through ECG, login with blur background and logo animation, arrives at dashboard"
|
||||
],
|
||||
"priority": 10,
|
||||
"passes": true,
|
||||
"notes": "Simple revert of US-001. Phase state is on line 47 of App.tsx."
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,208 @@
|
||||
# Progress Log — Login Screen Rework
|
||||
# Branch: ralph/login-screen-rework
|
||||
# Started: 2026-02-15
|
||||
|
||||
## Codebase Patterns
|
||||
|
||||
### Project Structure
|
||||
- Components in `src/components/`, tiles in `src/components/tiles/`
|
||||
- Data files in `src/data/`
|
||||
- Types in `src/types/pmr.ts` and `src/types/index.ts`
|
||||
- Hooks in `src/hooks/`, Contexts in `src/contexts/`, Lib in `src/lib/`
|
||||
- Path alias: `@/` maps to `./src/`
|
||||
|
||||
### Phase Management
|
||||
- App.tsx controls phase: 'boot' -> 'ecg' -> 'login' -> 'pmr'
|
||||
- BootSequence.tsx, ECGAnimation.tsx — LOCKED, do not modify
|
||||
- LoginScreen.tsx bridges to dashboard
|
||||
|
||||
### Typography
|
||||
- Elvaro Grotesque (`font-ui`, `var(--font-ui)`) — primary UI font
|
||||
- Blumir (`font-ui-alt`) — alternative variable font
|
||||
- Geist Mono (`font-geist`, `var(--font-geist-mono)`) — timestamps, data values
|
||||
- Fira Code (`font-mono`) — boot/ECG terminal only
|
||||
- Do NOT use Inter, Roboto, DM Sans, or system defaults
|
||||
|
||||
### Design Tokens (index.css CSS variables)
|
||||
- --surface: #FFFFFF (card/topbar background)
|
||||
- --bg-dashboard: #F0F5F4 (warm sage content background)
|
||||
- --accent: #0D6E6E (teal primary)
|
||||
- --accent-hover: #0A8080
|
||||
- --accent-light: rgba(10,128,128,0.08)
|
||||
- --border: #D4E0DE (structural borders)
|
||||
- --border-card: #E4EDEB (card/inner borders)
|
||||
- --text-primary: #1A2B2A
|
||||
- --text-secondary: #5B7A78
|
||||
- --text-tertiary: #8DA8A5
|
||||
- --sidebar-width: 304px
|
||||
- --topbar-height: 56px
|
||||
|
||||
### Known Dependencies
|
||||
- React 18.3.1, TypeScript, Vite, Tailwind CSS
|
||||
- Framer Motion 11.15.0, Lucide React 0.468.0, fuse.js 7.0.0
|
||||
|
||||
### Phase Rendering (post US-006)
|
||||
- Login phase now renders BOTH DashboardLayout and LoginScreen overlay simultaneously
|
||||
- DashboardLayout is wrapped in DetailPanelProvider for both 'login' and 'pmr' phases
|
||||
- LoginScreen overlay: `fixed inset-0 z-50` with `rgba(240, 245, 244, 0.7)` + `backdrop-filter: blur(20px)`
|
||||
|
||||
### Key Files for This Feature
|
||||
- src/App.tsx — phase management, will need restructuring for blur overlay
|
||||
- src/components/LoginScreen.tsx — main login screen (416 lines)
|
||||
- src/components/TopBar.tsx — Home icon replacement target (line 57)
|
||||
- src/components/DashboardLayout.tsx — rendered behind login blur
|
||||
- src/contexts/DetailPanelContext.tsx — wraps DashboardLayout
|
||||
- cvmis-logo.svg — source SVG with 3 capsule groups
|
||||
- LogoReveal/frame 1-5.jpg — animation reference frames
|
||||
|
||||
### CvmisLogo Component
|
||||
- `size` prop: numeric, sets SVG height attribute directly
|
||||
- `cssHeight` prop: string, sets height via CSS style (use for clamp/responsive values)
|
||||
- `animated` prop: boolean, enables framer-motion reveal animation (1000ms total)
|
||||
- Logo animation: 500ms rise (green capsule) + 500ms fan-out (all three) = 1000ms total
|
||||
|
||||
### LoginScreen.tsx Key Lines (post US-007)
|
||||
- Line 20: connectionState useState
|
||||
- Line 21: dotCount useState (for animated trailing dots)
|
||||
- Line 43: canLogin derived state
|
||||
- Line 60-101: startLoginSequence (typing animation)
|
||||
- Line 110-115: useEffect — connection transitions to green 500ms after typingComplete
|
||||
- Line 118-126: useEffect — animated dot cycling (500ms interval) while connecting
|
||||
- Line 128-150: useEffect — cursor blink + startLoginSequence delay (no more connectionTimeout)
|
||||
- Line 370-405: Connection status indicator (10px LED dot with glow, 12px text)
|
||||
|
||||
---
|
||||
|
||||
## 2026-02-15 - US-010
|
||||
- Reverted initial Phase state from 'login' back to 'boot' in App.tsx line 47
|
||||
- Full flow verified: boot → ECG → login (with blur, logo, typing, connection indicator, pulse) → dissolve → dashboard
|
||||
- Files changed: src/App.tsx
|
||||
- **Learnings for future iterations:**
|
||||
- Simple one-line revert as planned in US-001
|
||||
- The full boot→ECG→login sequence takes ~20 seconds before login screen appears
|
||||
---
|
||||
|
||||
## 2026-02-15 - US-009
|
||||
- Changed outer overlay container from plain `<div>` to `<motion.div>` for animated exit
|
||||
- On isExiting: overlay animates backgroundColor to transparent, backdropFilter from blur(20px) to blur(0px) over 600ms
|
||||
- Card exit animation extended from 200ms to 400ms for smoother dissolve feel
|
||||
- onComplete callback fires after 600ms dissolve (previously 200ms card exit)
|
||||
- After dissolve completes, overlay removed from DOM and dashboard becomes interactive
|
||||
- prefers-reduced-motion: instant transition (0ms for all timers)
|
||||
- Files changed: src/components/LoginScreen.tsx
|
||||
- Verified in browser: clicked login → spinner → card fades + overlay blur dissolves → dashboard revealed
|
||||
- **Learnings for future iterations:**
|
||||
- framer-motion can animate backdropFilter and backgroundColor on a motion.div via the animate prop
|
||||
- The onComplete timeout (600ms) must match the overlay dissolve duration, not the card fade duration
|
||||
- Card fade (400ms) finishes before overlay dissolve (600ms), creating a layered reveal effect
|
||||
- WebkitBackdropFilter needs to be animated alongside backdropFilter for Safari
|
||||
---
|
||||
|
||||
## 2026-02-15 - US-008
|
||||
- Added @keyframes login-pulse in index.css: scale 1→1.03→1 over 3s cycle (1.5s animation built into keyframe percentages with 1.5s pause)
|
||||
- Added .login-pulse-active class that applies the animation infinitely
|
||||
- Hover removes animation via CSS rule (.login-pulse-active:hover { animation: none })
|
||||
- Button gets login-pulse-active class when canLogin && !buttonPressed
|
||||
- prefers-reduced-motion: .login-pulse-active { animation: none } in reduced motion media query
|
||||
- Button opacity 0.6→1.0 transition preserved (existing behavior)
|
||||
- Button still receives keyboard focus when enabled (existing behavior)
|
||||
- Files changed: src/index.css, src/components/LoginScreen.tsx
|
||||
- Verified in browser: button has login-pulse animation running (3s ease-in-out infinite), class applied correctly
|
||||
- **Learnings for future iterations:**
|
||||
- Used keyframe percentages (0%,60%,100% at scale(1), 30% at scale(1.03)) to build pause into a single animation rather than animation-delay
|
||||
- CSS handles hover removal — no need for buttonHovered state in the class condition
|
||||
- buttonPressed removes the class entirely (not just pauses), which is cleaner
|
||||
---
|
||||
|
||||
## 2026-02-15 - US-007
|
||||
- Reworked connection status indicator: LED dot 6px→10px with glow box-shadow, text 10px→12px
|
||||
- Removed independent 2000ms connectionTimeout timer
|
||||
- Added useEffect that transitions to green 500ms after typingComplete becomes true
|
||||
- Added animated trailing dots cycling '.', '..', '...' every 500ms while connecting
|
||||
- Initial state: red LED + red text "Awaiting secure connection" with animated dots
|
||||
- Connected state: green LED + green text "Secure connection established, awaiting login"
|
||||
- 300ms smooth transition for color and box-shadow between states
|
||||
- prefers-reduced-motion: no dot cycling, instant state changes
|
||||
- Files changed: src/components/LoginScreen.tsx
|
||||
- Verified in browser: red indicator with cycling dots visible during typing, transitions to green after typing completes
|
||||
- **Learnings for future iterations:**
|
||||
- dotCount state cycles 0→1→2→3→0 (4 states: no dots, '.', '..', '...') via modulo arithmetic
|
||||
- Connection transition is now tied to typingComplete state, not an arbitrary timer
|
||||
- The dot interval cleanup needs to happen in both the dedicated useEffect and the main cleanup
|
||||
- LED glow uses rgba with 0.4 alpha for subtle effect matching project shadow conventions
|
||||
---
|
||||
|
||||
## 2026-02-15 - US-006
|
||||
- Rendered DashboardLayout (wrapped in DetailPanelProvider) behind LoginScreen during login phase in App.tsx
|
||||
- Changed LoginScreen overlay from solid #1A2B2A background to semi-transparent rgba(240, 245, 244, 0.7) with backdrop-filter: blur(20px)
|
||||
- Dashboard is non-interactive during login (overlay captures pointer events via fixed inset-0 z-50)
|
||||
- After login click, phase transitions to 'pmr' and overlay is removed from DOM, dashboard becomes interactive
|
||||
- Files changed: src/App.tsx, src/components/LoginScreen.tsx
|
||||
- Verified in browser: blur overlay shows dashboard content behind login card, login click transitions to interactive dashboard
|
||||
- **Learnings for future iterations:**
|
||||
- App.tsx phase rendering changed from exclusive (one phase at a time) to overlapping (login + pmr render DashboardLayout)
|
||||
- DetailPanelProvider now wraps DashboardLayout for both 'login' and 'pmr' phases — condition is `(phase === 'login' || phase === 'pmr')`
|
||||
- LoginScreen already had `fixed inset-0 z-50` which makes it a full-viewport overlay — just needed background/blur changes
|
||||
- WebkitBackdropFilter needed for Safari compatibility alongside backdropFilter
|
||||
---
|
||||
|
||||
## 2026-02-15 - US-005
|
||||
- Replaced Home icon with CvmisLogo (size={24}, static/no animation) in TopBar.tsx
|
||||
- Removed Home from lucide-react import (Search still used)
|
||||
- Imported CvmisLogo component
|
||||
- Files changed: src/components/TopBar.tsx
|
||||
- Verified in browser: logo renders correctly with teal/amber/green capsule colors, fits TopBar height
|
||||
- **Learnings for future iterations:**
|
||||
- TopBar uses inline styles throughout, consistent with LoginScreen pattern
|
||||
- Search is the only remaining lucide-react icon in TopBar.tsx
|
||||
- CvmisLogo default `animated=false` means no animation prop needed for static usage
|
||||
---
|
||||
|
||||
## 2026-02-15 - US-004
|
||||
- Rebranded login from "CareerRecord PMR" to "CVMIS" with subtitle "CV Management Information System"
|
||||
- Replaced Shield icon with CvmisLogo component (animated=true, responsive cssHeight)
|
||||
- Added `cssHeight` prop to CvmisLogo for CSS clamp-based responsive sizing: clamp(48px, 4vw, 64px)
|
||||
- Increased startLoginSequence delay from 400ms to 1500ms to let logo animation complete before typing begins
|
||||
- prefers-reduced-motion: keeps original 400ms delay since logo renders instantly
|
||||
- Fixed lint warning: added prefersReducedMotion to useEffect dependency array
|
||||
- Files changed: src/components/LoginScreen.tsx, src/components/CvmisLogo.tsx
|
||||
- **Learnings for future iterations:**
|
||||
- CvmisLogo `size` prop is numeric (SVG height attribute) — use `cssHeight` string prop for CSS clamp values
|
||||
- Logo animation is 1000ms total (500ms rise + 500ms fan-out) — typing delay must account for this
|
||||
- The committed LoginScreen from US-003 still had Shield icon — US-003 only committed responsive sizing, not branding changes
|
||||
---
|
||||
|
||||
## 2026-02-15 - US-003
|
||||
- Responsive card: width clamp(320px,28vw,480px), maxWidth calc(100vw-32px), padding clamp(24px,2.5vw,40px)
|
||||
- Replaced hardcoded colors with CSS variables: --surface, --bg-dashboard, --accent, --text-secondary, --text-tertiary
|
||||
- Input fields: #E4EDEB default border, var(--accent) focus border, var(--bg-dashboard) inactive bg
|
||||
- Font sizes: labels clamp(12px,1vw,14px), inputs clamp(13px,1.1vw,15px), button clamp(14px,1.1vw,16px)
|
||||
- Card shadow: 0 1px 2px rgba(26,43,42,0.05) matching project shadow tokens
|
||||
- Files changed: src/components/LoginScreen.tsx
|
||||
- **Learnings for future iterations:**
|
||||
- No --border-card CSS variable exists in index.css — use #E4EDEB directly
|
||||
- LoginScreen uses inline styles throughout, not Tailwind classes (except for focus-visible ring on button)
|
||||
- The card used className="bg-white" which needed to be replaced with inline style for consistency
|
||||
---
|
||||
|
||||
## 2026-02-15 - US-002
|
||||
- Created CvmisLogo.tsx component with inlined SVG paths from cvmis-logo.svg
|
||||
- Three capsule groups: capsule-rx (teal #0b7979), capsule-terminal (amber #d97706), capsule-data (green #059669)
|
||||
- Props: size (height px), animated (boolean, default false), className (optional)
|
||||
- Framer Motion animation: Phase 1 (rise 500ms) — green data capsule scales from 0, Phase 2 (fan-out 500ms) — all three appear
|
||||
- prefers-reduced-motion: skips animation, renders final state immediately
|
||||
- Files changed: src/components/CvmisLogo.tsx (new)
|
||||
- **Learnings for future iterations:**
|
||||
- The SVG uses viewBox="0 0 600 506" with internal g transform scale(0.05,-0.05) — keep this coordinate system intact
|
||||
- framer-motion's useReducedMotion() hook is the simplest way to handle reduced motion
|
||||
- transform-origin in SVG needs px units when using framer-motion on g elements
|
||||
---
|
||||
|
||||
## 2026-02-15 - US-001
|
||||
- Changed initial Phase state from 'boot' to 'login' in App.tsx line 47
|
||||
- Files changed: src/App.tsx
|
||||
- **Learnings for future iterations:**
|
||||
- Phase state is a simple string union type on line 47 of App.tsx
|
||||
- US-010 will revert this exact change back to 'boot'
|
||||
---
|
||||
|
||||
Reference in New Issue
Block a user