5.4.0
Restructure New Journal entries Colour tabs update with wind
This commit is contained in:
+180
-55
@@ -65,7 +65,14 @@ body {
|
||||
color: #1e1208;
|
||||
background: #f5edd6;
|
||||
min-height: 100vh;
|
||||
padding: 52px 36px 32px;
|
||||
/* The side padding, as a variable: the header and the event note both
|
||||
full-bleed by cancelling it, and would otherwise each need the number
|
||||
restating at every breakpoint that changes it. */
|
||||
--app-pad: 36px;
|
||||
/* No top padding: .utci-topnav is a real header at the very top of the flow
|
||||
now, and supplies its own. Was 52px, reserved for the nav when it was
|
||||
absolutely positioned over this space. */
|
||||
padding: 0 var(--app-pad) 32px;
|
||||
position: relative;
|
||||
/* overflow-x: clip (not hidden) — `clip` clips horizontal overflow
|
||||
WITHOUT making this a scroll container, so `position: sticky` on
|
||||
@@ -83,19 +90,27 @@ body {
|
||||
}
|
||||
|
||||
|
||||
/* ── 3. TOP NAVIGATION (Home / About links in the corner) ──────────── */
|
||||
/* ── 3. SITE HEADER (wordmark left, nav links right) ───────────────── */
|
||||
|
||||
/* Rendered as <header id="site-nav"> — the same element the static pages
|
||||
(about.html et al) use — and it now carries the wordmark and tagline that
|
||||
used to be repeated inside .utci-header. It sits FIRST in the flow, at the
|
||||
very top of the page, with the event banner beneath it.
|
||||
Full-bleed: .utci-app pads its content in by --app-pad a side, so the header
|
||||
cancels that with a matching negative margin and pads itself instead — the
|
||||
bar's rule reaches both page edges while its contents still line up with
|
||||
the content below. */
|
||||
.utci-topnav {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
position: relative; /* keeps z-index working without leaving the flow */
|
||||
z-index: 100;
|
||||
margin: 0 calc(var(--app-pad) * -1) 18px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
padding: 0px 32px;
|
||||
justify-content: flex-end; /* .nav-logo's margin-right:auto splits the row */
|
||||
padding: 18px var(--app-pad);
|
||||
gap: 28px;
|
||||
background: #f5edd6;
|
||||
border-bottom: 1px solid #e0d0a8;
|
||||
}
|
||||
|
||||
.utci-topnav a {
|
||||
@@ -116,9 +131,9 @@ body {
|
||||
border-bottom-color: #1e1208;
|
||||
}
|
||||
|
||||
/* Desktop: nav-links renders inline as part of nav flex row */
|
||||
/* Desktop: nav-links renders inline as part of the header's flex row */
|
||||
.utci-topnav .nav-links {
|
||||
display: contents; /* participates in nav's flex layout transparently */
|
||||
display: contents; /* participates in the header's flex layout transparently */
|
||||
}
|
||||
|
||||
/* ── About dropdown ─────────────────────────────────────────────────── */
|
||||
@@ -171,6 +186,22 @@ body {
|
||||
visibility: visible;
|
||||
transform: translateX(-50%) translateY(0);
|
||||
}
|
||||
/* The Account dropdown sits at the far right of the nav row, so a menu
|
||||
centred under it (like About's) would spill past the viewport edge on
|
||||
most screen widths. Right-align it to the toggle instead, growing left. */
|
||||
.utci-topnav .nav-dropdown--right .nav-dropdown-menu {
|
||||
left: auto;
|
||||
right: 0;
|
||||
transform: translateY(-4px);
|
||||
}
|
||||
.utci-topnav .nav-dropdown--right.nav-dropdown:hover .nav-dropdown-menu,
|
||||
.utci-topnav .nav-dropdown--right.nav-dropdown:focus-within .nav-dropdown-menu {
|
||||
transform: translateY(0);
|
||||
}
|
||||
/* Labels align to the same right edge the menu itself hangs from. */
|
||||
.utci-topnav .nav-dropdown--right .nav-dropdown-menu a {
|
||||
text-align: right;
|
||||
}
|
||||
.utci-topnav .nav-dropdown-menu a {
|
||||
text-transform: none;
|
||||
letter-spacing: normal;
|
||||
@@ -190,15 +221,15 @@ body {
|
||||
|
||||
/* ── Event note ─────────────────────────────────────────────────────── */
|
||||
/* Active cosmic/weather events shown as a strip across the content width,
|
||||
above the nav. It is IN FLOW — it pushes the page down instead of
|
||||
covering anything, which is the whole point of it not being a flyout.
|
||||
One event at a time with its full message, cycling with a fade.
|
||||
directly under the site header. It is IN FLOW — it pushes the page down
|
||||
instead of covering anything, which is the whole point of it not being a
|
||||
flyout. One event at a time with its full message, cycling with a fade.
|
||||
|
||||
The nav is normally position:absolute and .utci-app reserves 52px of top
|
||||
padding for it. When a note is present the nav joins the flow instead so
|
||||
the note can sit above it, and that padding is no longer needed. On true
|
||||
mobile (≤640px) the nav is position:fixed and stays that way — there the
|
||||
note simply becomes the first thing under it, so no override applies. */
|
||||
It used to render ABOVE the nav, which meant repositioning the nav out of
|
||||
its absolute placement whenever a note was present. The header owns the top
|
||||
of the page now, so the note is simply the first thing under it — on desktop
|
||||
and on mobile (where the header is fixed and .utci-app pads clear of it)
|
||||
alike, with no override either way. */
|
||||
.event-note {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
@@ -222,11 +253,20 @@ body {
|
||||
same device as .almanac-entry-accent. */
|
||||
.event-note-accent {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 3px;
|
||||
inset: 0;
|
||||
opacity: 0.75;
|
||||
pointer-events: none;
|
||||
/* One element, drawn as an L: a 1px strip down the left that turns and runs
|
||||
along the bottom. The note's own overflow: hidden rounds the corner off
|
||||
with the rest of the box. */
|
||||
clip-path: polygon(
|
||||
0 0,
|
||||
1px 0,
|
||||
1px calc(100% - 1px),
|
||||
100% calc(100% - 1px),
|
||||
100% 100%,
|
||||
0 100%
|
||||
);
|
||||
}
|
||||
|
||||
/* Safety-relevant weather (heat, frost, storm, wind, wet) — brass emphasis.
|
||||
@@ -408,33 +448,39 @@ body {
|
||||
color: #2a1a08;
|
||||
}
|
||||
|
||||
/* Collapse on the way out — height and vertical spacing animate to zero so
|
||||
the page closes the gap smoothly instead of snapping upward. */
|
||||
/* Closing: the slot's height runs down to zero (measured and driven inline by
|
||||
noteClose in app.js) and the note is anchored to its BOTTOM edge, so the
|
||||
banner rides up behind the header's seam while everything below it rises by
|
||||
the same amount at the same rate. One animated property for both movements —
|
||||
a transform on the note would slide it independently of the page, and a
|
||||
transform on the content below would break the fixed-position controls
|
||||
living inside it. */
|
||||
.event-note-slot {
|
||||
/* The gap under the banner lives here rather than on the note, and is
|
||||
deliberately equal to what the header gets back when .has-event-note is
|
||||
dropped at the end of the close: the header's own margin-bottom (18px,
|
||||
zeroed while a note is attached) plus, on a phone, the 8px .utci-app
|
||||
stops padding once the note is gone. Without that, the space swapped in
|
||||
at unmount showed up as a jump. */
|
||||
margin-bottom: 18px;
|
||||
display: grid;
|
||||
grid-template-rows: 1fr; /* the row fills the slot, whatever its height */
|
||||
align-items: end; /* ...and the note hangs from its bottom edge */
|
||||
overflow: hidden;
|
||||
}
|
||||
.event-note-slot > .event-note {
|
||||
min-height: 0; /* grid items floor at min-content without this */
|
||||
}
|
||||
/* The entry animation is fill-mode: both, so its final transform would stay
|
||||
applied — cleared so it cannot offset the note against the slot. */
|
||||
.event-note.is-closing {
|
||||
animation: event-note-out 0.26s ease forwards;
|
||||
animation: none;
|
||||
pointer-events: none;
|
||||
}
|
||||
@keyframes event-note-out {
|
||||
from { opacity: 1; transform: translateY(0); max-height: 200px; }
|
||||
to { opacity: 0; transform: translateY(-4px); max-height: 0;
|
||||
margin-bottom: 0; padding-top: 0; padding-bottom: 0; border-width: 0; }
|
||||
}
|
||||
|
||||
/* Above true-mobile: the nav drops into the flow beneath the note. Its own
|
||||
32px side padding is dropped so the links line up with the note and the
|
||||
content rather than sitting 32px inside them. */
|
||||
@media (min-width: 641px) {
|
||||
.utci-app.has-event-note {
|
||||
padding-top: 18px;
|
||||
}
|
||||
/* `relative`, not `static` — the nav keeps its z-index:100 that way, so
|
||||
the About dropdown still paints over .utci-shell (which is z-index:1). */
|
||||
.utci-app.has-event-note .utci-topnav {
|
||||
position: relative;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
}
|
||||
/* The note follows the header in the flow now, so it needs no special
|
||||
positioning — only the gap the header's own margin-bottom would otherwise
|
||||
have given the content it sits in front of. */
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.event-note {
|
||||
@@ -456,26 +502,89 @@ body {
|
||||
}
|
||||
}
|
||||
|
||||
/* Nav logo — hidden on desktop, shown on mobile */
|
||||
/* ── Note attached to the header ─────────────────────────────────────
|
||||
When a note is present it hangs off the header's bottom edge rather than
|
||||
floating below it as a separate panel: the header drops the gap it would
|
||||
otherwise leave, and the note keeps a square top with no top border, inset
|
||||
to the content edge so there is a gap either side. The header's own bottom
|
||||
rule becomes the seam the strip hangs from.
|
||||
|
||||
Placed after the ≤640px block above deliberately — these override the
|
||||
note's base padding and border at every width, mobile included. */
|
||||
.has-event-note .utci-topnav {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.has-event-note .event-note {
|
||||
/* Inset to the content edge rather than full-bleed, so the strip keeps a
|
||||
gap either side of it. The gap below is the slot's — see .event-note-slot. */
|
||||
margin: 0;
|
||||
padding: 10px 15px;
|
||||
/* No top border and square top corners: the header's own bottom rule is the
|
||||
seam it hangs from. A tinted note's inline borderColor still tints what is
|
||||
left, since that sets the colour only and this sets style and width. */
|
||||
border: 1.5px solid #c9b08a;
|
||||
border-top: none;
|
||||
border-radius: 0 0 4px 4px;
|
||||
}
|
||||
@media (max-width: 640px) {
|
||||
/* Matches the two-class specificity above so the phone's tighter padding
|
||||
survives the override. */
|
||||
.has-event-note .event-note {
|
||||
padding: 10px 12px;
|
||||
}
|
||||
|
||||
/* 18px + the 8px of .utci-app padding-top below — see .event-note-slot. */
|
||||
.event-note-slot {
|
||||
margin-bottom: 26px;
|
||||
}
|
||||
|
||||
/* The bar is position:fixed and 72px tall on a phone, and .utci-app pads 80px
|
||||
clear of it — the spare 8px would show as a gap above the note. Two classes
|
||||
so it outranks the single-class padding-top in ui.css whatever the order. */
|
||||
.utci-app.has-event-note {
|
||||
padding-top: 72px;
|
||||
}
|
||||
}
|
||||
|
||||
/* The site identity, in the header on every viewport. Was display:none here
|
||||
and unhidden only on mobile, back when the big .utci-title wordmark carried
|
||||
the desktop identity instead. */
|
||||
.nav-logo {
|
||||
display: none;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
/* Same device about.css uses on .nav-logo: one auto margin pushes everything
|
||||
after it to the right-hand end, which works with .nav-links staying
|
||||
display:contents. */
|
||||
margin-right: auto;
|
||||
}
|
||||
.nav-logo-wordmark {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.05em;
|
||||
/* It is the page's <h1> now, so the browser's own h1 margin and 2em size are
|
||||
cleared here — the wordmark's size and weight come from .nav-logo-sun and
|
||||
.nav-logo-scope, and the icon is sized in rem. */
|
||||
margin: 0;
|
||||
font-size: 1rem;
|
||||
font-weight: inherit;
|
||||
}
|
||||
.nav-logo-sun,
|
||||
.nav-logo-scope {
|
||||
font-family: Manrope, sans-serif;
|
||||
font-weight: 250;
|
||||
font-size: 2.1rem;
|
||||
/* 1.6rem matches .nav-logo-sun in about.css, so the wordmark is the same size on the
|
||||
forecast and on every static page. The phone bar scales it back up (see the
|
||||
≤640px block) where it is the centred focal point rather than a corner mark. */
|
||||
font-size: 1.6rem;
|
||||
color: #1e1208;
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
.nav-logo-icon {
|
||||
width: 1.65rem;
|
||||
height: 1.65rem;
|
||||
width: 1.26rem; /* same 0.79 ratio to the wordmark as .nav-logo-icon */
|
||||
height: 1.26rem;
|
||||
color: #1e1208;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
@@ -484,7 +593,7 @@ body {
|
||||
font-family: Manrope, sans-serif;
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-size: 8px;
|
||||
font-size: 10px;
|
||||
letter-spacing: 0.12em;
|
||||
text-transform: uppercase;
|
||||
color: #7a5c2a;
|
||||
@@ -548,14 +657,26 @@ body {
|
||||
display: block;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.utci-title,
|
||||
.utci-tagline {
|
||||
display: none;
|
||||
.nav-logo-sun,
|
||||
.nav-logo-scope {
|
||||
font-size: 2.1rem;
|
||||
}
|
||||
.nav-logo-icon {
|
||||
width: 1.65rem;
|
||||
height: 1.65rem;
|
||||
}
|
||||
|
||||
/* Phone keeps the bar pinned to the viewport, with the wordmark centred in
|
||||
it and the links behind the burger. The offsets are set here rather than
|
||||
inherited: the desktop rule is in-flow now and carries no top/left/right,
|
||||
and its full-bleed negative margin has nothing to cancel once the bar is
|
||||
fixed and already edge-to-edge. */
|
||||
.utci-topnav {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: 0;
|
||||
padding: 10px 20px;
|
||||
height: 72px;
|
||||
background: #f5edd6;
|
||||
@@ -616,6 +737,10 @@ body {
|
||||
gap: 18px;
|
||||
}
|
||||
.utci-topnav .nav-dropdown-menu a { padding: 0; font-size: 14px; }
|
||||
/* Right-aligned text is a desktop-popup touch (see the --right rule
|
||||
above) - on mobile everything is one left-indented list, so match
|
||||
About's list instead of standing out. */
|
||||
.utci-topnav .nav-dropdown--right .nav-dropdown-menu a { text-align: left; }
|
||||
|
||||
/* Burger → X animation */
|
||||
.utci-topnav.nav-open .utci-burger span:nth-child(1) {
|
||||
|
||||
+48
-75
@@ -18,18 +18,22 @@
|
||||
.scope-col { grid-area: dial; }
|
||||
.header-right { grid-area: hright; }
|
||||
|
||||
/* Left column — wordmark, tagline, search and location stacked together */
|
||||
/* Left column — the location line and its search overlay. The wordmark and
|
||||
tagline that used to head this stack now live in the site header, so what is
|
||||
left hangs from the top of the row, level with the top of the dial. */
|
||||
.header-left {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
/* Wraps the location line + the reveal-on-demand search overlay so the
|
||||
search can position itself directly over the location to save space. */
|
||||
.utci-loc-search {
|
||||
position: relative;
|
||||
margin-top: 18px;
|
||||
/* Was 18px, clearing the tagline above it. It leads the column now. */
|
||||
margin-top: 0;
|
||||
width: 380px;
|
||||
max-width: 100%;
|
||||
}
|
||||
@@ -40,45 +44,11 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
justify-content: center;
|
||||
justify-content: flex-start; /* level with the top of the dial */
|
||||
}
|
||||
|
||||
/* The big "SunScope" wordmark */
|
||||
.utci-title {
|
||||
font-family: Manrope, sans-serif;
|
||||
font-weight: 250;
|
||||
font-size: clamp(48px, 6vw, 80px);
|
||||
line-height: 1;
|
||||
letter-spacing: -0.01em;
|
||||
color: #1e1208;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.05em;
|
||||
}
|
||||
|
||||
.utci-title .title-sun,
|
||||
.utci-title .title-scope {
|
||||
color: #1e1208;
|
||||
}
|
||||
|
||||
.title-icon {
|
||||
width: 0.82em;
|
||||
height: 0.82em;
|
||||
color: #1e1208;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* "See the world the way..." */
|
||||
.utci-tagline {
|
||||
font-family: Manrope, sans-serif;
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-size: 11px;
|
||||
letter-spacing: 0.12em;
|
||||
text-transform: uppercase;
|
||||
color: #7a5c2a;
|
||||
margin-top: 12px;
|
||||
}
|
||||
/* The wordmark and tagline that used to head this column now live in the
|
||||
site header (.nav-logo in base.css) — see the header there. */
|
||||
|
||||
/* "↳ Location, Somewhere" + the magnifier that reveals the search */
|
||||
.utci-current-loc {
|
||||
@@ -184,6 +154,7 @@
|
||||
background: #fffcf2;
|
||||
color: #9a7a3a;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
transition: color 0.2s, border-color 0.2s, background 0.2s, box-shadow 0.2s;
|
||||
}
|
||||
|
||||
@@ -213,6 +184,39 @@
|
||||
.utci-loc-action.is-busy svg { animation: none; opacity: 0.55; }
|
||||
}
|
||||
|
||||
/* Tool row under the location line — the magnifier, locate, share and journal
|
||||
buttons sit on their own row now that the header has the space, each with a
|
||||
small caption so the icons don't have to carry the meaning alone. */
|
||||
.utci-loc-tools {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: flex-start;
|
||||
gap: 16px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.utci-loc-tool {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.utci-loc-tool-label {
|
||||
font-family: Manrope, sans-serif;
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-size: 9.5px;
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
color: #a08c62;
|
||||
white-space: nowrap;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
|
||||
/* Light the caption up with its button so the pair reads as one control */
|
||||
.utci-loc-tool:hover .utci-loc-tool-label { color: #c8922a; }
|
||||
|
||||
/* Transient note under the location row: "Link copied", permission errors */
|
||||
.utci-loc-note {
|
||||
display: flex;
|
||||
@@ -240,19 +244,6 @@
|
||||
|
||||
.utci-loc-note-x:hover { opacity: 1; }
|
||||
|
||||
/* The lat/lon below the location */
|
||||
.utci-loc-coords {
|
||||
font-family: JetBrains Mono, monospace;
|
||||
font-style: normal;
|
||||
font-size: 11px;
|
||||
color: #b09870;
|
||||
display: block;
|
||||
flex-basis: 100%; /* drop onto its own line below the name + magnifier */
|
||||
margin-top: 4px;
|
||||
margin-left: 0;
|
||||
letter-spacing: 0.08em;
|
||||
}
|
||||
|
||||
/* The big UTCI dial in the middle of the header.
|
||||
Change width/height to resize it. */
|
||||
.scope-ring {
|
||||
@@ -301,7 +292,9 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
/* Top-anchored so the dial defines the row's top edge and the location and
|
||||
Solar model columns beside it start on the same line. */
|
||||
justify-content: flex-start;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
@@ -594,12 +587,6 @@ body.tl-scrubbing * { transition: none !important; }
|
||||
box-shadow: 0 6px 20px #64461426; /* lift it off the location underneath */
|
||||
}
|
||||
|
||||
/* The 300px wrapper would let .utci-fetch-time's default right-align drift to
|
||||
the far edge; keep it left-aligned beneath the coords as before. */
|
||||
.utci-loc-search .utci-fetch-time {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.utci-search-label {
|
||||
font-family: Manrope, sans-serif;
|
||||
font-size: 10px;
|
||||
@@ -716,16 +703,6 @@ body.tl-scrubbing * { transition: none !important; }
|
||||
align-items: center; /* centre the "Why it feels like" panel under the dial */
|
||||
}
|
||||
|
||||
.utci-title {
|
||||
font-size: clamp(40px, 12vw, 60px);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.utci-title,
|
||||
.utci-tagline {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 960px) {
|
||||
@@ -753,12 +730,8 @@ body.tl-scrubbing * { transition: none !important; }
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.utci-loc-coords {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.utci-loc-search .utci-fetch-time {
|
||||
text-align: center; /* match the desktop override's specificity */
|
||||
.utci-loc-tools {
|
||||
justify-content: center; /* centre the tool row on mobile */
|
||||
}
|
||||
|
||||
.utci-search-wrap {
|
||||
|
||||
+271
-32
@@ -270,6 +270,34 @@
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* The sky glyph and anything composited onto it. Anchors .utci-day-wind and
|
||||
is inline-block so it hugs the 30px icon rather than the full tab width. */
|
||||
.utci-day-icon {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
line-height: 0;
|
||||
}
|
||||
|
||||
/* Gust lines overlaid on the sky glyph (Near Gale and above, where the wind
|
||||
isn't already the main icon). Absolutely positioned, so it costs the tab no
|
||||
layout width — at the 90px min-width there is no room for a second glyph
|
||||
beside the sky icon, and the tab's rows stay aligned with the legend column.
|
||||
|
||||
Concentric with the sky glyph rather than tucked into a corner: hanging it
|
||||
off one side made the pair read as two separate stickers, one of them
|
||||
falling off the edge. Centred, the gusts read as blowing THROUGH the cloud —
|
||||
one combined symbol. The -44% (rather than -50%) vertical offset drops it a
|
||||
couple of pixels below true centre, so the lines cross the base of the cloud
|
||||
instead of cutting through its middle. */
|
||||
.utci-day-wind {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -44%);
|
||||
line-height: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* Danger-band days breathe a slow dark-red inner glow */
|
||||
.utci-day-tab.danger {
|
||||
animation: dayTabDangerPulse 2.4s ease-in-out infinite;
|
||||
@@ -609,6 +637,10 @@
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 14px;
|
||||
/* .profile-tab carries z-index:1, and a flex item honours z-index without
|
||||
needing position — so without this the tabs paint straight over the
|
||||
close button wherever the tab strip reaches the panel's right edge. */
|
||||
z-index: 6;
|
||||
background: none;
|
||||
border: none;
|
||||
font-size: 24px;
|
||||
@@ -632,8 +664,15 @@
|
||||
bottom: auto;
|
||||
max-height: calc(100vh - var(--profile-anchor-top, 0px) - 16px);
|
||||
width: fit-content;
|
||||
min-width: 380px;
|
||||
max-width: min(880px, calc(100vw - 32px));
|
||||
/* The panel's width is pinned by the hidden Activities sizer (see
|
||||
.profile-scroll-sizer / ConfigPanel.js): 9 x 100px cards + gaps +
|
||||
padding, ~1000px all-in. The old 880px cap clipped the last card or
|
||||
two, so give it room — and a min-width past that natural size so the
|
||||
config strip underneath has enough room to pack into fewer rows.
|
||||
Both are capped to the viewport, so narrow desktops and tablets
|
||||
still shrink normally. */
|
||||
min-width: min(1080px, calc(100vw - 32px));
|
||||
max-width: min(1120px, calc(100vw - 32px));
|
||||
margin: 0 auto;
|
||||
border: 1.5px solid #c9b08a;
|
||||
border-radius: 12px;
|
||||
@@ -696,7 +735,11 @@
|
||||
}
|
||||
.utci-thead-sticky {
|
||||
position: sticky;
|
||||
top: 28px !important; /* Corrected to match the height of the active-profile-row + margins */
|
||||
/* Clears the profile row pinned above it. DayTabs measures that row and
|
||||
publishes its height (+ its 4px margin) as --profile-row-h — it is one
|
||||
line or two depending on the labels, and the old fixed 28px left the
|
||||
table header tucked under it. */
|
||||
top: var(--profile-row-h, 52px) !important;
|
||||
z-index: 10;
|
||||
}
|
||||
}
|
||||
@@ -1257,6 +1300,48 @@
|
||||
.profile-dropdown-body {
|
||||
max-height: calc(100vh - 16px);
|
||||
overflow-y: auto;
|
||||
/* Room for the close bar below — the tab strip goes full width on
|
||||
phones, so the close button can no longer share that top line. */
|
||||
padding-top: 42px;
|
||||
}
|
||||
|
||||
/* Give the sheet its own header strip with a proper thumb-sized close
|
||||
target. Previously the × sat on top of the full-width tab row, where
|
||||
it was both invisible and unhittable — the sheet covers most of the
|
||||
viewport on a phone, so there was almost no backdrop left to tap
|
||||
either, and no way back to the table. The button is a child of the
|
||||
fixed panel (not the scrolling body), so it stays put while the
|
||||
config list scrolls under it. */
|
||||
.profile-dropdown-close {
|
||||
top: 6px;
|
||||
right: 10px;
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 22px;
|
||||
color: #8a6a3a;
|
||||
background: #fffcf2;
|
||||
border: 1.5px solid #c9b08a;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
/* Bottom-sheet grab handle — the usual "drag/tap me away" cue, and a
|
||||
second visual hint that the top strip is chrome, not content. */
|
||||
.profile-dropdown::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 42px;
|
||||
height: 4px;
|
||||
border-radius: 999px;
|
||||
background: #d8c7a4;
|
||||
z-index: 6;
|
||||
pointer-events: none;
|
||||
}
|
||||
.floating-profile-val { max-width: 90px; }
|
||||
.floating-profile-sub { max-width: 90px; }
|
||||
@@ -1975,6 +2060,23 @@
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
/* ...except the plain single-picker cards (SunSoak, Fur, Burn, Pollen),
|
||||
which pair up two per row. Six full-width cards turned the sheet into
|
||||
a scrolling wall that buried the table; pairing halves that. Cards
|
||||
holding a fused control group (Vehicle, Indoors) keep a full row —
|
||||
they already wrap internally and have no width to spare — and so does
|
||||
the main item, which carries the badge and the gold emphasis.
|
||||
:has() gates the whole thing: a browser without it just drops these
|
||||
rules and keeps the old one-per-row stack. */
|
||||
.col-toggles-config-item:not(.col-toggles-config-item--main):not(:has(.col-toggle-group)) {
|
||||
flex: 1 1 calc((100% - 8px) / 2);
|
||||
}
|
||||
.col-toggles-config-item:not(.col-toggles-config-item--main):not(:has(.col-toggle-group)) .cs-btn {
|
||||
font-size: 11px;
|
||||
padding: 8px 4px;
|
||||
letter-spacing: 0.02em;
|
||||
}
|
||||
|
||||
/* Re-affirm the gold emphasis for the "main" item so it still stands
|
||||
out after the generic card border above. */
|
||||
.col-toggles-config-item--main {
|
||||
@@ -2277,7 +2379,9 @@
|
||||
grid-template-columns: 1fr;
|
||||
justify-items: center;
|
||||
row-gap: 6px;
|
||||
padding: 6px 0 10px;
|
||||
/* No bottom padding: the tabs have to touch the col-toggles border
|
||||
below them, or they read as floating above the box. */
|
||||
padding: 6px 0 0;
|
||||
}
|
||||
.fvt-toolbar-left {
|
||||
grid-column: 1;
|
||||
@@ -2285,6 +2389,12 @@
|
||||
justify-self: center;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
/* Quick view needs the row flush so its thermal tabs attach to the box
|
||||
below. Detailed and Table have no tabs, so the View buttons would
|
||||
otherwise sit right on the table — give those a gap. */
|
||||
.table-main:not(.table-main--simple) .table-toolbar-row {
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
.fvt-thermal-tabs {
|
||||
grid-column: 1;
|
||||
grid-row: 2;
|
||||
@@ -2360,7 +2470,16 @@
|
||||
.table-main--simple .forecast-simple-wrap {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 420px;
|
||||
/* Sized by its contents — cards, then the curve at its own fixed height,
|
||||
then the button. It used to be a fixed 420px with the curve set to flex: 1
|
||||
to absorb whatever was left over, which made the curve's height a
|
||||
subtraction: panel minus cards minus button. That left it one card-height
|
||||
change away from falling under .fsc-temp-curve's min-height, at which point
|
||||
the column overflowed .forecast-simple-scroll (overflow-y: hidden) and the
|
||||
BOTTOM of the curve — where the cold end of the scale lives — was clipped
|
||||
off. Content-sized panel + fixed-height curve: no leftover space to gap,
|
||||
none to run out of. */
|
||||
height: auto;
|
||||
border: 1.5px solid #d4c0a0;
|
||||
background: #fdf8ee;
|
||||
}
|
||||
@@ -2368,6 +2487,56 @@
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* ── SCROLL INDICATORS (quick view) ──────────────────────────────────────
|
||||
Same fade + chevron pair the detailed table carries, driven by the
|
||||
scroll-fade-left / scroll-fade-right classes app.js toggles from the
|
||||
card strip's scroll position. The gradients fade from the panel's own
|
||||
cream so they read as the content running under the edge. */
|
||||
.table-main--simple .forecast-simple-wrap {
|
||||
position: relative;
|
||||
}
|
||||
.forecast-simple-wrap::before,
|
||||
.forecast-simple-wrap::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 48px;
|
||||
pointer-events: none;
|
||||
opacity: 0;
|
||||
transition: opacity 0.2s ease;
|
||||
z-index: 6;
|
||||
}
|
||||
.forecast-simple-wrap::before {
|
||||
left: 0;
|
||||
background: linear-gradient(to right, rgba(253,248,238,0.95) 0%, transparent 100%);
|
||||
}
|
||||
.forecast-simple-wrap::after {
|
||||
right: 0;
|
||||
background: linear-gradient(to left, rgba(253,248,238,0.95) 0%, transparent 100%);
|
||||
}
|
||||
.forecast-simple-wrap.scroll-fade-left::before { opacity: 1; }
|
||||
.forecast-simple-wrap.scroll-fade-right::after { opacity: 1; }
|
||||
|
||||
.fsc-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;
|
||||
}
|
||||
.fsc-scroll-chevron.left { left: 6px; }
|
||||
.fsc-scroll-chevron.right { right: 6px; }
|
||||
|
||||
.forecast-simple-wrap.scroll-fade-left .fsc-scroll-chevron.left { opacity: 1; }
|
||||
.forecast-simple-wrap.scroll-fade-right .fsc-scroll-chevron.right { opacity: 1; }
|
||||
|
||||
/* ── SIMPLE VIEW CARDS ───────────────────────────────────────────────────── */
|
||||
|
||||
.forecast-simple-scroll {
|
||||
@@ -2503,6 +2672,11 @@
|
||||
opacity: 0.9;
|
||||
}
|
||||
.fsc-card--now .fsc-meta-row { opacity: 1; color: #4a3218; }
|
||||
/* Speed and direction read as one fact ("21mph E"), so they share a line and
|
||||
must never break across two. The direction sits a shade back from the
|
||||
number — it qualifies the speed rather than competing with it. */
|
||||
.fsc-meta-wind { white-space: nowrap; }
|
||||
.fsc-meta-dir { opacity: 0.75; letter-spacing: 0.02em; }
|
||||
.fsc-meta-rain { color: #2a6a90; }
|
||||
.fsc-card--now .fsc-meta-rain { color: #1a4a70; }
|
||||
|
||||
@@ -2514,11 +2688,17 @@
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
/* The curve plots a FIXED −15…45°C scale across its full height (see fscMin /
|
||||
fscMax in app.js) with preserveAspectRatio="none", so this height is the
|
||||
whole scale — every degree from freezing to danger is somewhere in these
|
||||
88px. It must not be flexible: the connector lines are drawn from the SVG's
|
||||
top edge and have to stay flush under the cards, so any height the box does
|
||||
not get is height the cold end loses off the bottom. */
|
||||
.fsc-temp-curve {
|
||||
display: block;
|
||||
width: 100%;
|
||||
flex: 1;
|
||||
min-height: 60px;
|
||||
flex: 0 0 auto;
|
||||
height: 88px;
|
||||
}
|
||||
|
||||
.fsc-table-btn-wrap {
|
||||
@@ -2566,7 +2746,7 @@
|
||||
padding: 2px 4px;
|
||||
}
|
||||
.fsc-temp-curve {
|
||||
min-height: 48px;
|
||||
height: 72px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2574,16 +2754,14 @@
|
||||
ROTATED TABLE — hours along the top, metrics down the side
|
||||
─────────────────────────────────────────────────────────────────────
|
||||
Toggled by the rotate button in the table's top-left cell (state lives
|
||||
in useAppState as tableRotated). Unlike the normal orientation — which
|
||||
is two tables kept in step by useTableScroll — this is ONE table in a
|
||||
single scroll pane, so both sticky edges are pure CSS.
|
||||
|
||||
A single table in the shared .utci-tbody-scroll horizontal scroller.
|
||||
The normal orientation splits head from body so its header can stick
|
||||
to the viewport; here the hour row scrolls away with the table by
|
||||
design, so that machinery is not needed. The metric column pins with
|
||||
plain CSS sticky, which works fine inside the scroller. The table
|
||||
keeps its natural height and the page scrolls normally.
|
||||
in useAppState as tableRotated). Built the same way as the normal
|
||||
orientation: head and body are separate tables sharing useTableScroll's
|
||||
width sync, so the hour row can stick to the viewport as the page
|
||||
scrolls. (A <thead> inside .utci-tbody-scroll can only ever stick to
|
||||
that scroller, which never scrolls vertically — so it would just
|
||||
travel away with the table.) The metric column pins with plain CSS
|
||||
sticky inside the body scroller, and the corner is held to the left
|
||||
edge by the head track's counter-translate.
|
||||
══════════════════════════════════════════════════════════════════════ */
|
||||
|
||||
/* Fallback only, for the first paint before the measurement lands.
|
||||
@@ -2591,13 +2769,14 @@
|
||||
inline — it can't be fixed here, because auto layout widens that
|
||||
column to fit the longest metric name on show. */
|
||||
.utci-table-wrap.is-rotated {
|
||||
--hour-col-w: 136px;
|
||||
--hour-col-w: 104px;
|
||||
}
|
||||
|
||||
.utci-table.utci-table-rotated {
|
||||
/* Auto layout: with a single table there are no header widths to match,
|
||||
so each hour column can simply size to its own content. */
|
||||
table-layout: auto;
|
||||
/* Fixed layout, like the normal orientation: head and body are two tables
|
||||
kept in step by useTableScroll's width sync, and only fixed layout
|
||||
honours the widths it writes onto the first row of each. */
|
||||
table-layout: fixed;
|
||||
width: max-content;
|
||||
min-width: 100%;
|
||||
/* The separate border model is required, not cosmetic. Under
|
||||
@@ -2703,9 +2882,13 @@
|
||||
/* The group rules carry a 2px left border that marks where a group STARTS
|
||||
along the columns. Rotated, groups are stacked rows and have no left
|
||||
edge to mark, so it shows up as a stray line — and its width offsets
|
||||
the label 2px against the metric names below it. */
|
||||
the label 2px against the metric names below it.
|
||||
The top rule matches .grp-label-fill's so the group boundary runs unbroken
|
||||
from the pinned label across every hour column. */
|
||||
.utci-table.utci-table-rotated tbody .grp-label-row--rotated th {
|
||||
border-left: 0;
|
||||
border-top: 2px solid rgba(74, 50, 24, 0.18);
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
/* The group heading pins with the metric names it labels. */
|
||||
@@ -2719,12 +2902,31 @@
|
||||
}
|
||||
|
||||
/* The per-hour cells filling out a divider row. They carry the group tint
|
||||
and, in the current hour's column, its share of the brass bracket. */
|
||||
and, in the current hour's column, its share of the brass bracket.
|
||||
|
||||
Composited over the SAME opaque cream base as the sticky label at the row's
|
||||
left end, for the same reason that label needs one: --grp-tint is only 50%
|
||||
opaque, so painting it straight onto the cell resolved it against the table
|
||||
background while the label resolved it against #f0e4c4. The divider then read
|
||||
as a dark cap at the left fading to a much paler band across the hours — one
|
||||
tint, two backgrounds, two colours. One base, and the row is a single shade
|
||||
end to end. The brass now-column bracket is unaffected: it is a border on
|
||||
these cells, not a background, so it still paints over the top. */
|
||||
.utci-table.utci-table-rotated tbody td.grp-label-fill {
|
||||
padding: 5px 0;
|
||||
min-width: 0;
|
||||
background: var(--grp-tint, transparent);
|
||||
border-bottom: 1px solid rgba(74, 50, 24, 0.18);
|
||||
background-color: #f0e4c4;
|
||||
background-image: linear-gradient(var(--grp-tint, transparent), var(--grp-tint, transparent));
|
||||
/* One rule, along the very top of the category block — the same 2px
|
||||
rgba(74,50,24,0.18) the unrotated table draws down the left of each new
|
||||
column group (.col-group-start), so a group boundary looks the same
|
||||
whichever way the table is turned. Nothing along the bottom: the divider
|
||||
and the metrics under it are one block, and a second line there just read
|
||||
as a double rule around the label. Every cell in the row carries the edge
|
||||
— under border-collapse:separate a <tr> border never paints, so the row's
|
||||
rule has to be drawn cell by cell (see the row-separator rule above). */
|
||||
border-top: 2px solid rgba(74, 50, 24, 0.18);
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
.utci-table.utci-table-rotated tbody th.rot-metric-label {
|
||||
@@ -2732,7 +2934,10 @@
|
||||
left: 0;
|
||||
z-index: 3;
|
||||
text-align: left;
|
||||
min-width: 136px;
|
||||
/* Was 136px, sized around the old long date in the corner. The names and
|
||||
their unit lines need far less than that, and every pixel here is taken
|
||||
straight off the hours. */
|
||||
min-width: 104px;
|
||||
/* box-shadow rather than border-right so the divider sits outside the
|
||||
cell box and cannot add to the column's measured width. */
|
||||
box-shadow: 1px 0 0 rgba(74, 50, 24, 0.18);
|
||||
@@ -2745,12 +2950,14 @@
|
||||
rule, which sets position:relative for the JS transform this view
|
||||
doesn't use. */
|
||||
.utci-table.utci-table-rotated thead th.rot-corner {
|
||||
position: sticky;
|
||||
left: 0;
|
||||
/* Left-pinned by the head-track counter-translate useTableScroll applies to
|
||||
thead th:first-child — the same device the normal orientation's Hour
|
||||
header uses. CSS sticky would do nothing here: the head table sits in a
|
||||
translated track, not in the scroller. */
|
||||
position: relative;
|
||||
z-index: 4;
|
||||
background: #f0e4c4;
|
||||
text-align: left;
|
||||
transform: none;
|
||||
box-shadow: 1px 0 0 rgba(74, 50, 24, 0.18);
|
||||
}
|
||||
.utci-table-rotated .rot-corner-date {
|
||||
@@ -2760,12 +2967,34 @@
|
||||
color: #a08040;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
/* This cell is what widens the pinned metric-name column, so the date is
|
||||
allowed to wrap rather than forcing the column past the names' width. */
|
||||
.utci-table.utci-table-rotated thead th.rot-corner {
|
||||
white-space: normal;
|
||||
}
|
||||
.utci-table-rotated .rot-corner-controls {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
/* The pinned column carries text, not figures with icons, so it does not
|
||||
need the 16px side padding the data cells use — and it is the one column
|
||||
that costs the hours their width. */
|
||||
.utci-table.utci-table-rotated thead th.rot-corner,
|
||||
.utci-table.utci-table-rotated tbody th.rot-metric-label,
|
||||
.utci-table.utci-table-rotated tbody th.rot-group-label {
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
/* Keep the interval stepper inside that width; it would otherwise set the
|
||||
column on its own. */
|
||||
.utci-table-rotated .rot-corner .row-stepper { gap: 2px; }
|
||||
.utci-table-rotated .rot-corner .row-stepper-btn { min-width: 26px; }
|
||||
.utci-table-rotated .rot-corner .row-stepper-value { min-width: 20px; }
|
||||
|
||||
@media (max-width: 640px) {
|
||||
/* Tighter segments on narrow screens — the toolbar is already tight,
|
||||
and there are three of them now. */
|
||||
@@ -2828,9 +3057,19 @@
|
||||
min-width: 68px;
|
||||
}
|
||||
.utci-table-rotated .rot-metric-label {
|
||||
min-width: 112px;
|
||||
min-width: 96px;
|
||||
}
|
||||
.utci-table.utci-table-rotated thead th.rot-corner,
|
||||
.utci-table.utci-table-rotated tbody th.rot-metric-label,
|
||||
.utci-table.utci-table-rotated tbody th.rot-group-label {
|
||||
padding-left: 8px;
|
||||
padding-right: 8px;
|
||||
}
|
||||
.utci-table-rotated .rot-corner-date {
|
||||
font-size: 9px;
|
||||
letter-spacing: 0.04em;
|
||||
}
|
||||
.utci-table-wrap.is-rotated {
|
||||
--hour-col-w: 112px;
|
||||
--hour-col-w: 96px;
|
||||
}
|
||||
}
|
||||
|
||||
+73
-18
@@ -1110,7 +1110,9 @@
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 3px;
|
||||
margin-top: 0.5rem;
|
||||
/* Was 0.5rem — the recents now follow the tool row, so they need a clearer
|
||||
break above them. */
|
||||
margin-top: 1.25rem;
|
||||
}
|
||||
/* header.css sets align-items: center for the same tablet breakpoint, but
|
||||
since ui.css is @imported after header.css in sunscope.css it wins at
|
||||
@@ -1381,9 +1383,15 @@
|
||||
}
|
||||
|
||||
.utci-app {
|
||||
padding: 52px 10px 32px;
|
||||
/* No top padding — the header is in the flow at the very top of the page.
|
||||
Was 52px, reserving space for the nav back when it was absolutely
|
||||
positioned over it. Narrowing --app-pad re-aims the header's and the
|
||||
event note's full-bleed at the same time. */
|
||||
--app-pad: 10px;
|
||||
padding: 0 var(--app-pad) 32px;
|
||||
}
|
||||
|
||||
|
||||
.utci-header {
|
||||
grid-template-columns: 1fr; /* stack the 3 header columns */
|
||||
text-align: center;
|
||||
@@ -1393,9 +1401,7 @@
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.utci-current-loc,
|
||||
.utci-loc-coords,
|
||||
.utci-fetch-time {
|
||||
.utci-current-loc {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@@ -1446,10 +1452,6 @@
|
||||
padding-top: 80px;
|
||||
}
|
||||
|
||||
.utci-fetch-time {
|
||||
text-align: center; /* override the default left-align on mobile */
|
||||
}
|
||||
|
||||
/* Hide the export panel on phones — no room for it, and the export
|
||||
actions aren't useful at this size. */
|
||||
.export-panel {
|
||||
@@ -1524,6 +1526,15 @@
|
||||
max-width: 300px;
|
||||
}
|
||||
|
||||
/* "Last update" closes the panel out — a hairline above it keeps it apart
|
||||
from the contribution rows it follows. */
|
||||
.insight-panel--why .utci-fetch-time {
|
||||
text-align: right;
|
||||
margin-top: 8px;
|
||||
padding-top: 6px;
|
||||
border-top: 1px solid #ede4cc;
|
||||
}
|
||||
|
||||
/* Solar model selector inside the Why it feels like panel */
|
||||
.insight-env-footer {
|
||||
display: flex;
|
||||
@@ -1627,10 +1638,13 @@
|
||||
}
|
||||
|
||||
/* Week rows carry a score bar, so they are a two-line grid rather than the
|
||||
single flex line the glance rows use: day and window on top, bar beneath. */
|
||||
single flex line the glance rows use: day and window on top, bar beneath.
|
||||
Day and window read as one sentence - "Sun 30 : all day" - so they sit
|
||||
together at the left rather than being pushed to opposite edges, where the
|
||||
gap between them made two short phrases look like two columns of data. */
|
||||
.insight-panel--week .insight-row {
|
||||
display: grid;
|
||||
grid-template-columns: 20px 1fr auto;
|
||||
grid-template-columns: 20px auto minmax(0, 1fr);
|
||||
grid-template-areas:
|
||||
"icon label value"
|
||||
"icon score score";
|
||||
@@ -1639,8 +1653,42 @@
|
||||
align-items: center;
|
||||
}
|
||||
.insight-panel--week .insight-icon { grid-area: icon; }
|
||||
.insight-panel--week .insight-label { grid-area: label; }
|
||||
.insight-panel--week .insight-value { grid-area: value; }
|
||||
.insight-panel--week .insight-label { grid-area: label; flex: none; }
|
||||
.insight-panel--week .insight-value {
|
||||
grid-area: value;
|
||||
text-align: left;
|
||||
flex-shrink: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
/* The separator is drawn, not written into the string, so the value stays a
|
||||
plain window ("all day") everywhere else it is used. */
|
||||
.insight-panel--week .insight-value::before {
|
||||
content: ': ';
|
||||
color: #8a8375;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
/* The washout row - no day qualified, so there is no day name and no score,
|
||||
just a sentence. Forcing it through the day-and-window layout squeezed that
|
||||
sentence into the narrow value column and stranded the colon on a line of
|
||||
its own, so it gets the full width and drops the separator. Specificity is
|
||||
raised past the rail rules below deliberately: this row stacks at every
|
||||
width. */
|
||||
.insight-panel--week .insight-row.insight-row--week-note {
|
||||
grid-template-columns: 20px minmax(0, 1fr);
|
||||
grid-template-areas:
|
||||
"icon label"
|
||||
"icon value";
|
||||
align-items: start;
|
||||
row-gap: 2px;
|
||||
}
|
||||
.insight-panel--week .insight-row--week-note .insight-icon { padding-top: 2px; }
|
||||
.insight-panel--week .insight-row--week-note .insight-value {
|
||||
font-family: Manrope, sans-serif;
|
||||
font-weight: 500;
|
||||
white-space: normal;
|
||||
}
|
||||
.insight-panel--week .insight-row--week-note .insight-value::before { content: none; }
|
||||
|
||||
/* How good the day is out of 100 — the bar does the comparing, the number
|
||||
settles close calls. */
|
||||
@@ -1765,6 +1813,7 @@
|
||||
margin: -6px 0 10px;
|
||||
}
|
||||
|
||||
|
||||
.insight-thermal-cat {
|
||||
display: inline-block;
|
||||
padding: 2px 7px;
|
||||
@@ -1930,14 +1979,20 @@
|
||||
row-gap: 1px;
|
||||
align-items: start;
|
||||
}
|
||||
/* The rail is only 240px wide, so the window drops under the day name and
|
||||
the score bar takes a third line rather than sharing one. */
|
||||
/* The rail is only 240px wide, but "Sun 30 : all day" still fits on one
|
||||
line, so the week rows keep day and window together and give the score
|
||||
bar the second line - unlike the glance rows, which stack. */
|
||||
.insight-panel--week .insight-row {
|
||||
grid-template-columns: 20px auto minmax(0, 1fr);
|
||||
grid-template-areas:
|
||||
"icon label"
|
||||
"icon value"
|
||||
"icon score";
|
||||
"icon label value"
|
||||
"icon score score";
|
||||
row-gap: 3px;
|
||||
align-items: center;
|
||||
}
|
||||
.insight-panel--week .insight-label,
|
||||
.insight-panel--week .insight-value {
|
||||
font-size: 14px;
|
||||
}
|
||||
.insight-panel--glance .insight-icon,
|
||||
.insight-panel--week .insight-icon {
|
||||
|
||||
Reference in New Issue
Block a user