RESPONSIVE BREAKPOINT SYSTEM - MIGRATION GUIDE Date: 2024-12-18 SUMMARY RSX now uses a custom two-tier responsive breakpoint system that replaces Bootstrap's default breakpoints (xs/sm/md/lg/xl/xxl) with semantic device names. This provides clearer intent (mobile vs desktop) and finer control (phone/tablet/desktop-sm/desktop-md/desktop-lg). All existing media queries using hardcoded pixel values or Bootstrap breakpoint variables should be migrated to use the new SCSS mixins. Bootstrap's default responsive utility classes (.col-md-*, .d-lg-*, etc.) no longer work. Applications must use the new breakpoint names. BREAKPOINT DEFINITIONS Tier 1 - Semantic (Mobile vs Desktop): mobile 0 - 1023px Phone + tablet combined desktop 1024px+ All desktop sizes Tier 2 - Granular Device Classes: phone 0 - 799px Phones, small handhelds tablet 800 - 1023px Tablets portrait, large phones landscape desktop-sm 1024 - 1699px Laptops, small monitors desktop-md 1700 - 2199px Standard monitors (1080p-1440p) desktop-lg 2200px+ Large/ultra-wide monitors, 4K The 1024px mobile/desktop boundary was chosen because tablets in landscape (iPad Pro at 1366px) should receive desktop layouts. VARIABLE CONVENTION IMPORTANT: Only 4 breakpoint variables are defined. Each variable represents where that breakpoint STARTS. Max values are calculated inline in mixins as ($next-breakpoint - 0.02px). DO NOT create -min/-max suffix variables like $bp-desktop-sm-max. This is the old convention and is incorrect. Correct: $bp-tablet: 800px; $bp-desktop: 1024px; $bp-desktop-md: 1700px; $bp-desktop-lg: 2200px; Wrong (old convention - do not use): $bp-phone-max: 799px; $bp-tablet-min: 800px; $bp-tablet-max: 1023px; $bp-desktop-sm-min: 1024px; $bp-desktop-sm-max: 1699px; ... etc AFFECTED FILES Framework files (already updated): rsx/theme/vendor/bootstrap5/scss/_variables.scss rsx/theme/variables.scss rsx/theme/responsive.scss (new file) All bundle definition files (*_bundle.php) Application files requiring migration: Any *.scss file with @media queries using pixel values Any template using Bootstrap responsive classes (.col-md-*, .d-lg-*, etc.) CHANGES REQUIRED 1. Bootstrap Assertion Disabled ------------------------------------------------------------------------- In rsx/theme/vendor/bootstrap5/scss/_variables.scss, the ascending assertion for $grid-breakpoints has been commented out to allow semantic aliases (mobile/phone share 0, desktop/desktop-sm share 1024px): Line 494-495: // RSX: Disabled to allow semantic breakpoint aliases // @include _assert-ascending($grid-breakpoints, "$grid-breakpoints"); If you have a custom Bootstrap checkout, apply this change. 2. Create responsive.scss ------------------------------------------------------------------------- Create rsx/theme/responsive.scss with mixins and utility classes. Full file contents: // ========================================================================== // RSX RESPONSIVE SYSTEM // ========================================================================== // // Two-tier responsive breakpoint system for consistent mobile/desktop handling. // // TIER 1 - Semantic (Mobile vs Desktop): // Mobile: 0 - 1023px (phone + tablet combined) // Desktop: 1024px+ (all desktop sizes) // // TIER 2 - Granular Device Classes: // phone: 0 - 799px Phones, small handhelds // tablet: 800 - 1023px Tablets portrait, large phones landscape // desktop-sm: 1024 - 1699px Laptops, small monitors // desktop-md: 1700 - 2199px Standard monitors (1080p-1440p) // desktop-lg: 2200px+ Large/ultra-wide monitors, 4K // // BREAKPOINTS: 800, 1024, 1700, 2200 // No -min/-max variables; calculate max as ($next-breakpoint - 0.02px) // // USAGE: // SCSS Mixins: // @include mobile { ... } // 0 - 1023px // @include desktop { ... } // 1024px+ // @include phone { ... } // 0 - 799px // @include tablet { ... } // 800 - 1023px // @include desktop-sm { ... } // 1024 - 1699px // @include desktop-md { ... } // 1700 - 2199px // @include desktop-lg { ... } // 2200px+ // // Bootstrap Utility Classes (auto-generated from $grid-breakpoints): // .col-mobile-6, .col-desktop-4, .col-tablet-12 // .d-mobile-none, .d-desktop-block, .d-phone-flex // .p-mobile-2, .p-desktop-4, .m-tablet-3 // ... and all other Bootstrap responsive utilities // // Custom Utility Classes: // .mobile-only, .desktop-only // .phone-only, .tablet-only // .hide-mobile, .hide-desktop, .hide-phone, .hide-tablet // // ========================================================================== // ========================================================================== // TIER 1 MIXINS: Mobile vs Desktop // ========================================================================== @mixin mobile { @media (max-width: #{$bp-desktop - 0.02px}) { @content; } } @mixin desktop { @media (min-width: $bp-desktop) { @content; } } // ========================================================================== // TIER 2 MIXINS: Device-specific ("only" ranges) // ========================================================================== @mixin phone { @media (max-width: #{$bp-tablet - 0.02px}) { @content; } } @mixin tablet { @media (min-width: $bp-tablet) and (max-width: #{$bp-desktop - 0.02px}) { @content; } } @mixin desktop-sm { @media (min-width: $bp-desktop) and (max-width: #{$bp-desktop-md - 0.02px}) { @content; } } @mixin desktop-md { @media (min-width: $bp-desktop-md) and (max-width: #{$bp-desktop-lg - 0.02px}) { @content; } } @mixin desktop-lg { @media (min-width: $bp-desktop-lg) { @content; } } // ========================================================================== // TIER 2 MIXINS: "and up" ranges // ========================================================================== @mixin tablet-up { @media (min-width: $bp-tablet) { @content; } } @mixin tablet-down { @media (max-width: #{$bp-desktop - 0.02px}) { @content; } } @mixin desktop-sm-up { @media (min-width: $bp-desktop) { @content; } } @mixin desktop-md-up { @media (min-width: $bp-desktop-md) { @content; } } @mixin desktop-lg-up { @media (min-width: $bp-desktop-lg) { @content; } } // ========================================================================== // UTILITY CLASSES // ========================================================================== // Tier 1: Mobile/Desktop visibility .mobile-only { @include desktop { display: none !important; } } .desktop-only { @include mobile { display: none !important; } } .hide-mobile { @include mobile { display: none !important; } } .hide-desktop { @include desktop { display: none !important; } } // Tier 2: Device-specific visibility .phone-only { @include tablet-up { display: none !important; } } .tablet-only { @include phone { display: none !important; } @include desktop { display: none !important; } } .hide-phone { @include phone { display: none !important; } } .hide-tablet { @include tablet { display: none !important; } } // ========================================================================== // CSS CUSTOM PROPERTIES (for JavaScript access) // ========================================================================== // Usage: // const bp = parseInt(getComputedStyle(document.documentElement).getPropertyValue('--bp-desktop')); // const isDesktop = window.innerWidth >= bp; :root { --bp-tablet: #{$bp-tablet}; // 800px --bp-desktop: #{$bp-desktop}; // 1024px --bp-desktop-md: #{$bp-desktop-md}; // 1700px --bp-desktop-lg: #{$bp-desktop-lg}; // 2200px } 3. Update variables.scss ------------------------------------------------------------------------- Add breakpoint variables and Bootstrap $grid-breakpoints override. Add to rsx/theme/variables.scss (replace any existing breakpoint vars): // ========================================================================== // RESPONSIVE BREAKPOINTS // ========================================================================== // Two-tier system: Tier 1 (Mobile vs Desktop) and Tier 2 (Granular devices) // See rsx/theme/responsive.scss for mixins and utilities // Breakpoints define where each tier STARTS // No -min/-max suffixes; calculate max inline as ($next-breakpoint - 0.02px) // // phone: 0px (implicit, viewport < $bp-tablet) // tablet: 800px (viewport >= 800 and < $bp-desktop) // desktop-sm: 1024px (viewport >= 1024 and < $bp-desktop-md) // desktop-md: 1700px (viewport >= 1700 and < $bp-desktop-lg) // desktop-lg: 2200px (viewport >= 2200) $bp-tablet: 800px; $bp-desktop: 1024px; $bp-desktop-md: 1700px; $bp-desktop-lg: 2200px; // Bootstrap grid breakpoints override // Allows: .col-mobile-6, .col-phone-12, .col-tablet-8, .col-desktop-4, etc. // Note: mobile/phone share 0, desktop/desktop-sm share 1024px (assertion disabled) $grid-breakpoints: ( xs: 0, mobile: 0, phone: 0, tablet: 800px, desktop: 1024px, desktop-sm: 1024px, desktop-md: 1700px, desktop-lg: 2200px ); Remove any old breakpoint variables like: $breakpoint-sm, $breakpoint-md, $breakpoint-lg, $breakpoint-xl, $breakpoint-2xl $bp-phone-max, $bp-tablet-min, $bp-tablet-max, $bp-desktop-sm-min, etc. 4. Update Bundle Definitions ------------------------------------------------------------------------- Add responsive.scss to every bundle after variables.scss but before Bootstrap. Before: 'include' => [ 'rsx/theme/variables.scss', 'Bootstrap5_Src_Bundle', ... ] After: 'include' => [ 'rsx/theme/variables.scss', 'rsx/theme/responsive.scss', // ADD THIS LINE 'Bootstrap5_Src_Bundle', ... ] Apply to all bundle files: - rsx/app/frontend/frontend_bundle.php - rsx/app/login/login_bundle.php - rsx/app/root/root_bundle.php - rsx/app/dev/dev_bundle.php - rsx/app/backend/backend_bundle.php - Any other *_bundle.php files 5. Migrate SCSS Media Queries ------------------------------------------------------------------------- Replace hardcoded media queries with mixins. Common patterns: Before: @media (max-width: 767px) { ... } After: @include phone { ... } Before: @media (max-width: 768px) { ... } After: @include mobile { ... } Before: @media (max-width: 991.98px) { ... } After: @include mobile { ... } Before: @media (max-width: 1199px) { ... } After: @include mobile { ... } Before: @media (min-width: 768px) { ... } After: @include tablet-up { ... } Before: @media (min-width: 992px) { ... } After: @include desktop { ... } Before: @media (min-width: 1200px) { ... } After: @include desktop { ... } Example file migration: Before: .My_Component { padding: 1rem; @media (max-width: 991.98px) { padding: 0.5rem; } } After: .My_Component { padding: 1rem; @include mobile { padding: 0.5rem; } } Remove any local breakpoint variables like: $mobile-breakpoint: 991.98px; 6. Migrate Bootstrap Utility Classes in Templates ------------------------------------------------------------------------- Replace Bootstrap's default breakpoint names with RSX names. Grid columns: Before: class="col-12 col-md-6 col-lg-4" After: class="col-mobile-12 col-tablet-6 col-desktop-4" Before: class="col-sm-6 col-xl-3" After: class="col-phone-6 col-desktop-md-3" Display utilities: Before: class="d-none d-md-block" After: class="d-none d-tablet-block" or class="d-mobile-none d-tablet-block" Before: class="d-lg-none" After: class="d-desktop-none" Spacing: Before: class="p-2 p-md-4" After: class="p-2 p-tablet-4" or class="p-mobile-2 p-desktop-4" Common mappings: Bootstrap RSX equivalent --------- -------------- xs (use base class, no suffix) sm phone or mobile md tablet or mobile lg desktop xl desktop or desktop-md xxl desktop-lg CONFIGURATION No additional configuration required beyond the file changes above. Optional: If you need JavaScript access to breakpoints: const styles = getComputedStyle(document.documentElement); const desktopMin = parseInt(styles.getPropertyValue('--bp-desktop')); const isMobile = window.innerWidth < desktopMin; VERIFICATION 1. Compile bundles and verify no SCSS errors: php artisan rsx:bundle:compile Frontend_Bundle 2. Check that responsive utility classes work: - Add class="mobile-only" to an element, verify hidden on desktop - Add class="col-mobile-12 col-desktop-6" to a div, verify layout changes 3. Search for orphaned Bootstrap classes: grep -r "col-sm-\|col-md-\|col-lg-\|col-xl-\|d-sm-\|d-md-\|d-lg-\|d-xl-" rsx/ 4. Search for hardcoded media queries that should be migrated: grep -r "@media.*max-width.*px\|@media.*min-width.*px" rsx/app rsx/theme/components DOCUMENTATION Man page created: rsx/resource/man/responsive.txt View with: php artisan rsx:man responsive CLAUDE.md and docs.dist/CLAUDE.dist.md updated with: - Responsive Breakpoints section under SCSS Component-First Architecture - Tier 1 and Tier 2 definitions - Mixin and class name reference - Warning about Bootstrap default classes not working PROJECT MAN PAGES The rsx:man command now also searches rsx/resource/man/ for project-specific documentation. Project man pages override framework man pages of the same name. Created: rsx/resource/man/CLAUDE.md (guidelines for project man pages) REFERENCE php artisan rsx:man responsive - Full responsive system documentation php artisan rsx:man scss - SCSS organization conventions php artisan rsx:man man - Man page system documentation