Updated event banner to fit top screen
Updated table thermal colours to max hot and min cold for 2h, 3h & 4h
Ground Lab preview
This commit is contained in:
fraxle
2026-08-01 16:18:15 +01:00
parent 2869694634
commit e55e0df86f
15 changed files with 406 additions and 380 deletions
+153 -1
View File
@@ -94,7 +94,7 @@ body {
display: flex;
align-items: center;
justify-content: flex-end;
padding: 18px 32px;
padding: 0px 32px;
gap: 28px;
}
@@ -188,6 +188,158 @@ body {
border-bottom: none;
}
/* ── 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.
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. */
.event-note {
display: flex;
align-items: baseline;
gap: 11px;
padding: 10px 15px;
margin-bottom: 14px;
background: #fdf8ee;
border: 1.5px solid #c9b08a;
border-radius: 4px;
position: relative;
overflow: hidden;
animation: event-note-in 0.35s cubic-bezier(0.34, 1.25, 0.64, 1) both;
}
@keyframes event-note-in {
from { opacity: 0; transform: translateY(-5px); }
to { opacity: 1; transform: translateY(0); }
}
/* Per-event colour, kept to a hairline so the strip stays parchment —
same device as .almanac-entry-accent. */
.event-note-accent {
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 3px;
opacity: 0.75;
}
/* Safety-relevant weather (heat, frost, storm, wind, wet) — brass emphasis */
.event-note.is-priority {
background: #f0e4c4;
border-color: #c8922a;
}
.event-note-slide {
display: flex;
align-items: baseline;
flex-wrap: wrap;
gap: 4px 10px;
flex: 1;
min-width: 0;
opacity: 1;
transition: opacity 0.35s ease;
}
.event-note-slide.is-fading {
opacity: 0;
}
.event-note-emoji {
font-size: 16px;
line-height: 1;
flex-shrink: 0;
}
.event-note-title {
font-family: Fraunces, serif;
font-style: italic;
font-weight: 700;
font-size: 14px;
color: #2a1a08;
flex-shrink: 0;
}
.event-note-msg {
font-family: Manrope, sans-serif;
font-size: 12.5px;
font-weight: 500;
line-height: 1.45;
color: #6b4f2a;
min-width: 0;
}
.event-note-dates {
font-family: Manrope, sans-serif;
font-size: 10px;
font-weight: 700;
letter-spacing: 0.06em;
text-transform: uppercase;
color: #9a7d5a;
white-space: nowrap;
margin-left: auto; /* push the dates to the right-hand end */
flex-shrink: 0;
}
.event-note.is-priority .event-note-dates {
color: #a06e18;
}
.event-note-dots {
display: flex;
align-items: center;
gap: 6px;
flex-shrink: 0;
align-self: center;
}
.event-note-dot {
width: 6px;
height: 6px;
padding: 0;
border: none;
border-radius: 50%;
background: #d9c39b;
cursor: pointer;
transition: background 0.2s, transform 0.2s;
}
.event-note-dot:hover {
background: #c0a880;
}
.event-note-dot.active {
background: #c8922a;
transform: scale(1.3);
}
/* 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;
}
}
@media (max-width: 640px) {
.event-note {
align-items: flex-start;
gap: 9px;
padding: 10px 12px;
}
.event-note-dates {
margin-left: 0; /* no room to right-align on a phone */
}
}
/* Nav logo — hidden on desktop, shown on mobile */
.nav-logo {
display: none;
-170
View File
@@ -2,136 +2,6 @@
ui.css — Status banners, legend, about block, footer, and responsive.
════════════════════════════════════════════════════════════════════════ */
/* ── EVENT BANNER ───────────────────────────────────────────────────── */
/* Animated slide-down banner for cosmic/weather/promo events. */
/* Flyout: a fixed panel pinned to the very top of the screen that slides
down over everything (including the nav) and retracts upward on close. */
.event-banner-wrap {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 9999;
display: flex;
justify-content: center;
padding: 0 14px;
transform: translateY(-130%);
transition: transform 0.5s cubic-bezier(0.34, 1.25, 0.64, 1);
/* The wrap is full-width but the panel is centred — keep the wrap itself
click-through so its transparent sides never block the nav beneath it.
Only the visible banner panel (.event-banner) captures clicks. */
pointer-events: none;
}
.event-banner-wrap.visible {
transform: translateY(0);
}
/* Slide crossfade: both banners rendered simultaneously, fading into each other */
@keyframes banner-fade-in {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes banner-fade-out {
from { opacity: 1; }
to { opacity: 0; }
}
/* Container that holds both slides during a crossfade. Constrains the
flyout to a centred panel width and clips the absolute outgoing slide. */
.event-banner-stage {
position: relative;
overflow: hidden;
width: 100%;
max-width: 720px;
}
/* True crossfade — outgoing slide sits absolutely on top and fades out */
.event-banner {
display: flex;
align-items: center;
gap: 14px;
padding: 14px 18px;
border-radius: 0 0 12px 12px; /* rounded bottom — it hangs from the top edge */
position: relative;
z-index: 1;
border-left: 4px solid rgba(255,255,255,0.25);
box-shadow: 0 12px 32px rgba(0, 0, 0, 0.3);
cursor: pointer; /* whole banner is click-to-close */
pointer-events: auto; /* re-enable clicks on the panel itself */
}
.event-banner--outgoing {
position: absolute;
top: 0;
left: 0;
width: 100%;
z-index: 2;
pointer-events: none;
animation: banner-fade-out 0.45s ease both;
}
.event-banner-emoji {
font-size: 24px;
flex-shrink: 0;
line-height: 1;
}
.event-banner-body {
flex: 1;
min-width: 0;
}
.event-banner-title {
font-family: Fraunces, serif;
font-style: italic;
font-weight: 700;
font-size: 16px;
line-height: 1.2;
margin-bottom: 3px;
}
.event-banner-msg {
font-family: Manrope, sans-serif;
font-size: 12.5px;
line-height: 1.55;
opacity: 0.88;
}
.event-banner-dismiss {
background: transparent;
border: none;
cursor: pointer;
font-size: 18px;
opacity: 0.55;
padding: 4px 6px;
line-height: 1;
flex-shrink: 0;
transition: opacity 0.15s;
}
.event-banner-dismiss:hover {
opacity: 1;
}
/* Slideshow dots */
.event-banner-dots {
display: flex;
gap: 10px;
margin-top: 7px;
align-items: center;
padding: 5px 0;
}
.event-banner-dot {
width: 10px;
height: 10px;
border-radius: 50%;
opacity: 0.35;
cursor: pointer;
transition: opacity 0.2s, transform 0.2s;
flex-shrink: 0;
}
.event-banner-dot.active {
opacity: 1;
transform: scale(1.3);
}
.event-banner-dot:hover {
opacity: 0.75;
}
/* Cell tag — event icon in the hour column */
.event-cell-tag {
font-size: 15px;
@@ -312,46 +182,6 @@
}
}
/* ── EVENT BANNER — mobile fixes ────────────────────────────────────── */
@media (max-width: 640px) {
.event-banner-wrap {
padding: 0; /* full-bleed flyout on small screens */
}
.event-banner {
align-items: flex-start; /* stop dismiss ✕ drifting downward */
gap: 10px;
padding: 18px 12px 14px 14px;
margin-bottom: 0;
border-radius: 0 0 12px 12px;
}
.event-banner-emoji {
font-size: 20px;
margin-top: 3px; /* visually balance the dates-line margin-top below */
}
.event-banner-title {
font-size: 15px;
line-height: 1.25;
margin-bottom: 3px;
}
.event-banner-msg {
font-size: 12px;
line-height: 1.5;
}
.event-banner-dismiss {
margin-top: 0; /* keep ✕ pinned flush to the top-right */
padding: 0 2px;
font-size: 16px;
line-height: 1.4;
flex-shrink: 0;
align-self: flex-start;
}
}
/* ── CUSTOM SELECT DROPDOWN ─────────────────────────────────────────── */
/* Cross-platform replacement for native <select> on the col-toggles bar */