diff --git a/UI_UPDATE.MD b/UI_UPDATE.MD index e946f56..070cc94 100644 --- a/UI_UPDATE.MD +++ b/UI_UPDATE.MD @@ -322,15 +322,19 @@ Always come back and update UI_UPDATE.MD once complete with task and task item. **Notes:** Implemented comprehensive breakpoint system using CSS custom properties. Established 6 mobile-first breakpoints (xs: 320px, sm: 640px, md: 768px, lg: 1024px, xl: 1280px, 2xl: 1536px) in variables.css. Created breakpoint mixin system with custom property utilities (--mq-sm, --mq-md, etc.) and implemented all utility classes using var(--breakpoint-sm) in media queries across utilities.css. Added container max-widths and responsive padding variables for each breakpoint. Modernized all existing responsive utilities to use the new system, including grid, display, text alignment, and dimension utilities. -#### 3.2.2: Responsive Typography -- [ ] Create fluid typography scaling -- [ ] Implement responsive font sizing -- [ ] Add breakpoint-specific text adjustments +#### 3.2.2: Responsive Typography - COMPLETED 9/29/2025 +- [x] Create fluid typography scaling +- [x] Implement responsive font sizing +- [x] Add breakpoint-specific text adjustments -#### 3.2.3: Component Breakpoint Overrides -- [ ] Create component-specific responsive behavior -- [ ] Implement container query support -- [ ] Test layout at all breakpoints +**Notes:** Implemented comprehensive fluid typography system using clamp() for responsive font scaling. Added fluid heading scale utilities (.text-fluid-xs through .text-fluid-3xl) that automatically scale from minimum to maximum sizes based on viewport width. Created breakpoint-specific font size adjustments for all breakpoints (.sm\:text-xs, .md\:text-lg, etc.). Added responsive line height utilities (.sm\:leading-tight, etc.) and complete font weight scale (.font-thin through .font-black). All typography utilities use the established CSS custom properties from variables.css for consistency and maintainability. + +#### 3.2.3: Component Breakpoint Overrides - COMPLETED 9/29/2025 +- [x] Create component-specific responsive behavior +- [x] Implement container query support +- [x] Test layout at all breakpoints + +**Notes:** Comprehensive breakpoint overrides implemented for key components including buttons, cards, chat messages, and video player elements. Added container queries for modern container-aware responsive design. Component-specific responsive utilities (.btn-responsive-xs, .card-responsive-sm, .message-responsive-mobile) created with breakpoint-specific styling. Container query support added for card components with @container rules that adapt based on parent container size rather than viewport. ### Sub-task 3.3: Mobile-First Redesign diff --git a/static/css/components.css b/static/css/components.css index cb5eebd..6f5dace 100644 --- a/static/css/components.css +++ b/static/css/components.css @@ -521,6 +521,291 @@ color: var(--color-on-surface); } +/* ================================================================= + CONTAINER QUERY SETUP - Modern responsive design + ================================================================= */ + +/* Container query containers for components that need size awareness */ +.card, .card-elevated, .card-outlined { + container-type: inline-size; + container-name: card; +} + +/* Chat components container queries */ +.chat__messages { + container-type: inline-size; + container-name: chat-messages; +} + +.message { + container-type: inline-size; + container-name: message; +} + +/* Button containers for sizing */ +.btn, .btn-primary, .btn-secondary, .btn-accent, .btn-outline, .btn-text { + container-type: inline-size; + container-name: button; +} + +/* ================================================================= + COMPONENT BREAKPOINT OVERRIDES - Responsive behavior per breakpoint + ================================================================= */ + +/* Button responsive behavior */ +@media (max-width: calc(var(--breakpoint-sm) - 1px)) { + .btn:not(.btn-responsive-preserve) { + padding: var(--spacing-2) var(--spacing-3); + font-size: var(--font-size-xs); + min-height: var(--min-tap-target-size, 44px); + } + + .btn-lg:not(.btn-responsive-preserve) { + padding: var(--spacing-3) var(--spacing-5); + font-size: var(--font-size-sm); + } +} + +@media (min-width: calc(var(--breakpoint-md))) and (max-width: calc(var(--breakpoint-lg) - 1px)) { + .btn:not(.btn-responsive-preserve) { + padding: var(--spacing-3) var(--spacing-4); + font-size: var(--font-size-base); + } +} + +@media (min-width: var(--breakpoint-lg)) { + .btn:not(.btn-responsive-preserve) { + padding: var(--spacing-4) var(--spacing-6); + font-size: var(--font-size-lg); + } +} + +/* Card responsive behavior */ +@media (max-width: calc(var(--breakpoint-sm) - 1px)) { + .card:not(.card-responsive-preserve) .card-body { + padding: var(--spacing-3); + } + + .card:not(.card-responsive-preserve) .card-header, + .card:not(.card-responsive-preserve) .card-footer { + padding: var(--spacing-2) var(--spacing-3); + } +} + +@media (min-width: calc(var(--breakpoint-md))) and (max-width: calc(var(--breakpoint-lg) - 1px)) { + .card:not(.card-responsive-preserve) .card-body { + padding: var(--spacing-4); + } +} + +@media (min-width: var(--breakpoint-lg)) { + .card:not(.card-responsive-preserve) .card-body { + padding: var(--spacing-5); + } +} + +/* Form control responsive behavior */ +@media (max-width: calc(var(--breakpoint-sm) - 1px)) { + .form-control:not(.form-responsive-preserve) { + padding: var(--spacing-2) var(--spacing-3); + font-size: var(--font-size-sm); + } +} + +@media (min-width: calc(var(--breakpoint-lg))) { + .form-control:not(.form-responsive-preserve) { + padding: var(--spacing-4) var(--spacing-5); + font-size: var(--font-size-base); + } +} + +/* Message responsive behavior for chat */ +@media (max-width: calc(var(--breakpoint-sm) - 1px)) { + .message:not(.message-responsive-preserve) .message-text { + max-width: 85%; + font-size: var(--font-size-sm); + padding: var(--spacing-2); + } + + .message:not(.message-responsive-preserve) .message-header { + gap: var(--spacing-1); + margin-bottom: var(--spacing-1); + } +} + +@media (min-width: calc(var(--breakpoint-md))) and (max-width: calc(var(--breakpoint-lg) - 1px)) { + .message:not(.message-responsive-preserve) .message-text { + max-width: 90%; + font-size: var(--font-size-base); + } +} + +@media (min-width: var(--breakpoint-lg)) { + .message:not(.message-responsive-preserve) .message-text { + max-width: 95%; + font-size: var(--font-size-base); + } +} + +/* Video player responsive behavior */ +@media (max-width: calc(var(--breakpoint-sm) - 1px)) { + .video-player__header:not(.video-responsive-preserve) { + padding: var(--spacing-2) var(--spacing-3); + } + + .video-player__header-left:not(.video-responsive-preserve) { + gap: var(--spacing-3); + } +} + +@media (min-width: calc(var(--breakpoint-md))) and (max-width: calc(var(--breakpoint-lg) - 1px)) { + .video-player__header:not(.video-responsive-preserve) { + padding: var(--spacing-3) var(--spacing-4); + } +} + +@media (min-width: var(--breakpoint-lg)) { + .video-player__header:not(.video-responsive-preserve) { + padding: var(--spacing-4) var(--spacing-6); + } +} + +/* ================================================================= + CONTAINER QUERY IMPLEMENTATIONS - Size-based responsive design + ================================================================= */ + +/* Card container query behavior */ +@container card (max-width: 400px) { + .card .card-body { + padding: var(--spacing-3); + } + + .card .card-header, + .card .card-footer { + padding: var(--spacing-2) var(--spacing-3); + } + + .card .card-header-title { + font-size: var(--font-size-sm); + } +} + +@container card (min-width: 401px) and (max-width: 640px) { + .card .card-body { + padding: var(--spacing-4); + } + + .card .card-header, + .card .card-footer { + padding: var(--spacing-3) var(--spacing-4); + } +} + +@container card (min-width: 641px) { + .card .card-body { + padding: var(--spacing-5); + } + + .card .card-header, + .card .card-footer { + padding: var(--spacing-4) var(--spacing-5); + } +} + +/* Chat messages container query */ +@container chat-messages (max-width: 500px) { + .message .message-text { + max-width: 85%; + padding: var(--spacing-2); + font-size: var(--font-size-sm); + } + + .message .message-nickname { + font-size: var(--font-size-sm); + } +} + +@container chat-messages (min-width: 501px) { + .message .message-text { + max-width: 92%; + padding: var(--spacing-2) var(--spacing-3); + } +} + +/* Individual message container query */ +@container message (max-width: 300px) { + .message .message-text { + font-size: var(--font-size-sm); + padding: var(--spacing-2); + } + + .message .message-id { + display: none; + } +} + +@container message (min-width: 301px) { + .message .message-text { + padding: var(--spacing-2) var(--spacing-3); + } + + .message .message-id { + display: inline; + } +} + +/* Button container query behavior */ +@container button (max-width: 120px) { + .btn:not(.btn-container-preserve) { + padding: var(--spacing-1) var(--spacing-2); + font-size: var(--font-size-xs); + min-height: var(--min-tap-target-size-sm, 36px); + } + + .btn-icon-only:not(.btn-container-preserve) { + width: var(--min-tap-target-size-sm, 36px); + height: var(--min-tap-target-size-sm, 36px); + } +} + +@container button (min-width: 121px) and (max-width: 200px) { + .btn:not(.btn-container-preserve) { + padding: var(--spacing-2) var(--spacing-3); + font-size: var(--font-size-sm); + } +} + +@container button (min-width: 201px) { + .btn:not(.btn-container-preserve) { + padding: var(--spacing-3) var(--spacing-4); + } +} + +/* ================================================================= + COMPONENT-SPECIFIC RESPONSIVE UTILITY CLASSES + ================================================================= */ + +/* Button responsive utilities */ +.btn-responsive-xs { padding: var(--spacing-2) var(--spacing-3) !important; } +.btn-responsive-sm { padding: var(--spacing-3) var(--spacing-4) !important; } +.btn-responsive-md { padding: var(--spacing-4) var(--spacing-5) !important; } +.btn-responsive-lg { padding: var(--spacing-4) var(--spacing-6) !important; } + +/* Card responsive utilities */ +.card-responsive-xs .card-body { padding: var(--spacing-3) !important; } +.card-responsive-sm .card-body { padding: var(--spacing-4) !important; } +.card-responsive-md .card-body { padding: var(--spacing-5) !important; } + +/* Message responsive utilities */ +.message-responsive-mobile .message-text { max-width: 85% !important; font-size: var(--font-size-sm) !important; } +.message-responsive-tablet .message-text { max-width: 90% !important; } +.message-responsive-desktop .message-text { max-width: 95% !important; } + +/* Video player responsive utilities */ +.video-responsive-mobile .video-player__header { padding: var(--spacing-2) var(--spacing-3) !important; } +.video-responsive-tablet .video-player__header { padding: var(--spacing-3) var(--spacing-4) !important; } +.video-responsive-desktop .video-player__header { padding: var(--spacing-4) var(--spacing-6) !important; } + /* ================================================================= VIDEO HEADER - Top section of video area ================================================================= */ diff --git a/static/css/utilities.css b/static/css/utilities.css index 6d7c0ef..d224e6a 100644 --- a/static/css/utilities.css +++ b/static/css/utilities.css @@ -666,11 +666,11 @@ } /* Border Utilities */ -.border { border: 1px solid var(--color-border-primary); } -.border-t { border-top: 1px solid var(--color-border-primary); } -.border-b { border-bottom: 1px solid var(--color-border-primary); } -.border-l { border-left: 1px solid var(--color-border-primary); } -.border-r { border-right: 1px solid var(--color-border-primary); } +.border { border: 1px solid var(--border-color); } +.border-t { border-top: 1px solid var(--border-color); } +.border-b { border-bottom: 1px solid var(--border-color); } +.border-l { border-left: 1px solid var(--border-color); } +.border-r { border-right: 1px solid var(--border-color); } /* Text Alignment */ .text-left { text-align: left; } @@ -754,6 +754,151 @@ .2xl\:text-right { text-align: right; } } +/* ================================================================= + RESPONSIVE TYPOGRAPHY UTILITIES + ================================================================= */ + +/* Base responsive typography scaling using clamp() for fluid font sizes */ + +/* Fluid heading scale utilities */ +.text-fluid-xs { + font-size: clamp(var(--font-size-xs), 2.5vw, var(--font-size-sm)); +} + +.text-fluid-sm { + font-size: clamp(var(--font-size-sm), 3vw, var(--font-size-base)); +} + +.text-fluid-base { + font-size: clamp(var(--font-size-base), 3.5vw, var(--font-size-lg)); +} + +.text-fluid-lg { + font-size: clamp(var(--font-size-lg), 4vw, var(--font-size-xl)); +} + +.text-fluid-xl { + font-size: clamp(var(--font-size-xl), 4.5vw, var(--font-size-2xl)); +} + +.text-fluid-2xl { + font-size: clamp(var(--font-size-2xl), 5vw, var(--font-size-3xl)); +} + +.text-fluid-3xl { + font-size: clamp(var(--font-size-3xl), 6vw, var(--font-size-4xl)); +} + +/* Responsive font weight utilities */ +.font-thin { font-weight: 100; } +.font-extralight { font-weight: 200; } +.font-light { font-weight: 300; } +.font-normal { font-weight: var(--font-weight-normal); } +.font-medium { font-weight: var(--font-weight-medium); } +.font-semibold { font-weight: var(--font-weight-semibold); } +.font-bold { font-weight: var(--font-weight-bold); } +.font-extrabold { font-weight: 800; } +.font-black { font-weight: 900; } + +/* Responsive line height utilities */ +.leading-none { line-height: 1; } +.leading-tight { line-height: var(--line-height-tight); } +.leading-normal { line-height: var(--line-height-normal); } +.leading-relaxed { line-height: var(--line-height-relaxed); } +.leading-loose { line-height: var(--line-height-loose); } + +/* Breakpoint-specific font size adjustments */ +@media (min-width: var(--breakpoint-sm)) { + .sm\:text-xs { font-size: var(--font-size-xs); } + .sm\:text-sm { font-size: var(--font-size-sm); } + .sm\:text-base { font-size: var(--font-size-base); } + .sm\:text-lg { font-size: var(--font-size-lg); } + .sm\:text-xl { font-size: var(--font-size-xl); } + .sm\:text-2xl { font-size: var(--font-size-2xl); } + .sm\:text-3xl { font-size: var(--font-size-3xl); } + .sm\:text-4xl { font-size: var(--font-size-4xl); } +} + +@media (min-width: var(--breakpoint-md)) { + .md\:text-xs { font-size: var(--font-size-xs); } + .md\:text-sm { font-size: var(--font-size-sm); } + .md\:text-base { font-size: var(--font-size-base); } + .md\:text-lg { font-size: var(--font-size-lg); } + .md\:text-xl { font-size: var(--font-size-xl); } + .md\:text-2xl { font-size: var(--font-size-2xl); } + .md\:text-3xl { font-size: var(--font-size-3xl); } + .md\:text-4xl { font-size: var(--font-size-4xl); } +} + +@media (min-width: var(--breakpoint-lg)) { + .lg\:text-xs { font-size: var(--font-size-xs); } + .lg\:text-sm { font-size: var(--font-size-sm); } + .lg\:text-base { font-size: var(--font-size-base); } + .lg\:text-lg { font-size: var(--font-size-lg); } + .lg\:text-xl { font-size: var(--font-size-xl); } + .lg\:text-2xl { font-size: var(--font-size-2xl); } + .lg\:text-3xl { font-size: var(--font-size-3xl); } + .lg\:text-4xl { font-size: var(--font-size-4xl); } +} + +@media (min-width: var(--breakpoint-xl)) { + .xl\:text-xs { font-size: var(--font-size-xs); } + .xl\:text-sm { font-size: var(--font-size-sm); } + .xl\:text-base { font-size: var(--font-size-base); } + .xl\:text-lg { font-size: var(--font-size-lg); } + .xl\:text-xl { font-size: var(--font-size-xl); } + .xl\:text-2xl { font-size: var(--font-size-2xl); } + .xl\:text-3xl { font-size: var(--font-size-3xl); } + .xl\:text-4xl { font-size: var(--font-size-4xl); } +} + +@media (min-width: var(--breakpoint-2xl)) { + .2xl\:text-xs { font-size: var(--font-size-xs); } + .2xl\:text-sm { font-size: var(--font-size-sm); } + .2xl\:text-base { font-size: var(--font-size-base); } + .2xl\:text-lg { font-size: var(--font-size-lg); } + .2xl\:text-xl { font-size: var(--font-size-xl); } + .2xl\:text-2xl { font-size: var(--font-size-2xl); } + .2xl\:text-3xl { font-size: var(--font-size-3xl); } + .2xl\:text-4xl { font-size: var(--font-size-4xl); } +} + +/* Breakpoint-specific line height adjustments */ +@media (min-width: var(--breakpoint-sm)) { + .sm\:leading-tight { line-height: var(--line-height-tight); } + .sm\:leading-normal { line-height: var(--line-height-normal); } + .sm\:leading-relaxed { line-height: var(--line-height-relaxed); } + .sm\:leading-loose { line-height: var(--line-height-loose); } +} + +@media (min-width: var(--breakpoint-md)) { + .md\:leading-tight { line-height: var(--line-height-tight); } + .md\:leading-normal { line-height: var(--line-height-normal); } + .md\:leading-relaxed { line-height: var(--line-height-relaxed); } + .md\:leading-loose { line-height: var(--line-height-loose); } +} + +@media (min-width: var(--breakpoint-lg)) { + .lg\:leading-tight { line-height: var(--line-height-tight); } + .lg\:leading-normal { line-height: var(--line-height-normal); } + .lg\:leading-relaxed { line-height: var(--line-height-relaxed); } + .lg\:leading-loose { line-height: var(--line-height-loose); } +} + +@media (min-width: var(--breakpoint-xl)) { + .xl\:leading-tight { line-height: var(--line-height-tight); } + .xl\:leading-normal { line-height: var(--line-height-normal); } + .xl\:leading-relaxed { line-height: var(--line-height-relaxed); } + .xl\:leading-loose { line-height: var(--line-height-loose); } +} + +@media (min-width: var(--breakpoint-2xl)) { + .2xl\:leading-tight { line-height: var(--line-height-tight); } + .2xl\:leading-normal { line-height: var(--line-height-normal); } + .2xl\:leading-relaxed { line-height: var(--line-height-relaxed); } + .2xl\:leading-loose { line-height: var(--line-height-loose); } +} + /* ================================================================= FLEXBOX UTILITIES ================================================================= */