2.2.5
Fix UI issues
This commit is contained in:
@@ -395,8 +395,14 @@
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
/* ── Mobile header layout ────────────────────────────────────────────── */
|
||||
@media (max-width: 640px) {
|
||||
/* ── Stacked header layout (mobile + tablet) ─────────────────────────────
|
||||
The desktop 3-column grid (left | dial | why-panel) needs ~960px of
|
||||
viewport to fit: the location/search box is 300px, the "Why it feels like"
|
||||
panel ~300px, plus the 220px dial and gaps. Below that the rigid columns
|
||||
can't shrink and the why-panel overflows off the right edge, so we stack
|
||||
everything into one centred column — matching where the glance rail also
|
||||
drops below the table. */
|
||||
@media (max-width: 960px) {
|
||||
.utci-header {
|
||||
grid-template-columns: 1fr; /* single column — stack title, dial, search */
|
||||
grid-template-areas: none; /* flow in DOM order: left, dial, selector, why */
|
||||
@@ -414,7 +420,7 @@
|
||||
}
|
||||
|
||||
.header-right {
|
||||
align-items: flex-start; /* left-align location on mobile */
|
||||
align-items: center; /* centre the "Why it feels like" panel under the dial */
|
||||
}
|
||||
|
||||
.utci-title {
|
||||
|
||||
@@ -210,9 +210,9 @@
|
||||
}
|
||||
|
||||
.profile-btn {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
flex: none; /* never shrink below 80px — the row scrolls instead */
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
flex: none; /* never shrink below 100px — the row scrolls instead */
|
||||
padding: 0;
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
@@ -958,8 +958,8 @@
|
||||
|
||||
/* Slightly smaller cards on mobile */
|
||||
.profile-btn {
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
flex: none;
|
||||
}
|
||||
|
||||
|
||||
+22
-10
@@ -447,12 +447,12 @@
|
||||
Used for the Places / Activities / Work triggers in the profile bar. */
|
||||
|
||||
.profile-scroll .cs-wrap {
|
||||
height: 80px;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.cs-btn.profile-card {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
padding: 0;
|
||||
position: relative;
|
||||
flex-direction: column;
|
||||
@@ -490,21 +490,32 @@
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 24px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
/* Block (not flex) so text-overflow:ellipsis cuts cleanly on the trailing
|
||||
edge — e.g. "Forest / Wo…" — instead of a flex item clipping both sides.
|
||||
line-height vertically centres the single line; text-align centres short
|
||||
labels while long ones ellipsise against the right pad that clears the
|
||||
arrow. */
|
||||
display: block;
|
||||
line-height: 24px;
|
||||
text-align: center;
|
||||
font-size: 10px;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
background: rgba(30,18,8,0.52);
|
||||
color: #fff;
|
||||
padding: 0 14px 0 4px;
|
||||
padding: 0 17px 0 6px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* When the label overflows it must read left-to-right so the ellipsis lands on
|
||||
the end ("Forest / Wo…"); centred overflow would clip the start too. */
|
||||
.cs-btn.profile-card.on .cs-btn-label {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.cs-btn.profile-card .cs-arrow {
|
||||
position: absolute;
|
||||
right: 6px;
|
||||
@@ -540,11 +551,11 @@
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.profile-scroll .cs-wrap {
|
||||
height: 68px;
|
||||
height: 80px;
|
||||
}
|
||||
.cs-btn.profile-card {
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
}
|
||||
.cs-btn.profile-card .cs-arrow {
|
||||
bottom: 7px;
|
||||
@@ -555,6 +566,7 @@
|
||||
}
|
||||
.cs-btn.profile-card .cs-btn-label {
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
font-size: 9px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,6 +63,19 @@ function weatherGradient(r, g, b) {
|
||||
return `linear-gradient(135deg, ${light} 0%, ${mid} 60%, ${dark} 100%)`;
|
||||
}
|
||||
|
||||
// Active-tab variant: a more solid (less pastelised) version of the weather
|
||||
// colour, drawn as a radial gradient whose strong colour sits at the outer
|
||||
// edge and softens toward a lighter centre — so the hue reads as radiating
|
||||
// inward from the outside of the tab.
|
||||
function weatherGradientActive(r, g, b) {
|
||||
const blend = (c) => Math.round(c + (255 - c) * 0.42);
|
||||
const [mr, mg, mb] = [blend(r), blend(g), blend(b)];
|
||||
const lighten = (c) => Math.min(255, Math.round(c + (255 - c) * 0.38));
|
||||
const center = `rgb(${lighten(mr)},${lighten(mg)},${lighten(mb)})`;
|
||||
const edge = `rgb(${mr},${mg},${mb})`;
|
||||
return `radial-gradient(circle at 50% 50%, ${center} 0%, ${center} 28%, ${edge} 100%)`;
|
||||
}
|
||||
|
||||
export function DayTabs({
|
||||
days,
|
||||
selectedDay, setSelectedDay,
|
||||
@@ -328,6 +341,7 @@ export function DayTabs({
|
||||
: modalCloudCat === 'wispy' ? [200, 180, 130]
|
||||
: [220, 190, 50];
|
||||
const wBg = weatherGradient(wR, wG, wB);
|
||||
const wBgActive = weatherGradientActive(wR, wG, wB);
|
||||
const wText = '#2a1d10';
|
||||
|
||||
return html`
|
||||
@@ -347,7 +361,7 @@ export function DayTabs({
|
||||
? `${band.label} · SunScope Extra unlocks day ${i + 1}`
|
||||
: `${band.label} · day ${i + 1} of 14`}
|
||||
style=${{
|
||||
background: wBg,
|
||||
background: isActive ? wBgActive : wBg,
|
||||
color: wText,
|
||||
border: '1px solid #c9b08a',
|
||||
opacity: locked ? 0.5 : 1,
|
||||
@@ -361,7 +375,7 @@ export function DayTabs({
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
height: isActive ? '5px' : '4px',
|
||||
height: isActive ? '8px' : '7px',
|
||||
background: band.bg,
|
||||
borderTop: '1px solid #c9b08a',
|
||||
borderRadius: '0 0 2px 2px',
|
||||
@@ -387,6 +401,7 @@ export function DayTabs({
|
||||
marginTop: '2px',
|
||||
letterSpacing: 0,
|
||||
textTransform: 'none',
|
||||
textShadow: '0 0 14px rgba(255,255,255,0.85), 0 0 11px rgba(255,255,255,0.7), 0 0 8px rgba(255,255,255,0.6), 0 0 5px rgba(255,255,255,0.5)',
|
||||
}}>
|
||||
<span style=${{ color: '#c0622a', fontWeight: 600 }}>${dayHi}°</span>
|
||||
<span style=${{ opacity: 0.5 }}> / </span>
|
||||
|
||||
@@ -339,17 +339,17 @@ export function useAppState() {
|
||||
const activityValue = activeProfile === 'outdoors' && activityVariantKeys.includes(outdoorsVariant)
|
||||
? outdoorsVariant
|
||||
: 'off';
|
||||
const activityLabel = activityOptions.find((o) => o.value === activityValue)?.label;
|
||||
const activityLabel = activityOptions.find((o) => o.value === activityValue)?.name;
|
||||
const placeValue = activeProfile === 'outdoors' && placeVariantKeys.includes(outdoorsVariant)
|
||||
? outdoorsVariant
|
||||
: 'off';
|
||||
const placeLabel = placeOptions.find((o) => o.value === placeValue)?.label;
|
||||
const placeLabel = placeOptions.find((o) => o.value === placeValue)?.name;
|
||||
const workValue = activeProfile === 'farming'
|
||||
? 'farming'
|
||||
: activeProfile === 'outdoors' && workVariantKeys.includes(outdoorsVariant)
|
||||
? outdoorsVariant
|
||||
: 'off';
|
||||
const workLabel = workOptions.find((o) => o.value === workValue)?.label;
|
||||
const workLabel = workOptions.find((o) => o.value === workValue)?.name;
|
||||
|
||||
// ── 6. TABLE REFS ────────────────────────────────────────────────────
|
||||
const headStickyRef = useRef(null);
|
||||
|
||||
+4
-4
@@ -27,7 +27,7 @@
|
||||
css/ui.css Status banners, legend, about, footer, responsive
|
||||
════════════════════════════════════════════════════════════════════════ */
|
||||
|
||||
@import "./css/base.css";
|
||||
@import "./css/header.css";
|
||||
@import "./css/table.css";
|
||||
@import "./css/ui.css";
|
||||
@import "./css/base.css?v=15g";
|
||||
@import "./css/header.css?v=15g";
|
||||
@import "./css/table.css?v=15g";
|
||||
@import "./css/ui.css?v=15g";
|
||||
|
||||
+1
-1
@@ -70,7 +70,7 @@
|
||||
|
||||
<link rel="preconnect" href="https://api.open-meteo.com" crossorigin />
|
||||
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>☀️</text></svg>" />
|
||||
<link rel="stylesheet" href="./assets/sunscope.css?v=15b">
|
||||
<link rel="stylesheet" href="./assets/sunscope.css?v=15g">
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
||||
Reference in New Issue
Block a user