1277 lines
39 KiB
CSS
1277 lines
39 KiB
CSS
/* ════════════════════════════════════════════════════════════════════════
|
|
table.css — Day tabs, filter profiles, column toggles, hourly table,
|
|
now-row and night-row decorations.
|
|
════════════════════════════════════════════════════════════════════════ */
|
|
|
|
/* ── 5. DAY TABS (today / tomorrow / etc.) ─────────────────────────── */
|
|
/* Note: each tab's background colour comes from inline styles in
|
|
app.js (the confidence bands). This file only handles spacing,
|
|
typography, and the active-tab underline. */
|
|
|
|
/* Wrapper that hosts the scrollable strip, edge fades, and chevrons. */
|
|
.utci-day-tabs-wrap {
|
|
position: relative;
|
|
margin-top: 12px;
|
|
margin-bottom: 15px;
|
|
border: 1px solid #c9b08a;
|
|
}
|
|
|
|
/* Edge fade gradients — only show when there's content to scroll to. */
|
|
.utci-day-tabs-wrap::before,
|
|
.utci-day-tabs-wrap::after {
|
|
content: '';
|
|
position: absolute;
|
|
top: 0;
|
|
bottom: 2px; /* leave the underline border visible */
|
|
width: 40px;
|
|
pointer-events: none;
|
|
z-index: 1;
|
|
opacity: 0;
|
|
transition: opacity 0.2s;
|
|
}
|
|
.utci-day-tabs-wrap::before {
|
|
left: 0;
|
|
background: linear-gradient(to right, #f5edd6 0%, rgba(245,237,214,0) 100%);
|
|
}
|
|
.utci-day-tabs-wrap::after {
|
|
right: 0;
|
|
background: linear-gradient(to left, #f5edd6 0%, rgba(245,237,214,0) 100%);
|
|
}
|
|
.utci-day-tabs-wrap.fade-left::before { opacity: 1; }
|
|
.utci-day-tabs-wrap.fade-right::after { opacity: 1; }
|
|
|
|
/* Chevron buttons — sit on top of the fades. */
|
|
.utci-day-scroll {
|
|
position: absolute;
|
|
top: 50%;
|
|
transform: translateY(-50%);
|
|
width: 30px;
|
|
height: 30px;
|
|
border-radius: 50%;
|
|
border: 1px solid #d4c0a0;
|
|
background: #fffcf2;
|
|
color: #6b4f2a;
|
|
font-size: 20px;
|
|
font-family: Fraunces, serif;
|
|
line-height: 1;
|
|
cursor: pointer;
|
|
z-index: 2;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 0 0 2px 0;
|
|
box-shadow: 0 1px 4px rgba(80,55,20,0.12);
|
|
transition: opacity 0.2s, background 0.15s, transform 0.15s;
|
|
}
|
|
.utci-day-scroll:hover {
|
|
background: #fef3dc;
|
|
}
|
|
.utci-day-scroll.left { left: -2px; }
|
|
.utci-day-scroll.right { right: -2px; }
|
|
.utci-day-scroll.hidden {
|
|
opacity: 0;
|
|
pointer-events: none;
|
|
}
|
|
|
|
.utci-day-tabs {
|
|
display: flex;
|
|
overflow-x: auto;
|
|
scroll-behavior: smooth;
|
|
scrollbar-width: none; /* Firefox */
|
|
-ms-overflow-style: none; /* old Edge */
|
|
}
|
|
.utci-day-tabs::-webkit-scrollbar {
|
|
display: none; /* Chrome/Safari */
|
|
}
|
|
|
|
.utci-day-tab {
|
|
flex: 1 0 auto;
|
|
padding: 12px 24px;
|
|
cursor: pointer;
|
|
font-family: Manrope, sans-serif;
|
|
font-size: 10px;
|
|
font-weight: 700;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.08em;
|
|
background: transparent;
|
|
border: 1px solid #c9b08a;
|
|
color: #b09870;
|
|
transition: color 0.2s, border-color 0.2s, background-color 0.2s, filter 0.15s;
|
|
}
|
|
|
|
.utci-day-tab + .utci-day-tab {
|
|
border-left: none;
|
|
}
|
|
|
|
/* Each tab's background is an inline per-day weather gradient, so we darken
|
|
the whole tab with a filter on hover (!important to beat the inline filter). */
|
|
.utci-day-tab:hover {
|
|
filter: brightness(0.93) !important;
|
|
}
|
|
|
|
.utci-day-tab.active {
|
|
color: #c8922a;
|
|
border-bottom-color: #c8922a;
|
|
}
|
|
|
|
/* The "Mon 12 May" date underneath each tab name */
|
|
.utci-day-date {
|
|
font-family: Fraunces, serif;
|
|
font-style: italic;
|
|
font-size: 13px;
|
|
text-transform: none;
|
|
letter-spacing: 0;
|
|
display: block;
|
|
margin-top: 3px;
|
|
color: inherit;
|
|
}
|
|
|
|
|
|
/* ── 5b. FILTER PROFILES (the "Profile: Basic Urban …" bar) ───────── */
|
|
|
|
.filter-profiles {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0;
|
|
margin-bottom: 0;
|
|
padding: 0px;
|
|
background: transparent;
|
|
border: none;
|
|
}
|
|
|
|
.filter-profiles-label {
|
|
font-family: Manrope, sans-serif;
|
|
font-size: 12px;
|
|
font-weight: 700;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.08em;
|
|
color: #7a5c2a;
|
|
margin-bottom: 6px;
|
|
white-space: nowrap;
|
|
text-align: center;
|
|
}
|
|
|
|
/* Single scrollable row of profile cards */
|
|
.profile-scroll {
|
|
display: flex;
|
|
flex-wrap: nowrap;
|
|
gap: 6px;
|
|
align-items: center;
|
|
pointer-events: none;
|
|
justify-content: center; /* centre when content fits */
|
|
justify-content: safe center; /* fall back to flex-start if it overflows */
|
|
overflow-x: auto;
|
|
overflow-y: auto; /* forced by browser when overflow-x is non-visible */
|
|
padding-bottom: 6px;
|
|
margin-bottom: 0;
|
|
scrollbar-width: none;
|
|
-ms-overflow-style: none;
|
|
padding-left: 4px; /* breathing room at left edge */
|
|
padding-right: 4px; /* breathing room at right edge */
|
|
}
|
|
.profile-scroll::-webkit-scrollbar { display: none; }
|
|
.profile-scroll > * { pointer-events: auto; }
|
|
|
|
/* Fade-edge wrapper — hosts the ::before/::after gradient overlays */
|
|
.profile-scroll-wrap {
|
|
position: relative;
|
|
width: 100%;
|
|
padding-top:8px;
|
|
padding-bottom:1px;
|
|
background-color: #fffcf2;
|
|
border-top: 1.5px solid #c9b08a;
|
|
border-left: 1.5px solid #c9b08a;
|
|
border-right: 1.5px solid #c9b08a;
|
|
border-bottom: 1.5px solid #c9b08a;
|
|
}
|
|
|
|
.profile-scroll-wrap::before,
|
|
.profile-scroll-wrap::after {
|
|
content: '';
|
|
position: absolute;
|
|
top: 0;
|
|
bottom: 0;
|
|
width: 52px;
|
|
pointer-events: none;
|
|
opacity: 0;
|
|
transition: opacity 0.2s ease;
|
|
z-index: 2;
|
|
}
|
|
.profile-scroll-wrap::before {
|
|
left: 0;
|
|
background: linear-gradient(to right, #f5edd6 10%, transparent 100%);
|
|
}
|
|
.profile-scroll-wrap::after {
|
|
right: 0;
|
|
background: linear-gradient(to left, #f5edd6 10%, transparent 100%);
|
|
}
|
|
.profile-scroll-wrap.fade-left::before { opacity: 1; }
|
|
.profile-scroll-wrap.fade-right::after { opacity: 1; }
|
|
|
|
.profile-scroll-chevron {
|
|
position: absolute;
|
|
top: 50%;
|
|
transform: translateY(-50%);
|
|
z-index: 3;
|
|
pointer-events: none;
|
|
color: #8a6a3a;
|
|
font-size: 18px;
|
|
line-height: 1;
|
|
opacity: 0;
|
|
transition: opacity 0.2s ease;
|
|
user-select: none;
|
|
}
|
|
.profile-scroll-chevron.left { left: 4px; }
|
|
.profile-scroll-chevron.right { right: 4px; }
|
|
|
|
.profile-scroll-wrap.fade-left .profile-scroll-chevron.left { opacity: 1; }
|
|
.profile-scroll-wrap.fade-right .profile-scroll-chevron.right { opacity: 1; }
|
|
|
|
/* Vertical rule separating general-use profiles from technical ones */
|
|
.profile-divider {
|
|
display: inline-block;
|
|
width: 1px;
|
|
align-self: stretch;
|
|
background: #c9b08a;
|
|
margin: 0 2px;
|
|
opacity: 0.6;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.profile-btn {
|
|
width: 100px;
|
|
height: 100px;
|
|
flex: none; /* never shrink below 100px — the row scrolls instead */
|
|
padding: 0;
|
|
position: relative;
|
|
display: inline-flex;
|
|
flex-direction: column;
|
|
align-items: stretch;
|
|
overflow: hidden;
|
|
cursor: pointer;
|
|
border: 1.5px solid #c9b08a;
|
|
background: transparent;
|
|
border-radius: 3px;
|
|
transition: border-color 0.15s, box-shadow 0.15s;
|
|
-webkit-user-select: none;
|
|
user-select: none;
|
|
}
|
|
|
|
.profile-btn-scene {
|
|
flex: 1;
|
|
background-size: cover;
|
|
background-position: center;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: 22px;
|
|
line-height: 1;
|
|
opacity: 0.7;
|
|
transition: opacity 0.2s;
|
|
}
|
|
|
|
.profile-btn:hover .profile-btn-scene {
|
|
opacity: 0.8;
|
|
}
|
|
|
|
.profile-btn.active .profile-btn-scene {
|
|
opacity: 1;
|
|
}
|
|
|
|
.profile-lock-badge {
|
|
position: absolute;
|
|
top: 4px;
|
|
right: 4px;
|
|
font-size: 11px;
|
|
line-height: 1;
|
|
pointer-events: none;
|
|
z-index: 1;
|
|
}
|
|
|
|
.profile-btn-label {
|
|
position: absolute;
|
|
bottom: 0;
|
|
left: 0;
|
|
right: 0;
|
|
height: 24px;
|
|
display: block;
|
|
line-height: 24px;
|
|
text-align: center;
|
|
font-family: Manrope, sans-serif;
|
|
font-size: 10px;
|
|
font-weight: 700;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.05em;
|
|
background: rgba(30,18,8,0.52);
|
|
color: #fff;
|
|
padding: 0 4px;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.profile-btn:hover {
|
|
border-color: #c8922a;
|
|
box-shadow: 0 1px 4px rgba(200,146,42,0.25);
|
|
}
|
|
|
|
.profile-btn.active {
|
|
border-color: #c8922a;
|
|
}
|
|
|
|
.profile-btn.active .profile-btn-label {
|
|
background: rgba(200,146,42,0.82);
|
|
color: #fff;
|
|
}
|
|
|
|
/* Tab strip above the profile scroll row */
|
|
.profile-tabs {
|
|
display: flex;
|
|
width: 360px;
|
|
margin-left: auto;
|
|
margin-right: auto;
|
|
margin-bottom: 0px;
|
|
}
|
|
.profile-tab {
|
|
flex: 1;
|
|
padding: 7px 4px;
|
|
background: transparent;
|
|
border: none;
|
|
border-bottom: 1.5px solid transparent;
|
|
border-left: 1.5px solid #f5edd6;
|
|
border-right: 1.5px solid #f5edd6;
|
|
border-top: 1.5px solid #f5edd6;
|
|
font-family: Manrope, sans-serif;
|
|
font-size: 11px;
|
|
font-weight: 700;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.06em;
|
|
color: #9a7a4a;
|
|
cursor: pointer;
|
|
transition: color 0.15s, border-color 0.15s;
|
|
white-space: nowrap;
|
|
border-radius:7px 7px 0px 0px;
|
|
z-index:1;
|
|
}
|
|
.profile-tab:hover {
|
|
color: #c8922a;
|
|
background: #f0e4c4;
|
|
}
|
|
.profile-tab.active {
|
|
color: #c8922a;
|
|
background-color: #fffcf2;
|
|
border-bottom-color: #fffcf2;
|
|
border-left: 1.5px solid #c9b08a;
|
|
border-right: 1.5px solid #c9b08a;
|
|
border-top: 1.5px solid #c9b08a;
|
|
margin-bottom: -1.5px;
|
|
}
|
|
|
|
|
|
/* ── 6. COLUMN TOGGLES (the "Columns: Hour Air RH ..." bar) ────────── */
|
|
|
|
.col-toggles {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 6px;
|
|
align-items: center;
|
|
margin-bottom: 0;
|
|
padding: 10px 14px;
|
|
background: #fdf8ee;
|
|
border: 1.5px solid #d4c0a0;
|
|
border-bottom: none;
|
|
}
|
|
|
|
.col-toggles-display-opts {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 12px;
|
|
margin-left: auto;
|
|
padding-left: 10px;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.col-toggles-label {
|
|
font-family: Manrope, sans-serif;
|
|
font-size: 12px;
|
|
font-weight: 700;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.08em;
|
|
color: #7a5c2a;
|
|
margin-right: 4px;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
/* The little pill buttons */
|
|
.col-toggle {
|
|
padding: 5px 13px;
|
|
cursor: pointer;
|
|
border: 1.5px solid #c9b08a;
|
|
background: #f5edd6;
|
|
color: #6b4228;
|
|
font-family: Manrope, sans-serif;
|
|
font-size: 12px;
|
|
font-weight: 700;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.06em;
|
|
transition: all 0.15s;
|
|
-webkit-user-select: none;
|
|
user-select: none;
|
|
}
|
|
|
|
.col-toggle:hover {
|
|
border-color: #c8922a;
|
|
color: #6b4f2a;
|
|
background: #fef3dc;
|
|
}
|
|
|
|
/* The "pressed-in" active look */
|
|
.col-toggle.on {
|
|
background: #c8922a;
|
|
border-color: #c8922a;
|
|
color: #fff;
|
|
}
|
|
|
|
/* ── COLUMN TOGGLE - group colour tints ─────────────────────────────────
|
|
Idle: light group tint bg + group text + group border.
|
|
Hover: darker tint matching th hover palette.
|
|
On: solid saturated group colour, white text.
|
|
On-hover: slightly darker solid. */
|
|
|
|
.col-toggle.grp-felt { background: rgba(223,243,236,0.50); color: #075c3a; border-color: rgba(7,92,58,0.35); }
|
|
.col-toggle.grp-surface { background: rgba(221,234,248,0.50); color: #0b3e72; border-color: rgba(11,62,114,0.30); }
|
|
.col-toggle.grp-ambient { background: rgba(236,234,227,0.50); color: #3c3a35; border-color: rgba(60,58,53,0.30); }
|
|
.col-toggle.grp-precip { background: rgba(247,228,238,0.50); color: #6b1e3a; border-color: rgba(107,30,58,0.30); }
|
|
.col-toggle.grp-sky { background: rgba(234,232,252,0.50); color: #352e7a; border-color: rgba(53,46,122,0.30); }
|
|
.col-toggle.grp-wind { background: rgba(250,230,224,0.50); color: #6a2210; border-color: rgba(106,34,16,0.30); }
|
|
.col-toggle.grp-airqual { background: rgba(229,240,216,0.50); color: #244408; border-color: rgba(36,68,8,0.30); }
|
|
.col-toggle.grp-solar { background: rgba(250,234,204,0.50); color: #5a3004; border-color: rgba(90,48,4,0.30); }
|
|
|
|
.col-toggle.grp-felt:hover { background: rgba(213,233,226,0.80); color: #075c3a; border-color: rgba(7,92,58,0.55); }
|
|
.col-toggle.grp-surface:hover { background: rgba(211,224,238,0.80); color: #0b3e72; border-color: rgba(11,62,114,0.50); }
|
|
.col-toggle.grp-ambient:hover { background: rgba(226,224,217,0.80); color: #3c3a35; border-color: rgba(60,58,53,0.50); }
|
|
.col-toggle.grp-precip:hover { background: rgba(237,218,228,0.80); color: #6b1e3a; border-color: rgba(107,30,58,0.50); }
|
|
.col-toggle.grp-sky:hover { background: rgba(224,222,242,0.80); color: #352e7a; border-color: rgba(53,46,122,0.50); }
|
|
.col-toggle.grp-wind:hover { background: rgba(240,220,214,0.80); color: #6a2210; border-color: rgba(106,34,16,0.50); }
|
|
.col-toggle.grp-airqual:hover { background: rgba(219,230,206,0.80); color: #244408; border-color: rgba(36,68,8,0.50); }
|
|
.col-toggle.grp-solar:hover { background: rgba(240,224,194,0.80); color: #5a3004; border-color: rgba(90,48,4,0.50); }
|
|
|
|
.col-toggle.grp-felt.on { background: #0f9e63; border-color: #0f9e63; color: #fff; }
|
|
.col-toggle.grp-surface.on { background: #2672c8; border-color: #2672c8; color: #fff; }
|
|
.col-toggle.grp-ambient.on { background: #7a7870; border-color: #7a7870; color: #fff; }
|
|
.col-toggle.grp-precip.on { background: #b03060; border-color: #b03060; color: #fff; }
|
|
.col-toggle.grp-sky.on { background: #6058c8; border-color: #6058c8; color: #fff; }
|
|
.col-toggle.grp-wind.on { background: #b04030; border-color: #b04030; color: #fff; }
|
|
.col-toggle.grp-airqual.on { background: #4a8018; border-color: #4a8018; color: #fff; }
|
|
.col-toggle.grp-solar.on { background: #b07820; border-color: #b07820; color: #fff; }
|
|
|
|
.col-toggle.grp-felt.on:hover { background: #0c7d4e; border-color: #0c7d4e; color: #fff; }
|
|
.col-toggle.grp-surface.on:hover { background: #1e5aa0; border-color: #1e5aa0; color: #fff; }
|
|
.col-toggle.grp-ambient.on:hover { background: #5e5c56; border-color: #5e5c56; color: #fff; }
|
|
.col-toggle.grp-precip.on:hover { background: #8c264c; border-color: #8c264c; color: #fff; }
|
|
.col-toggle.grp-sky.on:hover { background: #4c48a8; border-color: #4c48a8; color: #fff; }
|
|
.col-toggle.grp-wind.on:hover { background: #8c3226; border-color: #8c3226; color: #fff; }
|
|
.col-toggle.grp-airqual.on:hover { background: #3a6412; border-color: #3a6412; color: #fff; }
|
|
.col-toggle.grp-solar.on:hover { background: #8c5e18; border-color: #8c5e18; color: #fff; }
|
|
|
|
/* ── Vehicle group: select + windows-open checkbox fused together ── */
|
|
.col-toggle-group {
|
|
display: inline-flex;
|
|
align-items: stretch;
|
|
gap: 0;
|
|
/* Collapse any whitespace-node gap between the cs-wrap span and cs-vent */
|
|
font-size: 0;
|
|
}
|
|
.col-toggle-group > * {
|
|
font-size: 12px; /* restore font size for children */
|
|
}
|
|
|
|
/* Remove the right border + radius on the cs-wrap/cs-btn so it butts
|
|
flush with the VentPill. The cs-wrap is the direct child, so we
|
|
target its inner cs-btn via the grouped-left class on the button. */
|
|
.col-toggle-group .cs-wrap {
|
|
display: inline-flex;
|
|
align-items: stretch;
|
|
}
|
|
.col-toggle-group .grouped-left {
|
|
border-right: none !important;
|
|
border-radius: 0 !important;
|
|
}
|
|
.col-toggle-group .cs-wrap:only-child .grouped-left,
|
|
.col-toggle-group .cs-wrap:last-child .grouped-left {
|
|
border-right: 1.5px solid #c9b08a !important;
|
|
border-radius: 0 !important;
|
|
}
|
|
|
|
|
|
/* ── 7. HOURLY TABLE ────────────────────────────────────────────────── */
|
|
|
|
.utci-table-wrap {
|
|
/* No overflow on this wrapper — having any overflow here would make
|
|
the wrapper a scroll container, which would break sticky-to-viewport
|
|
on the .utci-thead-sticky strip inside.
|
|
The body scroller (.utci-tbody-scroll) owns the horizontal scrollbar. */
|
|
border: 1.5px solid #c9b08a;
|
|
background: #fffcf2;
|
|
position: relative; /* needed for ::before / ::after pseudo-element indicators */
|
|
}
|
|
|
|
/* ── SCROLL INDICATORS ──────────────────────────────────────────────────
|
|
Fade + chevron overlays on the left/right edges of the table wrap.
|
|
They appear only when there is content to scroll in that direction,
|
|
driven by the scroll-fade-left / scroll-fade-right classes toggled by JS. */
|
|
.utci-table-wrap::before,
|
|
.utci-table-wrap::after {
|
|
content: '';
|
|
position: absolute;
|
|
top: 0;
|
|
bottom: 0;
|
|
width: 48px;
|
|
pointer-events: none;
|
|
opacity: 0;
|
|
transition: opacity 0.2s ease;
|
|
z-index: 6; /* above sticky header (z-index 5) */
|
|
}
|
|
|
|
/* Left fade — warm cream fading to transparent rightward */
|
|
.utci-table-wrap::before {
|
|
left: 0;
|
|
background: linear-gradient(to right, rgba(240,228,196,0.92) 0%, transparent 100%);
|
|
}
|
|
|
|
/* Right fade — warm cream fading to transparent leftward */
|
|
.utci-table-wrap::after {
|
|
right: 0;
|
|
background: linear-gradient(to left, rgba(240,228,196,0.92) 0%, transparent 100%);
|
|
}
|
|
|
|
.utci-table-wrap.scroll-fade-left::before { opacity: 1; }
|
|
.utci-table-wrap.scroll-fade-right::after { opacity: 1; }
|
|
|
|
/* Chevron arrows — sit on top of the fade, centred vertically */
|
|
.utci-table-wrap .utci-scroll-chevron {
|
|
position: absolute;
|
|
top: 50%;
|
|
transform: translateY(-50%);
|
|
z-index: 7;
|
|
pointer-events: none;
|
|
color: #8a6a3a;
|
|
font-size: 18px;
|
|
line-height: 1;
|
|
opacity: 0;
|
|
transition: opacity 0.2s ease;
|
|
user-select: none;
|
|
}
|
|
.utci-table-wrap .utci-scroll-chevron.left { left: 6px; }
|
|
.utci-table-wrap .utci-scroll-chevron.right { right: 6px; }
|
|
|
|
.utci-table-wrap.scroll-fade-left .utci-scroll-chevron.left { opacity: 1; }
|
|
.utci-table-wrap.scroll-fade-right .utci-scroll-chevron.right { opacity: 1; }
|
|
|
|
/* Grab cursor on the body scroller to hint drag-to-scroll */
|
|
.utci-tbody-scroll {
|
|
cursor: grab;
|
|
user-select: none; /* prevent text highlighting during drag */
|
|
-webkit-user-select: none;
|
|
}
|
|
.utci-tbody-scroll:active {
|
|
cursor: grabbing;
|
|
}
|
|
|
|
/* ── STICKY HEADER STRIP ────────────────────────────────────────────────
|
|
Sits above the body and locks to the top of the viewport while the
|
|
page scrolls. Has overflow:hidden so the inner .utci-thead-track can
|
|
be translateX'd by JS to follow the body's scrollLeft. */
|
|
.utci-thead-sticky {
|
|
position: sticky;
|
|
top: 0;
|
|
z-index: 5;
|
|
overflow: hidden;
|
|
background: #f0e4c4;
|
|
border-bottom: 2px solid #c9b08a;
|
|
box-shadow: 0 2px 5px rgba(74, 52, 32, 0.10);
|
|
}
|
|
|
|
/* On mobile the nav bar is fixed at 72px - sticky header must clear it */
|
|
@media (max-width: 640px) {
|
|
.utci-thead-sticky {
|
|
top: 72px;
|
|
}
|
|
|
|
/* Shrink the day-tab labels on phones so more days stay readable
|
|
within the viewport before the tab strip needs to scroll. */
|
|
.utci-day-tab {
|
|
font-size: 9px;
|
|
padding: 10px 12px;
|
|
}
|
|
|
|
.utci-day-date {
|
|
font-size: 12px;
|
|
}
|
|
}
|
|
|
|
/* The shifted track inside the sticky header — JS sets transform:translate3d
|
|
to keep its columns aligned with the body scroller's scrollLeft. */
|
|
.utci-thead-track {
|
|
will-change: transform;
|
|
}
|
|
|
|
/* Body scroller — owns the horizontal scrollbar for the whole table. */
|
|
.utci-tbody-scroll {
|
|
overflow-x: auto;
|
|
overflow-y: visible;
|
|
}
|
|
|
|
.utci-table {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
font-size: 14px;
|
|
/* Fixed layout so the explicit per-cell widths set by the JS width-sync
|
|
(see useLayoutEffect in app.js) are actually enforced. Without
|
|
this the browser's auto layout treats those widths as suggestions and
|
|
redistributes space, which makes the header and body columns drift
|
|
apart the further right you scroll. */
|
|
table-layout: fixed;
|
|
}
|
|
|
|
/* Column headings (Hour, Air, RH, Wind...).
|
|
NOTE: stickiness is handled by the .utci-thead-sticky wrapper, not
|
|
the <th> itself — see the new wrapper rules higher up. */
|
|
.utci-table th {
|
|
background: #f0e4c4;
|
|
color: #6b4f2a;
|
|
font-family: Manrope, sans-serif;
|
|
font-size: 12px;
|
|
text-align: center;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.07em;
|
|
font-weight: 700;
|
|
padding: 14px 12px;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
@media (max-width: 800px) {
|
|
.utci-table th {
|
|
font-size: 10px;
|
|
letter-spacing: 0.08em;
|
|
}
|
|
}
|
|
|
|
/* The Hour column aligns left, the rest align right */
|
|
.utci-table th:first-child,
|
|
.utci-table td:first-child {
|
|
text-align: left;
|
|
}
|
|
|
|
/* The "°C" / "m/s" etc. unit underneath each heading */
|
|
.utci-table th .col-unit {
|
|
display: block;
|
|
color: #c8922a;
|
|
font-size: 10px;
|
|
margin-top: 2px;
|
|
}
|
|
|
|
/* Environment modifier badge — shown in SunSoak th when non-default env active */
|
|
.col-env-badge {
|
|
display: block;
|
|
font-size: 9px;
|
|
font-weight: 700;
|
|
font-family: Manrope, sans-serif;
|
|
letter-spacing: 0.04em;
|
|
color: #a06828;
|
|
opacity: 0.85;
|
|
margin-top: 2px;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
/* col-unit header spans always visible - units toggle only affects body cells */
|
|
|
|
@media (max-width: 800px) {
|
|
.utci-table th .col-unit {
|
|
font-size: 9px;
|
|
}
|
|
}
|
|
|
|
.utci-table tbody tr {
|
|
border-bottom: 1px solid #ffffff;
|
|
transition: background 0.1s;
|
|
}
|
|
|
|
.utci-table tbody tr:hover {
|
|
background: #fef8ea;
|
|
}
|
|
|
|
.utci-table td {
|
|
padding: 10px 12px;
|
|
text-align: center;
|
|
font-family: JetBrains Mono, monospace;
|
|
font-variant-numeric: tabular-nums; /* stops digits jiggling between rows */
|
|
white-space: nowrap;
|
|
color: #4a3420;
|
|
/* Baseline minimum column width — the JS width-sync uses max(60, head,
|
|
body) so very-narrow data columns ("Air 5.0") still feel comfortable
|
|
to read instead of being squashed. */
|
|
min-width: 60px;
|
|
}
|
|
|
|
/* Subtle vertical column dividers — same pale cream as the row
|
|
dividers so the table reads as a soft grid, not a hard one. The
|
|
last column has no divider so it doesn't double-up with the
|
|
container border. */
|
|
.utci-table th:not(:last-child),
|
|
.utci-table td:not(:last-child) {
|
|
border-right: 1px solid #ffffff;
|
|
}
|
|
|
|
/* The Dir column is centered on both desktop and mobile so the
|
|
compass vane sits with even padding either side — especially
|
|
important on mobile where the compass label is hidden and there's
|
|
no text to balance the right-aligned content. */
|
|
.utci-table th.utci-dir-cell,
|
|
.utci-table td.utci-dir-cell {
|
|
text-align: center;
|
|
}
|
|
|
|
/* "Tight" header — for columns whose body content is narrower than
|
|
the default tracked-out header would suggest (Air, Pcpt). Reducing
|
|
the letter-spacing shrinks the heading's natural width so it stops
|
|
driving the column wider than the body needs. Right-aligned values */
|
|
.utci-table th.utci-tight-head {
|
|
letter-spacing: 0.04em;
|
|
}
|
|
|
|
/* ── CLICKABLE COLUMN HEADERS ───────────────────────────────────────────
|
|
.col-info-th makes every <th> show a pointer cursor and a subtle hover
|
|
tint to signal it can be clicked for a description popup. */
|
|
.utci-table th.col-info-th {
|
|
cursor: pointer;
|
|
transition: background 0.15s;
|
|
}
|
|
.utci-table th.col-info-th:hover {
|
|
background: #e8d8a8;
|
|
}
|
|
|
|
/* ── HOUR-INTERVAL SELECTOR ──────────────────────────────────────────────
|
|
Compact 1h/2h/3h/4h segmented control inside the "Hour" header. Buckets
|
|
the table into multi-hour rows (clock-aligned from midnight). Lives in the
|
|
header so it stays put while the body scrolls. */
|
|
.hour-interval {
|
|
display: flex;
|
|
justify-content: flex-start;
|
|
gap: 2px;
|
|
margin-top: 4px;
|
|
}
|
|
.hour-interval-btn {
|
|
font-family: Manrope, sans-serif;
|
|
font-size: 10px;
|
|
font-weight: 700;
|
|
line-height: 1;
|
|
padding: 3px 4px;
|
|
cursor: pointer;
|
|
border: 1px solid #c9b08a;
|
|
background: #f5edd6;
|
|
color: #6b4228;
|
|
border-radius: 3px;
|
|
transition: background 0.12s, border-color 0.12s, color 0.12s;
|
|
}
|
|
.hour-interval-btn:hover {
|
|
border-color: #c8922a;
|
|
background: #fef3dc;
|
|
}
|
|
.hour-interval-btn.on {
|
|
background: #c8922a;
|
|
border-color: #c8922a;
|
|
color: #fff;
|
|
}
|
|
|
|
/* ── COLUMN DESCRIPTION POPUP ───────────────────────────────────────────
|
|
Fixed-position card that appears below a clicked column header.
|
|
JS sets left/top via inline style (centred on the clicked th). */
|
|
.col-info-popup {
|
|
position: fixed; /* set by JS — stays in viewport regardless of scroll */
|
|
z-index: 200;
|
|
width: 260px;
|
|
max-height: 260px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
background: #fffcf2;
|
|
border: 1.5px solid #c9b08a;
|
|
border-radius: 6px;
|
|
box-shadow: 0 4px 16px rgba(74,52,32,0.18);
|
|
padding: 14px 16px 16px;
|
|
pointer-events: all;
|
|
}
|
|
/* Arrow points DOWN toward the column header (default — popup is above the th) */
|
|
.col-info-popup::after {
|
|
content: '';
|
|
position: absolute;
|
|
bottom: -7px;
|
|
left: var(--arrow-left, 50%);
|
|
width: 12px;
|
|
height: 12px;
|
|
background: #fffcf2;
|
|
border-right: 1.5px solid #c9b08a;
|
|
border-bottom: 1.5px solid #c9b08a;
|
|
transform: translateX(-50%) rotate(45deg);
|
|
}
|
|
/* Arrow points UP toward the column header (popup is below the th) */
|
|
.col-info-popup.col-info-popup--below::after {
|
|
bottom: auto;
|
|
top: -7px;
|
|
border-right: none;
|
|
border-bottom: none;
|
|
border-left: 1.5px solid #c9b08a;
|
|
border-top: 1.5px solid #c9b08a;
|
|
transform: translateX(-50%) rotate(45deg);
|
|
}
|
|
.col-info-title {
|
|
display: block;
|
|
font-family: Manrope, sans-serif;
|
|
font-size: 12px;
|
|
font-weight: 700;
|
|
color: #4a3420;
|
|
margin-bottom: 6px;
|
|
text-transform: none;
|
|
letter-spacing: 0;
|
|
}
|
|
.col-info-desc {
|
|
font-family: Manrope, sans-serif;
|
|
font-size: 12px;
|
|
color: #6b4f2a;
|
|
line-height: 1.5;
|
|
margin: 0;
|
|
overflow-y: auto; /* scrolls when text exceeds max-height cap */
|
|
flex: 1 1 auto;
|
|
}
|
|
.col-info-close {
|
|
position: absolute;
|
|
top: 6px;
|
|
right: 8px;
|
|
background: none;
|
|
border: none;
|
|
font-size: 16px;
|
|
color: #a08060;
|
|
cursor: pointer;
|
|
line-height: 1;
|
|
padding: 0 2px;
|
|
}
|
|
.col-info-close:hover {
|
|
color: #4a3420;
|
|
}
|
|
|
|
/* ── POPUP OPEN/CLOSE ANIMATION ─────────────────────────────────────────
|
|
The popup mounts/unmounts instantly in JS, so we animate it via a
|
|
scale + fade keyframe anchored to the arrow tip (transform-origin).
|
|
Above-the-target: origin is bottom-center. Below: top-center. */
|
|
@keyframes popup-open {
|
|
from { opacity: 0; transform: translateX(-50%) translateY(-100%) scaleY(0.6); }
|
|
to { opacity: 1; transform: translateX(-50%) translateY(-100%) scaleY(1); }
|
|
}
|
|
@keyframes popup-open-below {
|
|
from { opacity: 0; transform: translateX(-50%) scaleY(0.6); }
|
|
to { opacity: 1; transform: translateX(-50%) scaleY(1); }
|
|
}
|
|
|
|
.col-info-popup:not(.col-info-popup--below) {
|
|
transform-origin: bottom center;
|
|
animation: popup-open 0.22s cubic-bezier(0.34, 1.4, 0.64, 1) both;
|
|
}
|
|
.col-info-popup.col-info-popup--below {
|
|
transform-origin: top center;
|
|
animation: popup-open-below 0.22s cubic-bezier(0.34, 1.4, 0.64, 1) both;
|
|
}
|
|
|
|
/* ── EVENT TAG POPUP — SLIDESHOW ────────────────────────────────────────
|
|
The stage holds the current slide. On transition, evTransition is set
|
|
to 'exiting' (fade out) then 'entering' (fade in) via the hook. */
|
|
@keyframes ev-fade-in { from { opacity: 0; } to { opacity: 1; } }
|
|
@keyframes ev-fade-out { from { opacity: 1; } to { opacity: 0; } }
|
|
|
|
.ev-popup-stage {
|
|
transition: opacity 0.38s ease;
|
|
}
|
|
.ev-popup-entering {
|
|
animation: ev-fade-in 0.38s ease both;
|
|
}
|
|
.ev-popup-exiting {
|
|
animation: ev-fade-out 0.38s ease both;
|
|
}
|
|
|
|
/* Slideshow navigation dots */
|
|
.ev-popup-dots {
|
|
display: flex;
|
|
gap: 5px;
|
|
margin-top: 8px;
|
|
justify-content: center;
|
|
align-items: center;
|
|
}
|
|
.ev-popup-dot {
|
|
width: 6px;
|
|
height: 6px;
|
|
border-radius: 50%;
|
|
background: #c9b08a;
|
|
opacity: 0.4;
|
|
cursor: pointer;
|
|
transition: opacity 0.2s, transform 0.2s;
|
|
flex-shrink: 0;
|
|
}
|
|
.ev-popup-dot.active {
|
|
opacity: 1;
|
|
transform: scale(1.35);
|
|
background: #7a5530;
|
|
}
|
|
.ev-popup-dot:hover {
|
|
opacity: 0.75;
|
|
}
|
|
|
|
|
|
/* ── 8. NOW-ROW & NIGHT-ROW DECORATIONS ─────────────────────────────── */
|
|
|
|
/* "Currently this hour" — the highlighted row.
|
|
The row gets a cream-yellow background and darker text. No left
|
|
stripe or pip — the colour shift alone signals "this is now". */
|
|
.utci-table tbody tr.is-now {
|
|
background: #fff8e4 !important;
|
|
}
|
|
|
|
.utci-table tbody tr.is-now td {
|
|
color: #1e1208;
|
|
/* Brass bracket framing the current-hour row top and bottom — clean,
|
|
definitive, no left stripe needed. */
|
|
border-top: 2px solid #c8922a;
|
|
border-bottom: 2px solid #c8922a;
|
|
}
|
|
|
|
/* Night-time hours get a slightly muted text colour */
|
|
.utci-table tbody tr.is-night td {
|
|
color: #7a5c30;
|
|
}
|
|
|
|
/* The time cell — uses the display serif instead of monospace */
|
|
.utci-time {
|
|
font-family: Fraunces, serif !important;
|
|
font-weight: 500;
|
|
font-size: 16px;
|
|
color: #1e1208 !important;
|
|
}
|
|
.utci-time svg {
|
|
margin: -6px 0;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
@media (max-width: 800px) {
|
|
.utci-time {
|
|
font-size: 15px;
|
|
}
|
|
.utci-cell-hero {
|
|
font-size: 15px !important;
|
|
padding: 5px 12px;
|
|
min-width: 60px;
|
|
}
|
|
}
|
|
|
|
/* The coloured pill inside UTCI / UTCI+P cells.
|
|
The pill's BACKGROUND comes from inline styles in app.js
|
|
(the utciCategory() function decides which thermal-stress colour
|
|
to apply). This rule just handles the pill shape. */
|
|
.utci-cell {
|
|
display: inline-block;
|
|
padding: 4px 12px;
|
|
border-radius: 3px;
|
|
font-weight: 600;
|
|
min-width: 60px;
|
|
text-align: center;
|
|
font-size: 14px;
|
|
}
|
|
|
|
/* Hero variant used for the UTCI+P column — the headline number.
|
|
Bigger, bolder, more breathing room so the eye lands here first. */
|
|
.utci-cell-hero {
|
|
padding: 6px 4px;
|
|
font-size: 17px;
|
|
font-weight: 700;
|
|
min-width: 63px;
|
|
letter-spacing: 0.01em;
|
|
box-shadow: 0 1px 0 rgba(0,0,0,0.15) inset, 0 0 0 1px rgba(255,255,255,0.08) inset;
|
|
}
|
|
|
|
.utci-band-label {
|
|
font-family: Manrope, sans-serif;
|
|
font-size: 10px;
|
|
font-weight: 700;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.06em;
|
|
}
|
|
|
|
/* Faint vertical divider before each new column group in the forecast table. */
|
|
.utci-table .col-group-start {
|
|
border-left: 2px solid rgba(74, 50, 24, 0.18);
|
|
}
|
|
|
|
/* ── COLUMN GROUP COLOURS — header cell tints per group ─────────────────
|
|
Each grp-* class gives the th a distinct background + text colour.
|
|
The hover state darkens slightly. The col-unit underneath inherits
|
|
a matching accent colour. */
|
|
|
|
.utci-table th.grp-felt { background: rgba(223,243,236,0.50); color: #075c3a; }
|
|
.utci-table th.grp-surface { background: rgba(221,234,248,0.50); color: #0b3e72; }
|
|
.utci-table th.grp-ambient { background: rgba(236,234,227,0.50); color: #3c3a35; }
|
|
.utci-table th.grp-precip { background: rgba(247,228,238,0.50); color: #6b1e3a; }
|
|
.utci-table th.grp-sky { background: rgba(234,232,252,0.50); color: #352e7a; }
|
|
.utci-table th.grp-wind { background: rgba(250,230,224,0.50); color: #6a2210; }
|
|
.utci-table th.grp-airqual { background: rgba(229,240,216,0.50); color: #244408; }
|
|
.utci-table th.grp-solar { background: rgba(250,234,204,0.50); color: #5a3004; }
|
|
|
|
.utci-table th.grp-felt.col-info-th:hover { background: rgba(213,233,226,0.80); }
|
|
.utci-table th.grp-surface.col-info-th:hover { background: rgba(211,224,238,0.80); }
|
|
.utci-table th.grp-ambient.col-info-th:hover { background: rgba(226,224,217,0.80); }
|
|
.utci-table th.grp-precip.col-info-th:hover { background: rgba(237,218,228,0.80); }
|
|
.utci-table th.grp-sky.col-info-th:hover { background: rgba(224,222,242,0.80); }
|
|
.utci-table th.grp-wind.col-info-th:hover { background: rgba(240,220,214,0.80); }
|
|
.utci-table th.grp-airqual.col-info-th:hover { background: rgba(219,230,206,0.80); }
|
|
.utci-table th.grp-solar.col-info-th:hover { background: rgba(240,224,194,0.80); }
|
|
|
|
.utci-table th.grp-felt .col-unit { color: #0f9e63; }
|
|
.utci-table th.grp-surface .col-unit { color: #2672c8; }
|
|
.utci-table th.grp-ambient .col-unit { color: #7a7870; }
|
|
.utci-table th.grp-precip .col-unit { color: #b03060; }
|
|
.utci-table th.grp-sky .col-unit { color: #6058c8; }
|
|
.utci-table th.grp-wind .col-unit { color: #b04030; }
|
|
.utci-table th.grp-airqual .col-unit { color: #4a8018; }
|
|
.utci-table th.grp-solar .col-unit { color: #b07820; }
|
|
|
|
/* ── GROUP LABEL ROW — spans above the column header row ────────────────
|
|
A second tr in the thead. Each cell spans all visible columns in its
|
|
group. The Hour column gets a blank matching-background cell. */
|
|
|
|
.grp-label-row th {
|
|
font-family: Manrope, sans-serif;
|
|
font-size: 9px;
|
|
font-weight: 700;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.10em;
|
|
padding: 4px 8px 2px;
|
|
text-align: center;
|
|
white-space: nowrap;
|
|
border-bottom: 1px solid rgba(0,0,0,0.06);
|
|
}
|
|
|
|
.utci-table .grp-label-row th.grp-felt { background: rgba(223,243,236,0.50); border-left: 2px solid rgba(74,50,24,0.18); border-bottom: 1px solid rgba(74,50,24,0.18);}
|
|
.utci-table .grp-label-row th.grp-surface { background: rgba(221,234,248,0.50); border-left: 2px solid rgba(74,50,24,0.18); border-bottom: 1px solid rgba(74,50,24,0.18);}
|
|
.utci-table .grp-label-row th.grp-ambient { background: rgba(236,234,227,0.50); border-left: 2px solid rgba(74,50,24,0.18); border-bottom: 1px solid rgba(74,50,24,0.18);}
|
|
.utci-table .grp-label-row th.grp-precip { background: rgba(247,228,238,0.50); border-left: 2px solid rgba(74,50,24,0.18); border-bottom: 1px solid rgba(74,50,24,0.18);}
|
|
.utci-table .grp-label-row th.grp-sky { background: rgba(234,232,252,0.50); border-left: 2px solid rgba(74,50,24,0.18); border-bottom: 1px solid rgba(74,50,24,0.18);}
|
|
.utci-table .grp-label-row th.grp-wind { background: rgba(250,230,224,0.50); border-left: 2px solid rgba(74,50,24,0.18); border-bottom: 1px solid rgba(74,50,24,0.18);}
|
|
.utci-table .grp-label-row th.grp-airqual { background: rgba(229,240,216,0.50); border-left: 2px solid rgba(74,50,24,0.18); border-bottom: 1px solid rgba(74,50,24,0.18);}
|
|
.utci-table .grp-label-row th.grp-solar { background: rgba(250,234,204,0.50); border-left: 2px solid rgba(74,50,24,0.18); border-bottom: 1px solid rgba(74,50,24,0.18);}
|
|
|
|
/* ── POPUP — mobile centre-alignment ───────────────────────────────── */
|
|
@media (max-width: 640px) {
|
|
.col-info-title,
|
|
.col-info-desc {
|
|
text-align: center;
|
|
}
|
|
}
|
|
|
|
/* ── FILTER PROFILES + COLUMN TOGGLES — mobile fixes ───────────────── */
|
|
@media (max-width: 640px) {
|
|
|
|
/* ── Profile bar — single scroll row on all screen sizes ───────────
|
|
No wrapping needed; scroll strip handles layout. Dividers stay. */
|
|
.filter-profiles {
|
|
padding: 4px 0 0;
|
|
}
|
|
|
|
.profile-tabs {
|
|
width: 100%;
|
|
margin-left: 0;
|
|
margin-right: 0;
|
|
}
|
|
|
|
/* Slightly smaller cards on mobile */
|
|
.profile-btn {
|
|
width: 80px;
|
|
height: 80px;
|
|
flex: none;
|
|
}
|
|
|
|
.profile-btn-scene {
|
|
font-size: 18px;
|
|
}
|
|
|
|
.profile-btn-label {
|
|
height: 20px;
|
|
font-size: 9px;
|
|
}
|
|
|
|
/* ── Column toggles bar ─────────────────────────────────────────────
|
|
Same approach — label full row, toggles at ~31% each. */
|
|
.col-toggles {
|
|
flex-wrap: wrap;
|
|
gap: 6px;
|
|
padding: 10px 10px;
|
|
align-items: stretch;
|
|
}
|
|
|
|
.col-toggles-label {
|
|
flex: 0 0 100%;
|
|
margin-right: 0;
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
.col-toggle {
|
|
flex: 0 0 calc((100% - 12px) / 3);
|
|
min-width: 0;
|
|
box-sizing: border-box;
|
|
text-align: center;
|
|
padding: 7px 2px;
|
|
font-size: 11px;
|
|
letter-spacing: 0.03em;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
/* Pollen CustomSelect in col-toggles — match toggle width */
|
|
.col-toggles .cs-wrap {
|
|
flex: 0 0 calc((100% - 12px) / 3);
|
|
min-width: 0;
|
|
}
|
|
.col-toggles .cs-btn {
|
|
width: 100%;
|
|
min-width: 0;
|
|
padding: 7px 6px;
|
|
font-size: 11px;
|
|
letter-spacing: 0.03em;
|
|
justify-content: center;
|
|
overflow: hidden;
|
|
}
|
|
|
|
/* Fused group: 1 slot by default, 2 slots when VentPill is active */
|
|
.col-toggle-group {
|
|
flex: 0 0 calc((100% - 12px) / 3);
|
|
min-width: 0;
|
|
display: inline-flex;
|
|
align-items: stretch;
|
|
}
|
|
.col-toggle-group--expanded {
|
|
flex: 0 0 calc((100% - 12px) / 3 * 2 + 6px);
|
|
}
|
|
.col-toggle-group .cs-wrap {
|
|
flex: 1 1 0;
|
|
min-width: 0;
|
|
width: 100%;
|
|
}
|
|
.col-toggle-group .cs-btn {
|
|
width: 100%;
|
|
min-width: 0;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
font-size: 11px;
|
|
padding: 7px 6px;
|
|
justify-content: center;
|
|
}
|
|
|
|
}
|
|
|
|
/* ── MOBILE TABLE DENSITY — squeeze all basic profile columns in ────────
|
|
Target: 7 cols (hour air wind cloud utciP precip vis) on a 390px screen.
|
|
Worst-case minimum width at these values: 366px - fits iPhone SE (375px).
|
|
Levers: tighter cell padding, smaller min-width, reduced font sizes.
|
|
The existing 800px and 640px blocks handle tablets and phablets above.
|
|
DENSITY-BREAKPOINT - change 480px here to adjust where dense layout kicks in.
|
|
-------------------------------------------------------------------- */
|
|
|
|
/* -- MOBILE TABLE DENSITY - squeeze all basic profile columns in --------
|
|
Target: 7 cols (hour air wind cloud utciP precip vis) on a 390px screen.
|
|
Worst-case minimum width: 366px - fits iPhone SE (375px) with room to spare.
|
|
DENSITY-BREAKPOINT - change 480px to adjust where dense layout kicks in.
|
|
-------------------------------------------------------------------- */
|
|
@media (max-width: 480px) {
|
|
|
|
/* -- Table header cells -----------------------------------------------
|
|
Reduce padding so headers do not drive columns wider than data needs. */
|
|
.utci-table th {
|
|
font-size: 9px;
|
|
padding: 10px 4px;
|
|
letter-spacing: 0.04em;
|
|
}
|
|
|
|
.utci-table th .col-unit {
|
|
font-size: 8px;
|
|
}
|
|
|
|
/* -- Table body cells -------------------------------------------------
|
|
Drop side padding 12px to 4px, shrink min-width 60px to 44px.
|
|
JetBrains Mono at 11px reads cleanly on retina screens. */
|
|
.utci-table td {
|
|
padding: 10px 4px;
|
|
font-size: 11px;
|
|
min-width: 44px;
|
|
}
|
|
|
|
/* -- Time (Hour) column -----------------------------------------------
|
|
Drop Fraunces from 16px to 13px and tighten the hour cell min-width. */
|
|
.utci-time {
|
|
font-size: 13px;
|
|
}
|
|
|
|
.utci-table td:first-child {
|
|
min-width: 42px;
|
|
}
|
|
|
|
/* -- SkyScope moon-sun icon in the hour cell ---------------------------
|
|
JS renders at size=38. Clamp to 25px via CSS to stop it ballooning
|
|
the hour column width and driving up row height. */
|
|
.utci-time svg {
|
|
width: 34px !important;
|
|
height: 34px !important;
|
|
margin: -5px 0;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
/* -- Cloud, wind-vane and precip icons in body cells -------------------
|
|
Clamp the 28px SVGs down to 20px on mobile to recover column width
|
|
without touching the JS size prop. */
|
|
.utci-table td svg {
|
|
width: 20px !important;
|
|
height: 20px !important;
|
|
flex-shrink: 0;
|
|
}
|
|
/* Override for SkyScope - keep it larger than other cell icons */
|
|
.utci-table td.utci-time svg {
|
|
width: 26px !important;
|
|
height: 26px !important;
|
|
}
|
|
|
|
/* -- Hero UTCI+P pill -------------------------------------------------
|
|
Shrink min-width and font - still the visual anchor but no longer
|
|
forcing the column to be the widest. */
|
|
.utci-cell-hero {
|
|
font-size: 14px;
|
|
min-width: 50px;
|
|
padding: 5px 2px;
|
|
}
|
|
|
|
/* -- Vis column -----------------------------------------------------------
|
|
Short values (8-99km) need less room than the default 44px min-width. */
|
|
.utci-vis-cell {
|
|
min-width: 30px;
|
|
}
|
|
|
|
/* -- Standard UTCI pill (non-hero) ------------------------------------*/
|
|
.utci-cell {
|
|
font-size: 12px;
|
|
min-width: 44px;
|
|
padding: 3px 5px;
|
|
}
|
|
|
|
/* -- Band label inside pills ------------------------------------------
|
|
Tighten letter-spacing to save a little width. */
|
|
.utci-band-label {
|
|
font-size: 9px;
|
|
letter-spacing: 0.03em;
|
|
}
|
|
}
|