Restructure
New Journal entries
Colour tabs update with wind
This commit is contained in:
fraxle
2026-08-31 15:12:45 +01:00
parent 47818fba33
commit 71860b9dd9
40 changed files with 3430 additions and 443 deletions
+180 -55
View File
@@ -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) {