From 5dd7dcb27b72878bd54e9a5ce2f0e2b83679803f Mon Sep 17 00:00:00 2001 From: Lucas 'Paperboy' Rose-Winters Date: Thu, 23 Oct 2025 18:33:01 +1100 Subject: [PATCH] feat(dashboard): improve widget scaling and fix attribute scrollbar MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement responsive scaling for info widgets and fix sizing issues: **1. Container-Responsive Info Widgets (style.css)** **Calendar Widget:** - Add flexbox layout (height: 100%, flex-direction: column) - Change font sizes from vw to rem for better scaling - Calendar day now uses clamp(1.5rem, 2.5rem, 3.5rem) to fill space - Add flex-shrink: 0 to top/year, flex: 1 to day **Weather Widget:** - Add container wrapper (height: 100%, justify-content: space-around) - Weather icon scales with container: clamp(2rem, 8vh, 4rem) - Forecast text uses rem instead of vw - Both elements marked flex-shrink: 0 **Temperature Widget:** - Container fills height with flexbox centering - Thermometer scales: clamp(4rem, 60%, 8rem) height - Tube/bulb use percentages (40% width, 70% height) - Text value uses rem units **Clock Widget:** - Container with space-around layout - Clock scales with container: clamp(3rem, 60%, 6rem) - Clock hands use percentages of clock size - Time text uses rem units **Location Widget:** - Container flexbox with column layout - Map background uses flex: 1 (was fixed 1.875rem) - Map marker scales: clamp(1.5rem, 4vh, 3rem) - Location text uses rem units **2. Fix Attributes Widget Scrollbar (style.css)** - Line 966: Change grid-auto-rows: 1fr to grid-auto-rows: minmax(0, 1fr) - Allows rows to shrink below natural size to fit container - Prevents overflow when widget manually positioned after auto-arrange **3. Widget Size Constraints (widget files)** - userAttributesWidget.js: Change minSize from {w:1, h:2} to {w:2, h:2} - Enforces 2x2 minimum as requested - Prevents cramped 1-column layout - infoBoxWidgets.js: Change location minSize from {w:2, h:2} to {w:1, h:2} - Allows narrow 1x2 layout for space-constrained dashboards - Only widget that didn't fit on desktop screen **Technical Details:** - All info widgets now use rem units instead of vw for text - Flexbox scaling ensures widgets fill their containers beautifully - Percentage-based sizing for thermometer/clock internal elements - clamp() used for min/preferred/max sizing across resolutions - minmax(0, 1fr) fixes classic CSS grid overflow issue **User-Reported Issues Fixed:** ✅ Info widgets scale to fill containers instead of fixed sizes ✅ Attributes widget no longer shows scrollbar in 2x2 (manual or auto-arranged) ✅ Location widget works in both 1x2 and 2x2 layouts ✅ All widgets maintain readability across different panel widths Related: Dashboard v2, Epic 2, Phase 3.2 --- .../dashboard/widgets/infoBoxWidgets.js | 2 +- .../dashboard/widgets/userAttributesWidget.js | 2 +- style.css | 104 ++++++++++++------ 3 files changed, 71 insertions(+), 37 deletions(-) diff --git a/src/systems/dashboard/widgets/infoBoxWidgets.js b/src/systems/dashboard/widgets/infoBoxWidgets.js index d183b28..f4accce 100644 --- a/src/systems/dashboard/widgets/infoBoxWidgets.js +++ b/src/systems/dashboard/widgets/infoBoxWidgets.js @@ -401,7 +401,7 @@ export function registerLocationWidget(registry, dependencies) { name: 'Location', icon: '📍', description: 'Map with location display', - minSize: { w: 2, h: 2 }, + minSize: { w: 1, h: 2 }, defaultSize: { w: 2, h: 2 }, requiresSchema: false, diff --git a/src/systems/dashboard/widgets/userAttributesWidget.js b/src/systems/dashboard/widgets/userAttributesWidget.js index 7e4bf46..1bd0e87 100644 --- a/src/systems/dashboard/widgets/userAttributesWidget.js +++ b/src/systems/dashboard/widgets/userAttributesWidget.js @@ -31,7 +31,7 @@ export function registerUserAttributesWidget(registry, dependencies) { icon: '⚔️', description: 'Classic RPG stats (STR, DEX, CON, INT, WIS, CHA)', category: 'user', - minSize: { w: 1, h: 2 }, + minSize: { w: 2, h: 2 }, defaultSize: { w: 2, h: 2 }, requiresSchema: false, diff --git a/style.css b/style.css index 7e43655..a28f58b 100644 --- a/style.css +++ b/style.css @@ -963,7 +963,7 @@ body:has(.rpg-panel.rpg-position-left) #sheld { grid-template-columns: repeat(2, 1fr); gap: clamp(2px, 0.4vh, 4px); flex: 1; - grid-auto-rows: 1fr; + grid-auto-rows: minmax(0, 1fr); min-height: 0; overflow-y: auto; overflow-x: hidden; @@ -1369,31 +1369,38 @@ body:has(.rpg-panel.rpg-position-left) #sheld { box-shadow: 0 4px 12px var(--rpg-shadow); } -/* Location widget - flexible height */ +/* Location Widget */ .rpg-location-widget { height: 100%; + display: flex; + flex-direction: column; + padding: 0.25rem; } /* Calendar Widget */ .rpg-calendar-widget { padding: 0.188em; + height: 100%; + display: flex; + flex-direction: column; } .rpg-calendar-top { background: var(--rpg-highlight); color: var(--rpg-bg); - font-size: clamp(0.5vw, 0.55vw, 0.6vw); + font-size: clamp(0.6rem, 0.7rem, 0.8rem); font-weight: bold; padding: 0.125em 0.375em; border-radius: 3px 3px 0 0; width: 100%; text-align: center; + flex-shrink: 0; } .rpg-calendar-day { background: rgba(255, 255, 255, 0.1); color: var(--rpg-text); - font-size: clamp(0.8vw, 1vw, 1.2vw); + font-size: clamp(1.5rem, 2.5rem, 3.5rem); font-weight: bold; padding: 0.25em; width: 100%; @@ -1404,24 +1411,35 @@ body:has(.rpg-panel.rpg-position-left) #sheld { display: flex; align-items: center; justify-content: center; + min-height: 0; } .rpg-calendar-year { - font-size: clamp(0.5vw, 0.55vw, 0.6vw); + font-size: clamp(0.6rem, 0.7rem, 0.8rem); color: var(--rpg-text); opacity: 0.7; margin-top: 0.062em; + flex-shrink: 0; +} + +/* Weather Widget */ +.rpg-weather-widget { + height: 100%; + display: flex; + flex-direction: column; + justify-content: space-around; + align-items: center; + padding: 0.5rem; } -/* Weather Widget Icon */ .rpg-weather-icon { - font-size: clamp(18px, 3.5vw, 24px); + font-size: clamp(2rem, 8vh, 4rem); filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.5)); flex-shrink: 0; } .rpg-weather-forecast { - font-size: clamp(0.4vw, 0.5vw, 0.6vw); + font-size: clamp(0.7rem, 0.9rem, 1.1rem); text-align: center; margin: 0; font-weight: 600; @@ -1433,6 +1451,7 @@ body:has(.rpg-panel.rpg-position-left) #sheld { max-width: 100%; overflow: hidden; text-overflow: ellipsis; + flex-shrink: 0; } .rpg-weather-forecast.rpg-editable { @@ -1441,22 +1460,28 @@ body:has(.rpg-panel.rpg-position-left) #sheld { /* Temperature Widget - Thermometer */ .rpg-temp-widget { - gap: 0.188em; + height: 100%; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + gap: 0.5rem; } .rpg-thermometer { position: relative; - width: 1.25rem; - height: 2.5rem; + width: clamp(1.5rem, 2rem, 3rem); + height: clamp(4rem, 60%, 8rem); display: flex; flex-direction: column; align-items: center; + flex-shrink: 1; } .rpg-thermometer-tube { position: relative; - width: 0.5rem; - height: 1.75rem; + width: 40%; + height: 70%; background: rgba(255, 255, 255, 0.1); border: 2px solid var(--rpg-border); border-radius: 0.625em 0.625em 0 0; @@ -1475,8 +1500,9 @@ body:has(.rpg-panel.rpg-position-left) #sheld { .rpg-thermometer-bulb { position: absolute; bottom: 0; - width: 0.875rem; - height: 0.875rem; + width: 70%; + height: 0; + padding-bottom: 70%; background: var(--rpg-highlight); border: 2px solid var(--rpg-border); border-radius: 50%; @@ -1484,25 +1510,33 @@ body:has(.rpg-panel.rpg-position-left) #sheld { } .rpg-temp-value { - font-size: clamp(0.5vw, 0.6vw, 0.7vw); + font-size: clamp(0.7rem, 0.9rem, 1.1rem); font-weight: bold; color: var(--rpg-text); text-align: center; + flex-shrink: 0; } /* Clock Widget */ .rpg-clock-widget { - gap: 0.188em; + height: 100%; + display: flex; + flex-direction: column; + justify-content: space-around; + align-items: center; + gap: 0.5rem; } .rpg-clock { - width: 2.625rem; - height: 2.625rem; + width: clamp(3rem, 60%, 6rem); + height: clamp(3rem, 60%, 6rem); + aspect-ratio: 1 / 1; border-radius: 50%; background: rgba(0, 0, 0, 0.4); border: 3px solid var(--rpg-border); box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.5); position: relative; + flex-shrink: 1; } .rpg-clock-face { @@ -1522,22 +1556,22 @@ body:has(.rpg-panel.rpg-position-left) #sheld { } .rpg-clock-hour { - width: 0.188rem; - height: 0.75rem; - margin-left: -0.094em; + width: 3%; + height: 28%; + margin-left: -1.5%; opacity: 0.9; } .rpg-clock-minute { - width: 0.125rem; - height: 1rem; - margin-left: -0.062em; + width: 2%; + height: 38%; + margin-left: -1%; } .rpg-clock-center { position: absolute; - width: 0.312rem; - height: 0.312rem; + width: 6%; + height: 6%; background: var(--rpg-highlight); border-radius: 50%; top: 50%; @@ -1547,17 +1581,18 @@ body:has(.rpg-panel.rpg-position-left) #sheld { } .rpg-time-value { - font-size: clamp(0.5vw,0.6vw,0.7vw); + font-size: clamp(0.7rem, 0.9rem, 1.1rem); font-weight: bold; color: var(--rpg-text); + flex-shrink: 0; } /* Location Widget - Map */ .rpg-map-bg { width: 100%; - height: 1.875rem; + flex: 1; + min-height: 3rem; margin: 0; - margin-bottom: 0 !important; background: linear-gradient(45deg, rgba(255,255,255,0.05) 25%, transparent 25%), linear-gradient(-45deg, rgba(255,255,255,0.05) 25%, transparent 25%), @@ -1573,12 +1608,10 @@ body:has(.rpg-panel.rpg-position-left) #sheld { justify-content: center; position: relative; overflow: hidden; - flex-shrink: 0; - margin-bottom: 0.188em; } .rpg-map-marker { - font-size: 1vw; + font-size: clamp(1.5rem, 4vh, 3rem); filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8)); animation: markerPulse 2s ease-in-out infinite; } @@ -1589,16 +1622,17 @@ body:has(.rpg-panel.rpg-position-left) #sheld { } .rpg-location-text { - font-size: clamp(0.5vw, 0.6vw, 0.7vw); + font-size: clamp(0.7rem, 0.9rem, 1.1rem); font-weight: bold; color: var(--rpg-text); text-align: center; line-height: 1.2; - padding: 0.125em 0.25em; + padding: 0.5rem 0.25rem; margin: 0; word-wrap: break-word; overflow-wrap: break-word; hyphens: auto; + flex-shrink: 0; } /* Character Status Cards */