Er is een vierde binnenmodule bijgekomen. De kaart verscheen al vanzelf (StationMapper leest alle NAModule4-modules uit), maar de kolom was op drie kaarten ontworpen: vier kaarten van 120px duwden de rij op 481px en daarmee de onderste strook 39px voorbij de onderrand van het canvas. De kolom heeft nu een vaste hoogte van 412px met overflow verborgen, en fitRooms() verkleint de inhoud met een schaal zodra die niet past. Bij drie modules verandert er niets (schaal 1), bij vier wordt het 0,86 en met een vastgezette module 0,78. Zo blijft het scherm kloppen, ongeacht hoeveel modules erbij komen. De dev-fixture heeft er een vierde module bij, zodat dit lokaal te zien is zonder Netatmo-koppeling. Servicewerker naar v12. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
257 lines
11 KiB
CSS
257 lines
11 KiB
CSS
/* Weerscherm, ontwerp A. Vast canvas van 1133 × 744 dat via JS geschaald en gecentreerd wordt. */
|
||
|
||
:root {
|
||
--bg: #E8EDF1;
|
||
--ink: #1B2A35;
|
||
--muted: #5F707C;
|
||
--line: #C6D0D8;
|
||
--warm: #B8761C;
|
||
--cold: #3A75A3;
|
||
--rain: #2E6A99;
|
||
--sun: #D39A2C;
|
||
--good: #4E8F5A;
|
||
--bad: #B5433B;
|
||
--iconfill: #E8EDF1;
|
||
--w: 1133px;
|
||
--h: 744px;
|
||
}
|
||
|
||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||
|
||
html, body {
|
||
height: 100%;
|
||
overflow: hidden;
|
||
background: var(--bg);
|
||
color: var(--ink);
|
||
font-family: -apple-system, "SF Pro Display", system-ui, "Segoe UI", Roboto, sans-serif;
|
||
font-variant-numeric: tabular-nums;
|
||
-webkit-text-size-adjust: none;
|
||
-webkit-user-select: none;
|
||
user-select: none;
|
||
-webkit-touch-callout: none;
|
||
}
|
||
|
||
[hidden] { display: none !important; }
|
||
|
||
#viewport {
|
||
position: fixed;
|
||
top: env(safe-area-inset-top, 0px);
|
||
right: env(safe-area-inset-right, 0px);
|
||
bottom: env(safe-area-inset-bottom, 0px);
|
||
left: env(safe-area-inset-left, 0px);
|
||
overflow: hidden;
|
||
}
|
||
|
||
#stage {
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
width: var(--w);
|
||
height: var(--h);
|
||
transform-origin: top left;
|
||
display: grid;
|
||
padding: 30px 44px;
|
||
grid-template-columns: 1fr 330px;
|
||
grid-template-rows: 40px 1fr 232px;
|
||
column-gap: 56px;
|
||
background: var(--bg);
|
||
}
|
||
|
||
.num { font-variant-numeric: tabular-nums; }
|
||
.cold { color: var(--cold); }
|
||
.warm { color: var(--warm); }
|
||
.muted { color: var(--muted); }
|
||
|
||
.ic, .wind-ic { fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; width: 100%; height: 100%; display: block; }
|
||
.i-sun { stroke: var(--sun); }
|
||
.i-drop { stroke: var(--rain); }
|
||
.i-cloud { fill: var(--iconfill); }
|
||
|
||
/* Kopregel */
|
||
.a-top { grid-column: 1 / -1; display: flex; justify-content: space-between; align-items: baseline; }
|
||
.a-date { font-size: 22px; font-weight: 500; }
|
||
.a-right { display: flex; gap: 18px; align-items: baseline; }
|
||
.a-status { font-size: 15px; color: var(--warm); }
|
||
.a-upd { font-size: 15px; color: var(--muted); }
|
||
.a-upd.stale { color: var(--warm); }
|
||
.a-clock { font-size: 26px; font-weight: 300; }
|
||
|
||
/* Buiten */
|
||
.a-hero { align-self: center; }
|
||
.a-label { font-size: 22px; color: var(--muted); font-weight: 500; display: flex; gap: 14px; align-items: baseline; }
|
||
.a-trend { font-size: 17px; font-weight: 400; }
|
||
.a-temprow { display: flex; align-items: center; gap: 28px; margin: 4px 0 10px 0; }
|
||
.a-temp { font-size: 200px; font-weight: 200; letter-spacing: -.045em; line-height: .95; margin-left: -8px; }
|
||
|
||
/* Temperatuurverloop van vandaag, in de ruimte rechts van het grote getal */
|
||
.a-today { flex: 1; min-width: 0; }
|
||
.a-today[hidden] { display: none; }
|
||
.a-tcap { font-size: 15px; color: var(--muted); margin-bottom: 4px; }
|
||
.a-tspark { display: block; width: 100%; height: 96px; overflow: visible; }
|
||
.a-hum { font-size: 17px; font-weight: 400; }
|
||
.a-hum:not(:empty)::before { content: "·"; margin-right: 14px; }
|
||
.a-range { width: 560px; }
|
||
.a-track { position: relative; height: 12px; border-radius: 6px; background: linear-gradient(90deg, var(--cold), var(--warm)); }
|
||
.a-mark { position: absolute; top: 50%; width: 28px; height: 28px; border-radius: 50%; background: var(--bg); border: 5px solid var(--ink); transform: translate(-50%, -50%); transition: left .6s ease; }
|
||
.a-ends { display: flex; justify-content: space-between; margin-top: 14px; font-size: 17px; color: var(--muted); }
|
||
.a-ends b { font-size: 24px; font-weight: 600; margin-right: 6px; }
|
||
|
||
/* Luchtdruk, 24 uur. Grafiek met een y-as (hoogste/laagste waarde) en tijdlabels op de x-as. */
|
||
.a-pressure { width: 560px; margin-top: 14px; }
|
||
.a-plabel { font-size: 17px; color: var(--muted); display: flex; gap: 12px; align-items: baseline; margin-bottom: 6px; }
|
||
.a-plabel b { font-size: 20px; font-weight: 600; color: var(--ink); }
|
||
.a-pgrid { display: grid; grid-template-columns: 44px 1fr; column-gap: 8px; row-gap: 3px; }
|
||
.a-py { display: flex; flex-direction: column; justify-content: space-between; text-align: right; font-size: 13px; color: var(--muted); line-height: 1; padding: 1px 0; }
|
||
.a-px { position: relative; height: 17px; font-size: 13px; color: var(--muted); }
|
||
.a-px span { position: absolute; top: 0; white-space: nowrap; }
|
||
.a-spark { display: block; width: 100%; height: 56px; overflow: visible; }
|
||
.a-spark-base { stroke: var(--line); stroke-width: 1; }
|
||
.a-spark-grid { stroke: var(--line); stroke-width: 1; vector-effect: non-scaling-stroke; opacity: .6; }
|
||
.a-spark-line { fill: none; stroke: var(--rain); stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; vector-effect: non-scaling-stroke; }
|
||
|
||
/* Binnen. Vaste hoogte met overflow verborgen: hoeveel modules er ook zijn, de kolom duwt nooit de
|
||
onderste strook van het scherm af. Past de inhoud niet, dan verkleint fitRooms() hem met een schaal. */
|
||
.a-inside { align-self: center; height: 412px; display: flex; align-items: center; overflow: hidden; }
|
||
#rooms { width: 100%; transform-origin: center center; }
|
||
.a-room { padding: 12px 0; border-top: 1px solid var(--line); }
|
||
.a-room:first-child { border-top: 0; }
|
||
.a-rname { font-size: 19px; color: var(--muted); display: flex; justify-content: space-between; align-items: center; }
|
||
.pill { display: inline-block; font-size: 13px; font-weight: 600; line-height: 1; padding: 5px 10px; border-radius: 999px; color: #fff; background: var(--muted); letter-spacing: .01em; white-space: nowrap; }
|
||
.pill.good { background: var(--good); }
|
||
.pill.medium { background: var(--warm); }
|
||
.pill.bad { background: var(--bad); }
|
||
.pill.unknown { background: var(--line); color: var(--muted); }
|
||
.a-rrow { display: flex; align-items: center; gap: 16px; }
|
||
.a-rtemp { font-size: 50px; font-weight: 300; line-height: 1.05; transition: font-size .25s ease; flex: none; }
|
||
/* Overal even hoog: zo zijn de kamers onderling vergelijkbaar, en groeit een vastgezette kaart niet
|
||
zo ver door dat de speling onder de kolom opraakt. */
|
||
.a-rspark { flex: 1; min-width: 0; height: 40px; overflow: visible; }
|
||
.a-room.off .a-rtemp { color: var(--muted); }
|
||
.a-room.pinned .a-rtemp { font-size: 92px; }
|
||
.a-rmm { font-size: 17px; display: flex; gap: 18px; }
|
||
.a-rmm .rv { color: var(--muted); }
|
||
|
||
/* Onderste strook */
|
||
.a-bottom { grid-column: 1 / -1; border-top: 1px solid var(--line); padding-top: 22px; display: grid; grid-template-columns: 390px 1fr; column-gap: 36px; }
|
||
.a-sub { font-size: 19px; color: var(--muted); font-weight: 500; margin-bottom: 10px; }
|
||
.a-rainrow { display: flex; justify-content: space-between; align-items: flex-end; }
|
||
.a-rbig { font-size: 22px; color: var(--rain); }
|
||
.a-rbig span { font-size: 60px; font-weight: 300; line-height: 1; }
|
||
.a-rsm { font-size: 17px; color: var(--muted); }
|
||
.a-month { font-size: 17px; margin-top: 18px; color: var(--muted); white-space: nowrap; }
|
||
.a-month b { color: var(--ink); font-weight: 600; font-size: 20px; margin-left: 4px; }
|
||
.a-bars { display: flex; gap: 6px; align-items: flex-end; }
|
||
.a-bar { display: flex; flex-direction: column; align-items: center; gap: 5px; font-size: 14px; color: var(--muted); min-width: 38px; }
|
||
.a-bar i { display: block; width: 24px; border-radius: 4px 4px 0 0; background: var(--rain); opacity: .4; transition: height .6s ease; }
|
||
.a-bar.now i { opacity: 1; }
|
||
.a-bar.now span { color: var(--ink); font-weight: 600; }
|
||
|
||
/* Verwachting */
|
||
.a-fc { display: grid; grid-template-columns: repeat(6, 1fr); text-align: center; }
|
||
.a-day { display: flex; flex-direction: column; align-items: center; gap: 6px; border-left: 1px solid var(--line); }
|
||
.a-day:first-child { border-left: 0; }
|
||
.a-dname { font-size: 19px; font-weight: 600; }
|
||
.a-icon { width: 50px; height: 50px; }
|
||
.a-hl { font-size: 28px; font-weight: 500; }
|
||
.a-hl span { font-size: 22px; color: var(--muted); font-weight: 400; margin-left: 6px; }
|
||
.a-fr { font-size: 16px; color: var(--rain); }
|
||
.a-fr span { color: var(--muted); margin-left: 6px; }
|
||
|
||
/* Meldingen */
|
||
.banner {
|
||
position: absolute;
|
||
left: 44px;
|
||
right: 44px;
|
||
top: 86px;
|
||
height: 396px;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
text-align: center;
|
||
padding: 40px 60px;
|
||
font-size: 30px;
|
||
line-height: 1.4;
|
||
color: var(--ink);
|
||
background: var(--bg);
|
||
border: 1px solid var(--line);
|
||
border-radius: 18px;
|
||
z-index: 2;
|
||
}
|
||
.banner small { display: block; margin-top: 16px; font-size: 20px; color: var(--muted); }
|
||
|
||
/* Overlays (uuroverzicht, regenradar): tik om te openen, tik erop of wacht 20s om te sluiten.
|
||
De .ho-*-chrome (balk, kop) wordt door beide overlays gedeeld. */
|
||
.overlay {
|
||
position: absolute;
|
||
left: 44px;
|
||
right: 44px;
|
||
top: 40px;
|
||
bottom: 40px;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 22px;
|
||
padding: 26px 0 22px;
|
||
background: var(--bg);
|
||
border: 1px solid var(--line);
|
||
border-radius: 18px;
|
||
box-shadow: 0 12px 32px rgba(27, 42, 53, .12);
|
||
z-index: 5;
|
||
}
|
||
.overlay[hidden] { display: none; }
|
||
|
||
.ho-bar { margin: 0 30px; height: 4px; border-radius: 2px; background: var(--line); overflow: hidden; }
|
||
.ho-bar i { display: block; width: 100%; height: 100%; background: var(--rain); transform-origin: left; }
|
||
|
||
.ho-head { margin: 0 30px; display: flex; justify-content: space-between; align-items: baseline; }
|
||
.ho-date { font-size: 22px; font-weight: 500; }
|
||
.ho-hint { font-size: 16px; color: var(--muted); }
|
||
|
||
.ho-grid { display: grid; grid-template-columns: repeat(12, 1fr); text-align: center; }
|
||
|
||
.ho-temp { display: flex; flex-direction: column; gap: 6px; }
|
||
#ho-temp-nums .num { font-size: 22px; font-weight: 500; }
|
||
.ho-temp-svg { display: block; width: 100%; height: 64px; }
|
||
.ho-temp-line { fill: none; stroke: var(--ink); stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; vector-effect: non-scaling-stroke; }
|
||
|
||
.ho-rain .ho-rbar { display: flex; flex-direction: column; align-items: center; justify-content: flex-end; gap: 6px; height: 66px; }
|
||
.ho-rbar i { display: block; width: 14px; border-radius: 3px 3px 0 0; background: var(--rain); opacity: .55; }
|
||
.ho-rbar .num { font-size: 14px; color: var(--muted); }
|
||
|
||
.ho-wind .ho-wcell { display: flex; flex-direction: column; align-items: center; gap: 6px; }
|
||
.ho-warrow { display: flex; align-items: center; justify-content: center; width: 26px; height: 26px; color: var(--muted); }
|
||
.ho-warrow.off { font-size: 18px; }
|
||
.ho-wcell .num { font-size: 15px; color: var(--muted); }
|
||
|
||
.ho-hours span { font-size: 16px; color: var(--muted); }
|
||
|
||
/* Regenradar */
|
||
.ro-body { display: flex; gap: 56px; margin: 0 30px; min-height: 0; }
|
||
.ro-map { display: flex; align-items: center; justify-content: center; width: 560px; flex: none; }
|
||
.ro-img { height: 512px; width: auto; display: block; border-radius: 10px; }
|
||
.ro-status { font-size: 22px; color: var(--muted); }
|
||
|
||
.ro-side { display: flex; flex-direction: column; justify-content: center; }
|
||
.ro-big { font-size: 26px; color: var(--rain); }
|
||
.ro-big span { font-size: 76px; font-weight: 300; line-height: 1; }
|
||
.ro-sub { font-size: 19px; color: var(--muted); margin-bottom: 26px; }
|
||
.ro-days p { display: flex; justify-content: space-between; width: 260px; font-size: 21px; color: var(--muted); padding: 7px 0; border-top: 1px solid var(--line); }
|
||
.ro-days b { color: var(--ink); font-weight: 600; }
|
||
.ro-month { width: 260px; font-size: 19px; color: var(--muted); margin-top: 18px; }
|
||
.ro-source { font-size: 15px; color: var(--muted); margin-top: auto; padding-top: 22px; }
|
||
|
||
#rotate {
|
||
display: none;
|
||
position: fixed;
|
||
top: 0; right: 0; bottom: 0; left: 0;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 30px;
|
||
color: var(--muted);
|
||
background: var(--bg);
|
||
z-index: 10;
|
||
}
|
||
@media (orientation: portrait) {
|
||
#rotate { display: flex; }
|
||
}
|