/* Weather, in Liquid Glass: the sky behind, and in front of it glass that's
   clear rather than frosted, saturated by what's behind it, lit along its rim
   where the light catches, with a sheen across the top, floating on its own
   shadow. Controls are capsules and circles of the same glass that give
   under a finger and spring back. (Browsers can't bend the light behind glass
   the way the phone does, so the lensing is suggested by the rim and the
   sheen.) With Reduce Transparency on, everything turns solid. */
:root {
  --text: #ffffff;
  --text-2: rgba(255, 255, 255, 0.84);
  --text-3: rgba(255, 255, 255, 0.8);
  --line: rgba(255, 255, 255, 0.14);
  --temp: #D07A12;
  --rain: #3B8BE0;
  --wind: #14A08F;
  --warn: #ffb020;
  --alert: #ff5a4f;
  --good: #34c759;
  --tint-blue: #9fd0ff;
  --rain-text: var(--tint-blue);   /* the chances of rain (paler on the palest skies: body) */
  /* the motion, as every app on the site has it: out (quick, then settling), the glide (iOS's own, for things that rise
     and slide: quick then soft, no overshoot), in (for what leaves), and a soft spring (about 2% over, then back: for
     what's let go of, never for a fade); and how long each kind of thing takes */
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-glide: cubic-bezier(0.32, 0.72, 0, 1);
  --ease-in: cubic-bezier(0.4, 0, 1, 1);
  --ease-spring: linear(0, 0.019, 0.067, 0.135, 0.214, 0.3, 0.388, 0.473, 0.553, 0.628, 0.695, 0.755, 0.807, 0.852, 0.89, 0.921, 0.947, 0.968, 0.984, 0.996, 1.005, 1.012, 1.016, 1.018, 1.02, 1.02, 1.019, 1.018, 1.017, 1.015, 1.013, 1.012, 1.01, 1.008, 1.007, 1.006, 1.005, 1.004, 1.003, 1);
  --dur-press: 0.1s; --dur-release: 0.45s; --dur-fast: 0.2s; --dur-base: 0.35s; --dur-sheet-in: 0.5s; --dur-sheet-out: 0.34s;
  /* (Weather's own names for them) */
  --ease: var(--ease-out);
  --glide: var(--ease-glide);
  --spring: var(--ease-spring);
  --pad: 16px;
  --card-x: 18px;                /* a card's side margins */
  /* the glass */
  --tint: rgba(14, 22, 38, 0.36);               /* panels: how much the glass darkens what's behind (more over a pale sky: body) */
  --tint-ctl: rgba(255, 255, 255, 0.12);        /* controls: lighter, clearer glass */
  --blur: blur(22px) saturate(190%) brightness(1.04);      /* (iOS 27's: diffusing busy things behind it more) */
  --blur-ctl: blur(10px) saturate(200%) brightness(1.08);
  --sheen: radial-gradient(140% 90% at 12% -20%, rgba(255, 255, 255, 0.24), rgba(255, 255, 255, 0) 46%);
  --body: linear-gradient(180deg, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0.015) 48%, rgba(255, 255, 255, 0.035));
  --edge: inset 0 1px 0.5px rgba(255, 255, 255, 0.55), inset 0 -1px 0.5px rgba(255, 255, 255, 0.12), inset 0 0 22px rgba(255, 255, 255, 0.04);
  /* (iOS 27's darker edge round the glass, a hairline outside its bright rim, setting it apart from what's behind) */
  --lift: 0 0 0 0.5px rgba(0, 0, 0, 0.34), 0 14px 34px -10px rgba(0, 0, 0, 0.38), 0 2px 6px rgba(0, 0, 0, 0.12);
  --rim: linear-gradient(135deg, rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.12) 28%, rgba(255, 255, 255, 0.03) 55%, rgba(255, 255, 255, 0.12) 78%, rgba(255, 255, 255, 0.55));
  --r-card: 26px;
  --r-inner: 18px;
  color-scheme: dark;
}
/* (where linear() isn't understood: a curve with the same little overshoot) */
@supports not (transition-timing-function: linear(0, 1)) { :root { --ease-spring: cubic-bezier(0.2, 1.1, 0.4, 1); } }
/* the page's panels: tinted glass that isn't blurred afresh as the page scrolls (blurring every card at every frame cost
   a phone most of its frames), its tint for each sky worked out to look as the blurred glass did over it. What's behind
   a card is only ever the sky, a soft gradient blurring hardly changes: what it did change, the blur's richer, lighter
   colour, the tint gives instead (--pane: as Settings has the glass, as iOS 27's Liquid Glass slider, clear (--pane-c),
   between, or tinted (--pane-t)). The top bar and the sheets, over the page's own busy content, are still blurred */
body { --pane: 14 22 38 / 0.36; --pane-c: 14 22 38 / 0.2; --pane-t: 12 21 40 / 0.68; --pane-now: var(--pane); --tint: rgb(var(--pane-now)); }
body[data-sky="clear-day"] { --pane: 0 63 113 / 0.61; --pane-c: 0 99 181 / 0.44; --pane-t: 12 20 36 / 0.88; }
body[data-sky="partly-day"] { --pane: 0 25 87 / 0.43; --pane-c: 0 27 187 / 0.19; --pane-t: 13 22 39 / 0.90; }
body[data-sky="cloudy-day"] { --pane: 0 17 77 / 0.29; --pane-c: 0 13 156 / 0.12; --pane-t: 10 21 40 / 0.66; }
body[data-sky="rain-day"] { --pane: 0 15 77 / 0.28; --pane-c: 0 6 170 / 0.10; --pane-t: 11 22 41 / 0.67; }
body[data-sky="storm"] { --pane: 11 32 92 / 0.33; --pane-c: 12 44 147 / 0.19; --pane-t: 16 26 48 / 0.61; }
body[data-sky="snow-day"] { --pane: 0 21 63 / 0.43; --pane-c: 0 21 115 / 0.20; --pane-t: 13 21 38 / 0.89; }
body[data-sky="fog"] { --pane: 0 16 45 / 0.41; --pane-c: 0 4 66 / 0.17; --pane-t: 13 21 38 / 0.89; }
body[data-sky="clear-night"] { --pane: 0 0 255 / 0.05; --pane-c: 0 0 205 / 0.05; --pane-t: 9 21 46 / 0.50; }
body[data-sky="partly-night"] { --pane: 0 15 136 / 0.15; --pane-c: 0 0 255 / 0.05; --pane-t: 10 22 46 / 0.53; }
body[data-sky="cloudy-night"] { --pane: 0 0 94 / 0.13; --pane-c: 0 0 163 / 0.05; --pane-t: 10 21 42 / 0.53; }
body[data-sky="rain-night"] { --pane: 0 26 81 / 0.24; --pane-c: 0 41 159 / 0.11; --pane-t: 14 25 45 / 0.60; }
body[data-sky="snow-night"] { --pane: 0 2 101 / 0.15; --pane-c: 0 0 232 / 0.05; --pane-t: 9 21 43 / 0.53; }
body[data-sky="dusk"] { --pane: 5 0 20 / 0.31; --pane-c: 0 0 0 / 0.05; --pane-t: 14 21 38 / 0.89; }
body[data-sky="dawn"] { --pane: 0 0 9 / 0.41; --pane-c: 0 0 0 / 0.05; --pane-t: 12 20 37 / 0.88; }
body[data-glass="clear"] { --pane-now: var(--pane-c); --blur: blur(12px) saturate(180%) brightness(1.05); --tint-ctl: rgba(255, 255, 255, 0.08); }
body[data-glass="tinted"] { --pane-now: var(--pane-t); --blur: blur(30px) saturate(140%); --tint-ctl: rgba(40, 52, 76, 0.62); }
/* (on the palest skies, the secondary words, the chances of rain and "Uncertain" a little stronger: as far as 4.5:1 over
   the standard glass takes, the panes left as they were tuned, but for dawn's, a little deeper, where even white fell
   short over it. With contrast turned up, its own, below) */
@media not all and (prefers-contrast: more) {
  body:is([data-sky$="-day"], [data-sky="fog"], [data-sky="dusk"], [data-sky="dawn"]) { --text-2: rgba(255, 255, 255, 0.9); --text-3: rgba(255, 255, 255, 0.86); --rain-text: #d8edff; --unsure: #ffe8b8; }
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-padding-top: 76px; -webkit-tap-highlight-color: transparent; }
body {
  margin: 0; min-height: 100vh; min-height: 100svh;
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "SF Pro Display", "Segoe UI", Roboto, "Helvetica Neue", system-ui, sans-serif;
  color: var(--text); -webkit-font-smoothing: antialiased; line-height: 1.4;
  padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
  overflow-x: clip;      /* (the top bar's glass reaches the screen's edges: never past them, under a scrollbar) */
}
button, input, select { font: inherit; color: inherit; }
/* an app, not a page: its words aren't selected (so not copied) by a long press or a drag, and nothing calls up a menu
   or a link's preview; what you type into (search, settings) still takes typing, cutting, copying and pasting */
html { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
input, textarea, select, [contenteditable] { -webkit-user-select: text; user-select: text; -webkit-touch-callout: default; }
img, svg, a { -webkit-user-drag: none; }
/* an icon in a span (app.js h): just the icon, with no room under it for a line of text's descenders, which left icons
   sitting high in their buttons and rows */
.ic { display: inline-grid; }
a { color: inherit; }
.sr-only { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }
.muted { color: var(--text-3); }
.small { font-size: 13px; }
[hidden] { display: none !important; }
:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }

/* ---------- the glass ---------- */
/* panels */
.card, .ins, .tile, .section-title, dialog.sheet, .c-tip {
  position: relative; isolation: isolate; border: 0;
  background-color: var(--tint);
  background-image: var(--sheen), var(--body);
  box-shadow: var(--edge), var(--lift);
  /* (its tint eased, as the sky's changes it or Settings' Glass does, rather than snapped) */
  transition: background-color var(--dur-base) var(--ease), --la 0.3s var(--ease);
}
dialog.sheet { -webkit-backdrop-filter: var(--blur); backdrop-filter: var(--blur); }
/* (where there's a pointer, the light it casts across the glass, on the pane it's over (app.js lit): where it is, --lx
   and --ly, the pane's own and not passed on to what's in it, so the pointer moving restyles that pane alone; and only
   that pane repainted as the page scrolls, its light fixed to the screen; a phone's panels are spared it. It comes up
   on the pane the pointer moves on to as it goes down on the one it's left (--la: how bright, eased; .unlit, a moment)) */
@property --lx { syntax: "<length>"; inherits: false; initial-value: -9999px; }
@property --ly { syntax: "<length>"; inherits: false; initial-value: -9999px; }
@property --la { syntax: "<number>"; inherits: false; initial-value: 0; }
@media (hover: hover) and (pointer: fine) {
  :is(.card, .ins, .tile, .section-title, dialog.sheet, .c-tip):is(.lit, .unlit) {
    background-image: radial-gradient(520px circle at var(--lx) var(--ly), rgba(255, 255, 255, calc(0.07 * var(--la, 1))), transparent 45%), var(--sheen), var(--body);
    background-attachment: fixed, scroll, scroll; }
  :is(.card, .ins, .tile, .section-title, dialog.sheet, .c-tip).lit { --la: 1; }
  :is(.card, .ins, .tile, .section-title, dialog.sheet, .c-tip).unlit { --la: 0; }
}
/* controls */
.icon-btn, .place, .pill-btn, .seg, .radar-chip, .radar-hint, .search input, fieldset.opt label, .win-rate, .best,
.map-zoom, :is(.radar-centre, .map-layers), .radar-credit {
  position: relative; isolation: isolate; border: 0;
  background-color: var(--tint-ctl);
  background-image: var(--sheen), var(--body);
  -webkit-backdrop-filter: var(--blur-ctl); backdrop-filter: var(--blur-ctl);
  box-shadow: inset 0 1px 0.5px rgba(255, 255, 255, 0.6), inset 0 -1px 0.5px rgba(255, 255, 255, 0.14), 0 0 0 0.5px rgba(0, 0, 0, 0.3), 0 6px 18px -6px rgba(0, 0, 0, 0.35);
}
/* (on a card, over the card: badges, and the card's own buttons; blurred, they'd each cost a layer for nothing. Over the
   radar's map, full screen, its buttons are) */
.win-rate, .best, main .card :is(.seg, .pill-btn, .icon-btn) { -webkit-backdrop-filter: none; backdrop-filter: none; }
main .radar.radar-big .icon-btn { -webkit-backdrop-filter: var(--blur-ctl); backdrop-filter: var(--blur-ctl); }
/* the rim: a hairline that's bright where the light catches it, top left and bottom right */
.card::before, .ins::before, .tile::before, .section-title::before, dialog.sheet::before, .c-tip::before,
.icon-btn::before, .place::before, .pill-btn::before, .seg::after, .radar-chip::before, .map-zoom::before, :is(.radar-centre, .map-layers)::before, .radar-credit::before, .win-rate::before, .best::before {
  content: ""; position: absolute; inset: 0; border-radius: inherit; padding: 1px; pointer-events: none; z-index: 2;
  background: var(--rim);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
}
/* glass on glass: things inside a panel */
.win, .stat, .part, .hour.now, .act-edit, .choice, .credits, .detail-now, .way {
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.04));
  box-shadow: inset 0 1px 0.5px rgba(255, 255, 255, 0.3), inset 0 -1px 0.5px rgba(255, 255, 255, 0.06), inset 0 0 0 0.5px rgba(255, 255, 255, 0.08);
}
/* give under a finger, spring back (buttons); rows and choices light a little instead (shrinking, they'd lurch) */
.icon-btn, .place, .pill-btn, .day-row, .row-btn, :is(.radar-centre, .map-layers), .link {
  transition: transform var(--dur-release) var(--spring), background-color 0.25s, filter 0.25s, opacity var(--dur-fast);
}
.icon-btn:active, .place:active, .pill-btn:active, :is(.radar-centre, .map-layers):active { transform: scale(0.92); filter: brightness(1.18); transition-duration: var(--dur-press); }
fieldset.opt label { transition: filter 0.2s, color 0.25s; }
fieldset.opt label:active { filter: brightness(1.15); transition-duration: var(--dur-press); }
.day-row:active, .row-btn:active { transform: scale(0.985); transition-duration: var(--dur-press); }
@media (hover: hover) {
  .icon-btn:hover, .place:hover, .pill-btn:hover, :is(.radar-centre, .map-layers):hover { filter: brightness(1.15); }
}

/* ---------- the sky ---------- */
/* each sky four colours down the screen (--s1 to --s4, at 0, --p2, --p3 and 100%) and the glows the glass catches, each
   eased to the next sky's over a second, so a new sky comes in as a crossfade, from wherever the last change had got
   to (a gradient itself can't be eased); where these can't be eased, it changes at once, as it always did */
@property --s1 { syntax: "<color>"; inherits: false; initial-value: #3f5670; }
@property --s2 { syntax: "<color>"; inherits: false; initial-value: #5d7189; }
@property --s3 { syntax: "<color>"; inherits: false; initial-value: #6c7f95; }
@property --s4 { syntax: "<color>"; inherits: false; initial-value: #7b8ca0; }
@property --p2 { syntax: "<percentage>"; inherits: false; initial-value: 60%; }
@property --p3 { syntax: "<percentage>"; inherits: false; initial-value: 80%; }
@property --glow { syntax: "<color>"; inherits: true; initial-value: rgba(255, 255, 255, 0.12); }
@property --glow-2 { syntax: "<color>"; inherits: true; initial-value: rgba(120, 160, 255, 0.12); }
.sky { position: fixed; inset: 0; z-index: -1; overflow: hidden;
  --s1: #3f5670; --s2: #5d7189; --p2: 60%; --s3: #6c7f95; --p3: 80%; --s4: #7b8ca0;
  background: linear-gradient(180deg, var(--s1) 0%, var(--s2) var(--p2), var(--s3) var(--p3), var(--s4) 100%);
  transition: --s1 1s var(--ease), --s2 1s var(--ease), --s3 1s var(--ease), --s4 1s var(--ease), --p2 1s var(--ease), --p3 1s var(--ease), --glow 1s var(--ease), --glow-2 1s var(--ease); }
/* (on a phone or a tablet, the sky ends above Safari's bar at the foot, fading into the page's own colour, the sky's at its
   foot (app.js SKY_FOOT), so the page carries on under the bar: with a layer fixed down to the foot of the screen, Safari
   fills under its bar solid) */
@media (hover: none) {
  .sky { bottom: auto; height: calc(100% - 120px); -webkit-mask-image: linear-gradient(#000 calc(100% - 160px), transparent); mask-image: linear-gradient(#000 calc(100% - 160px), transparent); }
}
/* light in the sky for the glass to catch: a glow where the sun or moon would be */
.sky::before { content: ""; position: absolute; inset: -20% -20% auto auto; width: 90vmax; height: 90vmax; border-radius: 50%; background: radial-gradient(circle, var(--glow, rgba(255, 255, 255, 0.12)), transparent 62%); pointer-events: none; }
.sky::after { content: ""; position: absolute; inset: auto auto -30% -25%; width: 80vmax; height: 80vmax; border-radius: 50%; background: radial-gradient(circle, var(--glow-2, rgba(120, 160, 255, 0.12)), transparent 60%); pointer-events: none; }
/* (what shows past the page's ends as it's pulled: the sky's top, app.js sky, eased with it) */
html { background: #2a3546; transition: background-color 1s var(--ease); }
body { background: transparent; }
/* (three colours down the sky make four with the one halfway between the last two, so each looks as it always has) */
body[data-sky="clear-day"] .sky, .sky-alt[data-sky="clear-day"] { --s1: #1f5fae; --s2: #3b82cf; --p2: 50%; --s3: #5395d9; --p3: 75%; --s4: #6aa7e2; --glow: rgba(255, 236, 180, 0.32); --glow-2: rgba(120, 200, 255, 0.22); }
body[data-sky="partly-day"] .sky, .sky-alt[data-sky="partly-day"] { --s1: #2c5f99; --s2: #4e7fb6; --p2: 55%; --s3: #6691c0; --p3: 77.5%; --s4: #7ea2c9; --glow: rgba(255, 236, 190, 0.22); }
body[data-sky="cloudy-day"] .sky, .sky-alt[data-sky="cloudy-day"] { --s1: #43566c; --s2: #5c6f85; --p2: 55%; --s3: #6b7d91; --p3: 77.5%; --s4: #7a8a9c; }
body[data-sky="rain-day"] .sky, .sky-alt[data-sky="rain-day"] { --s1: #303f52; --s2: #46576b; --p2: 55%; --s3: #526276; --p3: 77.5%; --s4: #5d6d80; --glow-2: rgba(80, 150, 255, 0.16); }
body[data-sky="storm"] .sky, .sky-alt[data-sky="storm"] { --s1: #1c2130; --s2: #2c3245; --p2: 55%; --s3: #363c4f; --p3: 77.5%; --s4: #3f4559; --glow: rgba(170, 150, 255, 0.14); }
body[data-sky="snow-day"] .sky, .sky-alt[data-sky="snow-day"] { --s1: #4f6580; --s2: #6d819b; --p2: 55%; --s3: #8092aa; --p3: 77.5%; --s4: #92a3b8; --glow: rgba(255, 255, 255, 0.2); }
body[data-sky="fog"] .sky, .sky-alt[data-sky="fog"] { --s1: #59626e; --s2: #737c87; --p2: 55%; --s3: #808993; --p3: 77.5%; --s4: #8d959f; --glow: rgba(255, 255, 255, 0.16); }
body[data-sky="clear-night"] .sky, .sky-alt[data-sky="clear-night"] { --s1: #070d22; --s2: #101c3e; --p2: 55%; --s3: #17244b; --p3: 77.5%; --s4: #1d2c57; --glow: rgba(190, 210, 255, 0.16); --glow-2: rgba(110, 90, 220, 0.16); }
body[data-sky="partly-night"] .sky, .sky-alt[data-sky="partly-night"] { --s1: #0c1428; --s2: #18233f; --p2: 55%; --s3: #1f2c49; --p3: 77.5%; --s4: #263453; --glow: rgba(190, 210, 255, 0.12); }
body[data-sky="cloudy-night"] .sky, .sky-alt[data-sky="cloudy-night"] { --s1: #151b27; --s2: #222a3a; --p2: 55%; --s3: #2a3243; --p3: 77.5%; --s4: #313a4c; }
body[data-sky="rain-night"] .sky, .sky-alt[data-sky="rain-night"] { --s1: #10151f; --s2: #1c2432; --p2: 55%; --s3: #232c3b; --p3: 77.5%; --s4: #2a3343; --glow-2: rgba(70, 120, 220, 0.14); }
body[data-sky="snow-night"] .sky, .sky-alt[data-sky="snow-night"] { --s1: #1b2335; --s2: #2c374d; --p2: 55%; --s3: #354158; --p3: 77.5%; --s4: #3e4a62; }
body[data-sky="dusk"] .sky, .sky-alt[data-sky="dusk"] { --s1: #1f2b55; --s2: #5a4a78; --p2: 45%; --s3: #b0666a; --p3: 80%; --s4: #d98b62; --glow: rgba(255, 170, 120, 0.3); --glow-2: rgba(140, 100, 230, 0.2); }
body[data-sky="dawn"] .sky, .sky-alt[data-sky="dawn"] { --s1: #24376a; --s2: #5b6a9a; --p2: 45%; --s3: #c58a86; --p3: 80%; --s4: #e7ad7c; --glow: rgba(255, 200, 150, 0.3); }
/* stars on a clear night, rain falling on a wet one, snow on a snowy one: each a layer of its own, there for its skies
   only, faded in and out with the sky (and once it's faded out, gone, its motion with it) */
.sky-stars, .sky-rain, .sky-snow { position: absolute; inset: 0; display: none; opacity: 0; pointer-events: none;
  transition: opacity 1s var(--ease); transition: opacity 1s var(--ease), display 1s var(--ease) allow-discrete; }
/* (the page's sky's, by the place showing; and each of the skies of the places either side, as it comes in over this one
   as the page is swiped: styles.css .sky-alt) */
body:is([data-sky="clear-night"], [data-sky="partly-night"]) .sky > .sky-stars, .sky-alt:is([data-sky="clear-night"], [data-sky="partly-night"]) > .sky-stars { display: block; opacity: 0.8; }
body[data-sky="partly-night"] .sky > .sky-stars, .sky-alt[data-sky="partly-night"] > .sky-stars { opacity: 0.4; }
body:is([data-sky^="rain"], [data-sky="storm"]) .sky > .sky-rain, .sky-alt:is([data-sky^="rain"], [data-sky="storm"]) > .sky-rain { display: block; opacity: 0.22; }
body[data-sky^="snow"] .sky > .sky-snow, .sky-alt[data-sky^="snow"] > .sky-snow { display: block; opacity: 1; }
@starting-style {
  body:is([data-sky="clear-night"], [data-sky="partly-night"]) .sky > .sky-stars, body:is([data-sky^="rain"], [data-sky="storm"]) .sky > .sky-rain, body[data-sky^="snow"] .sky > .sky-snow { opacity: 0; }
}
.sky-stars {
  background-image: radial-gradient(1.2px 1.2px at 12% 18%, #fff 50%, transparent), radial-gradient(1px 1px at 28% 8%, #fff 50%, transparent),
    radial-gradient(1.4px 1.4px at 45% 22%, #fff 50%, transparent), radial-gradient(1px 1px at 63% 12%, #fff 50%, transparent),
    radial-gradient(1.2px 1.2px at 78% 26%, #fff 50%, transparent), radial-gradient(1px 1px at 88% 6%, #fff 50%, transparent),
    radial-gradient(1px 1px at 8% 38%, #fff 50%, transparent), radial-gradient(1.3px 1.3px at 34% 34%, #fff 50%, transparent),
    radial-gradient(1px 1px at 56% 40%, #fff 50%, transparent), radial-gradient(1.1px 1.1px at 92% 44%, #fff 50%, transparent),
    radial-gradient(1px 1px at 70% 52%, #fff 50%, transparent), radial-gradient(1px 1px at 20% 56%, #fff 50%, transparent);
}
.sky-rain { inset: -50% 0 0;
  background-image: repeating-linear-gradient(103deg, transparent 0 14px, rgba(255, 255, 255, 0.5) 14px 15px, transparent 15px 31px);
  background-size: 120px 120px; animation: rain 0.7s linear infinite; }
@keyframes rain { to { transform: translateY(120px); } }
/* the sky lives a little: clouds drift slowly over, stars twinkle, snow falls (two layers, the nearer
   faster), lightning lights the cloud now and then (soft and rare: at most two flickers, every eleven seconds) */
/* (fog's lower and deeper, eased there and back with the rest of the sky; and drifting at the clouds' own pace, so it
   doesn't jump along its drift as it comes or goes) */
.sky-clouds { position: absolute; inset: -12% -50% auto; height: 75%; opacity: 0; transition: opacity 1s var(--ease), top 1s var(--ease), height 1s var(--ease); pointer-events: none;
  background: radial-gradient(26% 16% at 18% 32%, rgba(255, 255, 255, 0.13), transparent 70%), radial-gradient(20% 12% at 40% 18%, rgba(255, 255, 255, 0.1), transparent 70%),
    radial-gradient(30% 18% at 66% 36%, rgba(255, 255, 255, 0.12), transparent 70%), radial-gradient(18% 11% at 88% 22%, rgba(255, 255, 255, 0.09), transparent 70%);
  animation: clouds 80s steps(160) infinite alternate; }
/* (moved on in small steps, twice a second: a slow drift looks the same, and the glass over it is blurred afresh twice
   a second rather than at every frame; and held still where there are no clouds to see) */
body:is([data-sky^="clear"], [data-sky="dawn"], [data-sky="dusk"]) .sky > .sky-clouds, .sky-alt:is([data-sky^="clear"], [data-sky="dawn"], [data-sky="dusk"]) > .sky-clouds { animation-play-state: paused; }
body[data-sky^="partly"] .sky > .sky-clouds, .sky-alt[data-sky^="partly"] > .sky-clouds { opacity: 0.55; }
body:is([data-sky^="cloudy"], [data-sky="fog"]) .sky > .sky-clouds, .sky-alt:is([data-sky^="cloudy"], [data-sky="fog"]) > .sky-clouds { opacity: 1; }
body:is([data-sky^="rain"], [data-sky^="snow"], [data-sky="storm"]) .sky > .sky-clouds, .sky-alt:is([data-sky^="rain"], [data-sky^="snow"], [data-sky="storm"]) > .sky-clouds { opacity: 0.8; }
body[data-sky$="night"]:not([data-sky="clear-night"]) .sky > .sky-clouds, .sky-alt[data-sky$="night"]:not([data-sky="clear-night"]) > .sky-clouds { opacity: 0.4; }
body[data-sky="fog"] .sky > .sky-clouds, .sky-alt[data-sky="fog"] > .sky-clouds { inset: 20% -50% auto; height: 90%; }
@keyframes clouds { from { transform: translateX(-9%); } to { transform: translateX(9%); } }
/* (the twinkling ones: a layer of them on both nights, a second on a clear one, faded in and out as it clears or
   clouds over: by a filter, as their twinkle is their opacity) */
.sky-stars::before, .sky-stars::after {
  content: ""; position: absolute; inset: 0; animation: twinkle 3.6s steps(14) infinite alternate;
  background-image: radial-gradient(1.4px 1.4px at 17% 12%, #fff 50%, transparent), radial-gradient(1px 1px at 38% 28%, #fff 50%, transparent),
    radial-gradient(1.2px 1.2px at 52% 9%, #fff 50%, transparent), radial-gradient(1px 1px at 71% 33%, #fff 50%, transparent),
    radial-gradient(1.5px 1.5px at 84% 16%, #fff 50%, transparent), radial-gradient(1px 1px at 5% 26%, #fff 50%, transparent), radial-gradient(1.1px 1.1px at 60% 47%, #fff 50%, transparent); }
.sky-stars::after { animation-duration: 5.2s; animation-delay: -2.4s; filter: opacity(0); transition: filter 1s var(--ease);
  background-image: radial-gradient(1.2px 1.2px at 24% 21%, #fff 50%, transparent), radial-gradient(1px 1px at 46% 14%, #fff 50%, transparent),
    radial-gradient(1.4px 1.4px at 66% 24%, #fff 50%, transparent), radial-gradient(1px 1px at 93% 30%, #fff 50%, transparent),
    radial-gradient(1px 1px at 12% 48%, #fff 50%, transparent), radial-gradient(1.2px 1.2px at 79% 42%, #fff 50%, transparent); }
body[data-sky="clear-night"] .sky > .sky-stars::after, .sky-alt[data-sky="clear-night"] > .sky-stars::after { filter: none; }
@keyframes twinkle { from { opacity: 0.15; } to { opacity: 1; } }
.sky-snow::before, .sky-snow::after {
  content: ""; position: absolute; inset: -240px 0 0; opacity: 0.75;
  background-image: radial-gradient(2.4px 2.4px at 30px 40px, #fff 60%, transparent), radial-gradient(2px 2px at 150px 90px, #fff 60%, transparent),
    radial-gradient(2.8px 2.8px at 90px 170px, #fff 60%, transparent), radial-gradient(2px 2px at 200px 210px, #fff 60%, transparent), radial-gradient(2.2px 2.2px at 220px 20px, #fff 60%, transparent);
  background-size: 240px 240px; animation: snow-near 11s linear infinite, sway 5s ease-in-out infinite alternate; }
.sky-snow::after { inset: -160px 0 0; opacity: 0.45; background-size: 160px 160px;
  background-image: radial-gradient(1.4px 1.4px at 20px 30px, #fff 60%, transparent), radial-gradient(1.2px 1.2px at 110px 70px, #fff 60%, transparent),
    radial-gradient(1.6px 1.6px at 60px 130px, #fff 60%, transparent), radial-gradient(1.2px 1.2px at 140px 150px, #fff 60%, transparent);
  animation: snow-far 13s linear infinite, sway 7s ease-in-out -3s infinite alternate; }
@keyframes snow-near { to { translate: 0 240px; } }
@keyframes snow-far { to { translate: 0 160px; } }
@keyframes sway { from { transform: translateX(-12px); } to { transform: translateX(12px); } }
.sky-flash { position: absolute; inset: 0; opacity: 0; pointer-events: none; background: radial-gradient(55% 40% at 72% 14%, rgba(214, 206, 255, 0.55), transparent 72%); }
body[data-sky="storm"] .sky-flash { animation: lightning 11s linear infinite; }
@keyframes lightning { 0%, 84%, 100% { opacity: 0; } 85% { opacity: 0.32; } 86% { opacity: 0.06; } 87.5% { opacity: 0.22; } 90% { opacity: 0; } }
/* the sky holds still under a sheet, and once the page has scrolled on past the top (behind the cards it's
   hardly seen, and every pane of glass over it would be blurred afresh each frame it moves); and under a sheet a new
   sky is just there, not eased in behind it */
body:is(.sheet-up, .deep, .no-scroll) :is(.sky-stars, .sky-rain, .sky-clouds, .sky-flash), body:is(.sheet-up, .deep, .no-scroll) :is(.sky-stars, .sky-snow)::before, body:is(.sheet-up, .deep, .no-scroll) :is(.sky-stars, .sky-snow)::after { animation-play-state: paused; }
body.sheet-up :is(.sky, .sky > *) { transition-duration: 0s; }
/* (with Reduce Motion: nothing in it moves, and a new sky is a quick dissolve) */
@media (prefers-reduced-motion: reduce) {
  .sky-stars, .sky-stars::before, .sky-stars::after, .sky-rain, .sky-snow::before, .sky-snow::after, .sky-clouds, .sky-flash { animation: none !important; }
  html, .sky, .sky-clouds, .sky-stars, .sky-stars::after, .sky-rain, .sky-snow { transition-duration: 0.2s; }
}

/* ---------- the top bar: floating glass ---------- */
.top { position: sticky; top: 0; z-index: 5; display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 10px var(--pad) 8px; max-width: 1180px; margin: 0 auto; min-height: 70px; }
/* where the page scrolls under the bar, a bar of glass the width of the screen with a hairline under it (iOS 27's
   scroll edge: uniform, so what's under it stays legible, rather than iOS 26's soft fade) */
.top::before { content: ""; position: absolute; inset: calc(-1 * env(safe-area-inset-top)) calc(50% - 50vw) 0; z-index: -1; pointer-events: none; opacity: 0; transition: opacity 0.3s, background-color 0.3s;
  background: rgba(12, 18, 30, 0.5); border-bottom: 0.5px solid rgba(255, 255, 255, 0.16); box-shadow: 0 0.5px 0 rgba(0, 0, 0, 0.3);
  -webkit-backdrop-filter: blur(22px) saturate(160%); backdrop-filter: blur(22px) saturate(160%); }
.top.scrolled::before { opacity: 1; }
/* (behind the radar full screen, its glass isn't blurred (as the page's isn't: below): made more solid instead, so the
   cards under it don't show through the bar as if over the buttons; behind a sheet, where the page steps back, it goes:
   stepping back with the page, it was a dark box, short of the screen's edges and the strip at its top, under the dim) */
body.no-scroll .top::before { background-color: rgba(12, 18, 30, 0.88); }
body.sheet-up .top::before { opacity: 0; }
/* over the page's own content, the bar's glass firms up so it stays legible (as iOS's does over busy content) */
.top .place, .top .icon-btn { transition: background-color 0.3s, transform var(--dur-release) var(--spring), filter 0.25s; }
.top.scrolled .place, .top.scrolled .icon-btn { background-color: rgba(34, 44, 64, 0.62); }
.place { display: flex; flex-direction: column; align-items: flex-start; justify-content: center; min-width: 0; min-height: 44px; padding: 7px 18px 8px; border-radius: 999px; cursor: pointer; text-align: left; max-width: 72vw; }
.place-name { font-size: 17px; line-height: 22px; font-weight: 650; display: flex; align-items: center; gap: 0; max-width: 100%; white-space: nowrap; }
#place-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
/* (its name faded in once it's known, as the app starts: not a stand-in "Weather" first, swapped for it) */
.place-name, .place-line { transition: opacity 0.25s var(--ease); }
.place:not(.named) :is(.place-name, .place-line) { opacity: 0; }
.place-name::after { content: ""; width: 7px; height: 7px; border-right: 2px solid var(--text-2); border-bottom: 2px solid var(--text-2); transform: rotate(45deg) translateY(-3px); margin-left: 6px; flex: none; }
/* the line under the name: where it is, and once the big temperature has scrolled away, the temperature and sky
   (crossfading as it goes, as iOS Weather's large title collapses: .top.collapsed, app.js) */
.place-line { display: grid; font-size: 12px; line-height: 15px; color: var(--text-3); }
.place-line > * { grid-area: 1 / 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; transition: opacity 0.28s var(--glide); }
.top.collapsed .place-sub { opacity: 0; }
/* (only the one showing takes room, so the pill's as wide as what it says: the other laid over it as they crossfade,
   the pill easing from the one's width to the other's: app.js) */
.top:not(.collapsed) .place-now, .top.collapsed .place-sub { position: absolute; inset: 0; }
.place-now { opacity: 0; color: var(--text-2); font-weight: 600; }
.top.collapsed .place-now { opacity: 1; }
.place-now:empty, .place-line:has(.place-sub:empty):has(.place-now:empty) { display: none; }
/* with nothing to say under the name, it stays one line: the temperature slides in beside the name instead
   (the pill never changes height) */
.place.no-sub .place-line { display: none; }
.place-temp { display: none; }
.place.no-sub .place-temp { display: inline-block; flex: none; overflow: hidden; white-space: nowrap; color: var(--text-2); font-weight: 600;
  max-width: 0; margin-left: 0; opacity: 0; transition: max-width 0.4s var(--glide), margin-left 0.4s var(--glide), opacity 0.28s var(--glide); }
.top.collapsed .place.no-sub .place-temp { max-width: 3.2em; margin-left: 7px; opacity: 1; }
.top-actions { display: flex; gap: 10px; }
/* pull to refresh (app.js pullToRefresh): iOS's spinner, in the gap that opens above the bar, its ticks coming in one by
   one as the page is pulled, a little pop when letting go would refresh, then turning, each tick fainter than the one
   ahead of it; it eases into its place in the gap the page is held open by, and away as the page glides back up */
.ptr { position: fixed; z-index: 6; top: env(safe-area-inset-top); left: 50%; width: 28px; height: 28px; margin-left: -14px; pointer-events: none; opacity: 0;
  transition: transform 0.5s var(--glide), opacity 0.25s ease; }
.ptr.follow { transition: none; }
.ptr svg { display: block; overflow: visible; filter: drop-shadow(0 1px 1.5px rgba(0, 0, 0, 0.3)); }
.ptr line { stroke: #fff; stroke-width: 2.6; stroke-linecap: round; opacity: clamp(0, calc(var(--pull, 0) * 9 - var(--i)), 1); }
.ptr.armed svg { animation: ptr-pop 0.42s var(--spring); }
.ptr.busy line { opacity: var(--o); }
.ptr.busy svg { animation: ptr-spin 0.8s steps(8) infinite; }
@keyframes ptr-pop { 40% { transform: scale(1.16); } }
@keyframes ptr-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .ptr { transition: none; } .ptr.armed svg, .ptr.busy svg { animation: none; } }
/* (the page held open at its top while it refreshes: as far as the spinner's room in app.js, 56 pixels) */
.page.held { transform: translateY(56px); }
.icon-btn { width: 44px; height: 44px; border-radius: 50%; display: grid; place-items: center; cursor: pointer; flex: none; color: #fff; }
.icon-btn .g { position: relative; z-index: 3; }
.icon-btn.small { width: 36px; height: 36px; }
.icon-btn.small::after, .radar-credit::after { content: ""; position: absolute; inset: -5px; border-radius: inherit; }
.radar-credit::after { inset: -9px; }
.icon-btn.busy .g { animation: spin 1s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

/* ---------- the layout ---------- */
/* (nothing past its sides counted as the page's: the places either side's pages out there, and the cards as they're
   swiped, would have a phone take the page for twice as wide, and show it smaller) */
main { max-width: 1180px; margin: 0 auto; padding: 0 var(--pad) 8px; display: grid; gap: 16px; overflow-x: clip; }
.col { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
/* the weather now, the saved places either side of it beside it, in a scroller that stops at each (app.js pager): the
   one either side drawn to its height, not adding to it (contain), and on a phone reaching the screen's edges, so a
   place comes in from the edge, not from inside the page's margin; faded and shrunk a little as the page is scrolled
   down (app.js: --c, on it and on the .pv-hero copies) */
.pager { position: relative; display: flex; min-width: 0; overflow-x: auto; overflow-y: hidden; scroll-snap-type: x mandatory; overscroll-behavior-x: contain; scrollbar-width: none;
  transform-origin: 0 0; opacity: calc(1 - var(--c, 0) * 1.15); transform: scale(calc(1 - var(--c, 0) * 0.06)); }
.pager::-webkit-scrollbar { display: none; }
.pager > :is(.hero, .pg-page) { flex: 0 0 100%; min-width: 0; box-sizing: border-box; scroll-snap-align: start; scroll-snap-stop: always; }
.pg-page { contain: size layout paint; }
@media (max-width: 979px) {
  .pager { margin-inline: calc(-1 * var(--pad)); }
  .pager > :is(.hero, .pg-page) { padding-inline: calc(var(--pad) + 4px); }
}
/* the places either side's whole pages (app.js drawWhole), on a phone upright: each where this one's cards are, but a
   screen to either side, out of sight but for while it's swiped; as tall as this one's (contain), cut off there. The
   cards here led by the finger across them too (app.js cardSwipe), their own sideways scrolling as ever */
.pv { display: none; }
@media (max-width: 979px) {
  /* (each in the one column, said so: the places either side's pages are put there, over the first two rows, and
     anything left to find its own column would be put in a second one beside them, a gap in from the side) */
  main > .pager { grid-row: 1; grid-column: 1; }
  main > .col-a { grid-row: 2; grid-column: 1; }
  main > .col-b { grid-row: 3; grid-column: 1; }
  /* (each from the top of the weather now, its own over its cards, a gap between as the page has; the scroller's own
     pages either side left empty here) */
  .pv { grid-row: 1 / span 2; grid-column: 1; display: flex; flex-direction: column; gap: inherit; align-self: stretch; min-width: 0; contain: size layout paint; pointer-events: none; }
  .pv-hero { flex: none; transform-origin: calc(-1 * var(--pad)) 0; opacity: calc(1 - var(--c, 0) * 1.15); transform: scale(calc(1 - var(--c, 0) * 0.06)); }
  .pager > .pg-page { visibility: hidden; }
  .pv-prev { translate: -100vw 0; }
  .pv-next { translate: 100vw 0; }
  .pv .skeleton { display: grid; gap: 14px; }
  main > .col { touch-action: pan-y pinch-zoom; }
}
.pager.pg-led { scroll-snap-type: none; }
@media (min-width: 980px) {
  /* (the second column alongside the weather now, as it always was, the first's cards under it) */
  main { grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); grid-template-rows: auto 1fr; align-items: start; gap: 22px; }
  .pager { grid-column: 1; grid-row: 1; }
  .col-a { grid-column: 1; grid-row: 2; }
  .col-b { grid-column: 2; grid-row: 1 / span 2; padding-top: 8px; }
}

/* a phone on its side (iOS 27's Weather turns too): the weather now held on the left, everything else beside it, and a
   slimmer bar */
@media (orientation: landscape) and (max-height: 500px) and (min-width: 600px) {
  main { grid-template-columns: minmax(0, 0.36fr) minmax(0, 0.64fr); grid-template-rows: none; align-items: start; gap: 12px 18px; }
  .col { display: contents; }
  main > .col > * { grid-column: 2; grid-row: auto; }
  .pv { display: none; }
  .pager > .pg-page { visibility: visible; }
  main > .col { touch-action: auto; }
  main > .pager { grid-column: 1; grid-row: 1 / span 30; position: sticky; top: 64px; opacity: 1; transform: none; margin-inline: 0; }
  .pager > :is(.hero, .pg-page) { padding-inline: 4px; }
  .hero-temp { font-size: 76px; }
  :is(.hero-icon, .pg-icon) .wi { width: 60px; height: 60px; }
  .brief { font-size: 15px; }
  .top { min-height: 56px; padding-top: 6px; padding-bottom: 4px; }
  .top .place { min-height: 40px; padding-top: 4px; padding-bottom: 4px; }
  .top .icon-btn { width: 40px; height: 40px; }
  html { scroll-padding-top: 60px; }
}

/* the radar with no rain about, or the layer chosen still being fetched: said on the map, at its top in the middle, in a
   pill that fades in and out (.off: radar.js onMap) */
.radar-dry { position: absolute; left: 50%; top: 14px; transform: translateX(-50%); z-index: 3; padding: 6px 12px; border-radius: 999px; font-size: 13px; font-weight: 600; color: #fff;
  background: rgba(20, 28, 44, 0.62); -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px); box-shadow: inset 0 1px 0.5px rgba(255, 255, 255, 0.35), 0 0 0 0.5px rgba(0, 0, 0, 0.3); pointer-events: none;
  transition: opacity 0.3s var(--ease), translate 0.35s var(--glide), visibility 0s; }
.radar-dry.off { opacity: 0; translate: 0 -6px; visibility: hidden; transition: opacity 0.25s var(--ease), translate 0.35s var(--glide), visibility 0s 0.35s; }

/* a word about the alerts, once, until they're on or it's put away */
.nudge { display: grid; grid-template-columns: 34px 1fr; gap: 4px 12px; align-items: start; }
.nudge .ins-icon { width: 34px; height: 34px; border-radius: 10px; display: grid; place-items: center; background: linear-gradient(180deg, rgba(93, 178, 255, 0.45), rgba(93, 178, 255, 0.2)); color: #e1f0ff; grid-row: span 2; }
.nudge h2 { margin: 0; font-size: 16px; font-weight: 650; }
.nudge p { margin: 0; font-size: 14px; color: var(--text-2); line-height: 1.4; }
.nudge-btns { grid-column: 2; display: flex; gap: 10px; margin-top: 8px; }
.nudge-btns .pill-btn { min-height: 40px; padding: 8px 16px; }
.nudge-btns .link { min-height: 40px; padding: 0 8px; color: var(--text-2); }

/* ---------- now ---------- */
/* (positioned: words on their way out are laid over where they were, app.js fadeOff) */
.hero, .pg-page, .pv-hero { position: relative; padding: 10px 4px 8px; text-shadow: 0 1px 14px rgba(0, 0, 0, 0.2); }
/* (positioned: a temperature on its way out is laid over the new one, at its start: app.js roll) */
.hero-row { position: relative; display: flex; align-items: center; gap: 10px; }
.hero-temp { font-family: -apple-system-headline, -apple-system, "SF Pro Display", system-ui, sans-serif; font-size: 100px; font-weight: 200; line-height: 1; letter-spacing: -4px; }
:is(.hero-icon, .pg-icon) .wi { width: 78px; height: 78px; filter: drop-shadow(0 6px 16px rgba(0, 0, 0, 0.22)); }
/* (a new sky's icon comes in over the last as it goes, the two in the one place: the one going laid over the new, app.js
   hero. Not as a grid: there its drifting cloud has the browser take the page's width afresh, and mid-swipe, with
   the page's columns out past the screen's edge, it would widen the page to take them in) */
.hero-icon { position: relative; }
.hero-icon > .wi-was { position: absolute; left: 0; top: 0; pointer-events: none; }
/* and lives a little: the sun's rays turn, clouds drift, rain and snow fall, the lightning flickers (the slow drifts, the
   rays' turn and the clouds' and the fog's, in small steps as the sky's clouds move: a degree or a fraction of a pixel at
   a time looks the same, and the page isn't drawn afresh every frame for them) */
.hero-icon .wi-rays, .hero-icon .wi-flakes > * { transform-box: fill-box; transform-origin: 50% 50%; }
.hero-icon .wi-rays { animation: wi-turn 30s steps(360) infinite; }
.hero-icon .wi-cloud { animation: wi-drift 7s steps(56) infinite alternate; }
.hero-icon .wi-cloud + .wi-cloud { animation-duration: 5.4s; animation-direction: alternate-reverse; }
.hero-icon .wi-drops > * { animation: wi-fall 1.3s cubic-bezier(0.5, 0, 0.9, 0.6) infinite; }
.hero-icon .wi-drops > :nth-child(2) { animation-delay: -0.45s; }
.hero-icon .wi-drops > :nth-child(3) { animation-delay: -0.9s; }
.hero-icon .wi-drops > :nth-child(4) { animation-delay: -0.25s; }
.hero-icon .wi-flakes > * { animation: wi-flake 3.4s ease-in-out infinite; }
.hero-icon .wi-flakes > :nth-child(2) { animation-delay: -1.7s; }
.hero-icon .wi-fog > * { animation: wi-drift 6s steps(48) infinite alternate; }
.hero-icon .wi-fog > :nth-child(2) { animation-direction: alternate-reverse; animation-duration: 7.5s; }
.hero-icon .wi-bolt { animation: wi-flicker 4.6s linear infinite; }
@keyframes wi-turn { to { transform: rotate(360deg); } }
@keyframes wi-drift { from { transform: translateX(-2.2px); } to { transform: translateX(2.2px); } }
@keyframes wi-fall { 0% { transform: translate(1px, -4px); opacity: 0; } 20% { opacity: 1; } 75% { opacity: 1; } 100% { transform: translate(-1.5px, 5px); opacity: 0; } }
@keyframes wi-flake { 0% { transform: translate(0, -4px) rotate(0deg); opacity: 0; } 20% { opacity: 1; } 80% { opacity: 1; } 100% { transform: translate(1.5px, 5px) rotate(60deg); opacity: 0; } }
@keyframes wi-flicker { 0%, 78%, 100% { opacity: 1; } 80% { opacity: 0.3; } 83% { opacity: 1; } 86% { opacity: 0.45; } 89% { opacity: 1; } }
.hero:is(.away, .still) .hero-icon .wi * { animation-play-state: paused; }
@media (prefers-reduced-motion: reduce) { .hero-icon .wi * { animation: none !important; } }
.hero-cond { font-size: 22px; font-weight: 600; margin-top: 4px; }
.hero-hl { font-size: 16px; color: var(--text-2); margin-top: 2px; font-weight: 500; }
.hero-hl, .brief, .status { text-shadow: 0 1px 2px rgba(0, 0, 0, 0.32), 0 0 12px rgba(0, 0, 0, 0.22); }
.brief { font-size: 17px; line-height: 1.45; margin: 14px 0 4px; max-width: 46ch; font-weight: 500; color: var(--text-2); }
.brief b { font-weight: 650; color: #fff; }
.status { font-size: 13px; color: var(--text-3); margin: 6px 0 0; min-height: 1.4em; }
/* (and no room kept for it while it says nothing: the brief and what's under it, a warning, closer) */
.status:empty { margin: 0; min-height: 0; }
.status.warn { color: #ffd68a; }
.retry { margin-top: 14px; }
/* (Try again, and the placeholders as it tries, come in, rather than appearing) */
.retry:not([hidden]) { animation: rise 0.4s var(--glide) backwards; }
main[data-empty] ~ .foot .foot-refresh { display: none; }
/* (and the footer comes with the forecast, not before: under placeholders it would only be pushed away as it came) */
main:is([data-empty="loading"], [data-empty="kept"]) ~ .foot { display: none; }

/* before there's a forecast: glass placeholders that shimmer (or, if it couldn't be had, just the hero's message);
   the cards that would be empty wait out of sight */
.skeleton { display: none; }
main:is([data-empty="loading"], [data-empty="kept"]) > .col > .skeleton { display: grid; gap: 14px; animation: c-fade 0.3s var(--ease) backwards; }
main[data-empty] > .col > :not(.hero):not(.skeleton) { display: none !important; }
main[data-empty="error"] .hero .hero-row { display: none; }
/* (in one column, the second's placeholders would sit under the first's, only to be pushed away as the forecast came) */
@media (max-width: 979px) { main[data-empty] .col-b { display: none; } }
main[data-empty="loading"] .hero .hero-temp { color: transparent; width: 150px; height: 84px; margin: 8px 0; border-radius: 22px; }
/* (and the lines the hero will have, the high and low and the briefing, kept for them: so the cards come in where the
   placeholders were, not some way further down) */
main[data-empty="loading"] .hero :is(.hero-hl, .brief) { display: block; border-radius: 8px; background: rgba(255, 255, 255, 0.07); }
main[data-empty="loading"] .hero .hero-hl { width: 42%; height: 14px; margin-top: 10px; }
main[data-empty="loading"] .hero .brief { width: 88%; height: 49px; }
/* (the weather as it was last shown, put up as the page opens (boot.js): the temperature and its lines as they were,
   placeholders for the rest) */
main[data-empty="kept"] .hero .brief:empty { display: block; width: 88%; height: 49px; border-radius: 8px; background: rgba(255, 255, 255, 0.07); }
.sk { display: flex; flex-direction: column; gap: 12px; }
/* (the shimmer a light passing over each: moved, rather than its background redrawn every frame) */
.sk i, main[data-empty="loading"] .hero .hero-temp { display: block; position: relative; overflow: hidden; background: rgba(255, 255, 255, 0.07); }
.sk i::after, main[data-empty="loading"] .hero .hero-temp::after { content: ""; position: absolute; inset: 0; transform: translateX(-100%);
  background: linear-gradient(100deg, transparent 20%, rgba(255, 255, 255, 0.09) 50%, transparent 80%); animation: sk 1.6s ease-in-out infinite; }
.sk-l { height: 12px; border-radius: 6px; width: 100%; }
.sk-l.w30 { width: 30%; } .sk-l.w35 { width: 35%; } .sk-l.w40 { width: 40%; } .sk-l.w50 { width: 50%; } .sk-l.w80 { width: 80%; } .sk-l.w90 { width: 90%; }
.sk-hours { display: flex; gap: 10px; overflow: hidden; }
/* (the hours' pills their own width, as the hours are, however wide the card: not stretched into discs) */
.sk-hours i { flex: 0 0 52px; height: 86px; border-radius: 999px; }
.sk-chart { height: 120px; border-radius: 14px; }
.sk-big { height: 40px; width: 60%; border-radius: 10px; }
.sk-tiles { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.sk-tiles .card { border-radius: 24px; min-height: 136px; }
@keyframes sk { to { transform: translateX(100%); } }
/* when the forecast arrives, the hero eases up into place, first (the cards on screen come in after it: app.js arrive;
   only what's on screen: an animation on a card still off it can leave it unpainted; backwards fill, so nothing's left
   behind) */
@keyframes rise { from { opacity: 0; transform: translateY(12px); } }
/* (and as the page opens, for the weather last shown: the same rise carried on, not started again, as the forecast comes) */
main:is(:not([data-empty]), [data-empty="kept"]) .hero { animation: rise 0.55s var(--glide) backwards; }
.ins.rise { animation: rise 0.6s var(--glide) backwards; animation-delay: calc(var(--i, 0) * 60ms); }
/* swiping between places (app.js pager): the scroller under the finger moves by itself, the browser's own, as quick and
   as smooth as any; the cards under it carried along with it (and the next place's beside them), the place coming in's
   sky coming in over this one's and, while it's swiped (.top.swiping), its name over this one's in the bar, each by how
   far across it's got (where the weather now is in the scroller, a timeline: --cur). Always on, but for the bar's and the
   sky's few parts: they do nothing till the page moves, and switching them on as a finger lands (on a pull to refresh,
   say) would have the whole page restyled just then. Where that can't be had, app.js does the same as it scrolls.
   Landed on the next place, it's drawn in the weather now's place at once (:root.pg-snap: nothing eased) */
.sky-alt { position: absolute; inset: 0; overflow: hidden; opacity: 0; pointer-events: none; background: linear-gradient(180deg, var(--s1) 0%, var(--s2) var(--p2), var(--s3) var(--p3), var(--s4) 100%); }
/* (its clouds, stars, rain or snow with it, over this sky's own, as it comes in; there only while it's swiped: nothing of
   them kept moving out of sight) */
.sky-alt > * { transition: none !important; }
.sky:not(.swiping) > .sky-alt > * { display: none !important; }
.place-name { position: relative; }
/* (each laid over this one's name, as wide as it is (to the arrow after it), and over the line under it: neither taking
   any room of its own, so the pill's as wide as this place's words, not the widest of the three; as it's swiped, the
   pill and the name in it go from this place's width to the next one's: pill-w, name-w, app.js pillWidths) */
.pg-name { position: absolute; left: 0; right: 13px; top: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; opacity: 0; pointer-events: none; }
.place-line { position: relative; }
.pill-probe { position: absolute; left: 0; top: 0; visibility: hidden; white-space: nowrap; pointer-events: none; }
.place-line > .pg-sub { position: absolute; inset: 0; opacity: 0; pointer-events: none; }
.top.collapsed .pg-sub { visibility: hidden; }
:root.pg-snap, :root.pg-snap :is(.sky, .sky > *, .sky-stars::after, .dots i) { transition: none !important; }
@supports (timeline-scope: --a) and (animation-range: cover 0% cover 100%) {
  body { timeline-scope: --cur; }
  .hero { view-timeline: --cur x; }
  main > .col, .pv, .sky-alt, .top.swiping :is(#place-name, .pg-name) { animation-timing-function: linear; animation-fill-mode: both; animation-timeline: --cur; animation-range: cover 0% cover 100%; }
  main > .col { animation-name: pg-col; }
  .pv-prev { animation-name: pv-prev; }
  .pv-next { animation-name: pv-next; }
  @media (min-width: 980px) { main > .col { animation-name: pg-col-fade; } }
  /* (not with the radar full screen in a column: a column moved, even by nothing, would hold it in the column rather
     than the screen) */
  main:has(.radar-big) > .col { animation: none; }
  .sky-prev { animation-name: pg-sky-prev; }
  .sky-next { animation-name: pg-sky-next; }
  .top.swiping #place-name { animation-name: pg-name; }
  .top.swiping .pg-name-prev { animation-name: pg-name-prev; }
  .top.swiping .pg-name-next { animation-name: pg-name-next; }
  .top.swiping:not(.collapsed) :is(#place-sub, .pg-sub) { animation-timing-function: linear; animation-fill-mode: both; animation-timeline: --cur; animation-range: cover 0% cover 100%; }
  .top.swiping:not(.collapsed) #place-sub { animation-name: pg-name; }
  .top.swiping:not(.collapsed) .pg-sub-prev { animation-name: pg-name-prev; }
  .top.swiping:not(.collapsed) .pg-sub-next { animation-name: pg-name-next; }
  .top.swiping:not(.collapsed) .place { animation-name: pill-w; animation-timing-function: linear; animation-fill-mode: both; animation-timeline: --cur; animation-range: cover 0% cover 100%; }
  .top.swiping:not(.collapsed) #place-name { animation-name: pg-name, name-w; }
  .top.swiping:not(.collapsed) .place-line { align-self: stretch; }
  @media (prefers-reduced-motion: reduce) { main > .col { animation-name: pg-col-calm; } .pv { visibility: hidden; } }
}
@keyframes pg-col { 0% { translate: 100vw 0; } 50% { translate: 0 0; } 100% { translate: -100vw 0; } }
@keyframes pv-prev { 0% { translate: 0 0; } 50% { translate: -100vw 0; } 100% { translate: -200vw 0; } }
@keyframes pv-next { 0% { translate: 200vw 0; } 50% { translate: 100vw 0; } 100% { translate: 0 0; } }
@keyframes pg-col-fade { 0% { translate: 100vw 0; opacity: 0; } 25% { opacity: 0; } 50% { translate: 0 0; opacity: 1; } 75% { opacity: 0; } 100% { translate: -100vw 0; opacity: 0; } }
@keyframes pg-col-calm { 0%, 25% { opacity: 0; } 50% { opacity: 1; } 75%, 100% { opacity: 0; } }
@keyframes pg-sky-prev { 0% { opacity: 1; } 50%, 100% { opacity: 0; } }
@keyframes pg-sky-next { 0%, 50% { opacity: 0; } 100% { opacity: 1; } }
@keyframes pg-name { 0%, 40% { opacity: 0; } 50% { opacity: 1; } 60%, 100% { opacity: 0; } }
@keyframes pg-name-prev { 0% { opacity: 1; } 25%, 100% { opacity: 0; } }
@keyframes pg-name-next { 0%, 75% { opacity: 0; } 100% { opacity: 1; } }
/* (so neither name is ever cut short in it: wider, at once, as this one's fading; narrower, only once it's gone; and the
   next one's coming in only once it's as wide as that one: pg-name, pg-name-next) */
@keyframes pill-w { 0%, 25% { width: var(--w-prev); } 40% { width: var(--w-prev-max); } 50% { width: var(--w-cur); } 60% { width: var(--w-next-max); } 75%, 100% { width: var(--w-next); } }
@keyframes name-w { 0%, 25% { width: var(--n-prev); } 40% { width: var(--n-prev-max); } 50% { width: var(--n-cur); } 60% { width: var(--n-next-max); } 75%, 100% { width: var(--n-next); } }
/* turning to a place chosen in Places or on the map: the page's picture carried off as the next one's comes in beside
   it (app.js turnPage) */
::view-transition-group(page) { animation: none; }
::view-transition-image-pair(page) { isolation: auto; }
::view-transition-old(page), ::view-transition-new(page) { animation: none; mix-blend-mode: normal; }
/* (a new temperature rolls in over the last as it rolls away: app.js roll; the one going, never read out or in the way) */
.hero-temp.was { position: absolute; left: 0; top: 0; margin: 0; pointer-events: none; }
/* which place, of the saved ones (an arrow for My Location) */
.dots { display: flex; gap: 7px; align-items: center; margin: 0 0 6px 2px; height: 10px; }
.dots i { width: 7px; height: 7px; border-radius: 50%; background: rgba(255, 255, 255, 0.35); transition: background-color 0.3s, transform 0.4s var(--spring); }
.dots i.on { background: #fff; transform: scale(1.15); }
.dots i.gps { width: 9px; height: 9px; background: none; color: rgba(255, 255, 255, 0.45); display: grid; place-items: center; }
.dots i.gps.on { color: #fff; }
.dots i svg { display: block; }
@media (prefers-reduced-motion: reduce) { main:is(:not([data-empty]), [data-empty="kept"]) .hero, .ins.rise, .retry:not([hidden]) { animation: c-fade 0.2s var(--ease) backwards; } }
@media (prefers-reduced-motion: reduce) { .sk i::after, main[data-empty="loading"] .hero .hero-temp::after { animation: none; } .icon-btn.busy .g { animation: none; } }

/* ---------- cards ---------- */
.card { border-radius: var(--r-card); padding: 16px var(--card-x) 18px; min-width: 0; }
.card-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.card-title, .section-title { font-size: 13px; font-weight: 650; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-2); margin: 0 0 10px; display: flex; align-items: center; gap: 7px; }
.card-head .card-title { margin: 0; }
.section-title { margin: 4px 0 10px; padding: 0 4px; width: fit-content; }
/* (no glass of its own: a heading over the tiles, as each card's is inside it) */
.section-title { background: none !important; box-shadow: none !important; -webkit-backdrop-filter: none !important; backdrop-filter: none !important; }
.section-title::before { display: none; }
.ct-icon { display: inline-flex; color: var(--text-3); }
.stack { display: flex; flex-direction: column; gap: 12px; }
.stack:empty { display: none; }

/* segmented control: a glass track with a lens that glides to the choice */
.seg { display: grid; grid-template-columns: repeat(3, 1fr); padding: 3px; border-radius: 999px; min-width: 200px; background-color: rgba(0, 0, 0, 0.16); }
.seg::before { content: ""; position: absolute; top: 3px; bottom: 3px; left: 3px; width: calc((100% - 6px) / 3); border-radius: 999px; z-index: 0;
  transform: translateX(calc(var(--seg-i, 0) * 100%)); transition: transform 0.42s var(--glide);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.36), rgba(255, 255, 255, 0.16));
  box-shadow: inset 0 1px 0.5px rgba(255, 255, 255, 0.7), inset 0 -1px 0.5px rgba(255, 255, 255, 0.18), 0 4px 12px -2px rgba(0, 0, 0, 0.3); }
@media (prefers-reduced-motion: reduce) { .seg::before { transition: none; } }
.seg button { position: relative; z-index: 3; border: 0; background: none; padding: 6px 14px; border-radius: 999px; font-size: 14px; font-weight: 600; color: var(--text-2); cursor: pointer; min-height: 38px; transition: color 0.3s, opacity 0.15s; }
.seg button[aria-selected="true"] { color: #fff; }
/* (each a finger's 44 points tall, reaching over the track's edge) */
.seg button::after { content: ""; position: absolute; inset: -3px 0; }
.seg button:not([aria-selected="true"]):active { opacity: 0.6; }
@media (hover: hover) and (pointer: fine) { .seg button:not([aria-selected="true"]):hover { color: #fff; } }

/* hour strip */
/* the hours: they swipe to the card's edges, fading there, but rest and snap inside its margins
   (the space at the end is a spacer: browsers differ on padding at the end of a scrolling row) */
/* (positioned: an hour that's gone fades where it was, among them: app.js hourly) */
.strip { position: relative; display: flex; gap: 4px; overflow-x: auto; scroll-snap-type: x proximity; margin: 12px calc(-1 * var(--card-x)) 6px; padding: 2px 0 8px var(--card-x); scroll-padding-inline: var(--card-x); scrollbar-width: none;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 12px, #000 calc(100% - 12px), transparent); mask-image: linear-gradient(90deg, transparent, #000 12px, #000 calc(100% - 12px), transparent); }
.strip:focus-visible { -webkit-mask-image: none; mask-image: none; outline-offset: -2px; }
.strip::after { content: ""; flex: none; width: calc(var(--card-x) - 4px); }
.strip::-webkit-scrollbar { display: none; }
.hour { flex: none; width: 56px; display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 8px 0; border-radius: 999px; scroll-snap-align: start; }
.hour .h-time { font-size: 13px; color: var(--text-2); font-weight: 600; white-space: nowrap; }
.hour.now .h-time { color: #fff; }
.hour .h-temp { font-size: 17px; font-weight: 600; }
.hour .h-pop { font-size: 12px; color: var(--rain-text); font-weight: 650; min-height: 16px; }
.hour.sunev .h-temp { font-size: 13px; font-weight: 600; color: var(--text-2); }
.chart-note { font-size: 12.5px; color: var(--text-3); margin: 4px 0 0; }

/* charts */
.chart { position: relative; width: 100%; outline-offset: 4px; touch-action: pan-y pinch-zoom; }
.chart svg { display: block; width: 100%; height: auto; overflow: visible; }
.c-grid { stroke: rgba(255, 255, 255, 0.13); stroke-width: 1; }
.c-daysep { stroke: rgba(255, 255, 255, 0.22); stroke-width: 1; }
.c-night { fill: rgba(0, 0, 0, 0.16); }
.c-ytick, .c-xtick { fill: rgba(255, 255, 255, 0.72); font-size: 11px; font-variant-numeric: tabular-nums; }
/* scale labels inside a chart, in the middle of their bands: legible over the bars */
.c-ytick.c-in { fill: rgba(255, 255, 255, 0.85); font-weight: 600; paint-order: stroke; stroke: rgba(14, 22, 38, 0.55); stroke-width: 3px; stroke-linejoin: round; }
.c-day { fill: #fff; font-weight: 650; }
.c-line { fill: none; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.c-band { opacity: 0.22; }
.c-col { opacity: 0.95; }
.c-now { stroke: rgba(255, 255, 255, 0.55); stroke-width: 1; }
.c-nowtext { fill: rgba(255, 255, 255, 0.85); font-size: 10.5px; font-weight: 650; }
.c-label { fill: #fff; font-size: 11.5px; font-weight: 650; paint-order: stroke; stroke: rgba(10, 16, 28, 0.55); stroke-width: 3px; }
.c-dot, .c-crossdot { stroke: rgba(14, 22, 36, 0.9); stroke-width: 2; }
/* a new chart draws in (charts.js): the line traced from the left, its range fading in behind it, columns
   growing from the baseline one after another with a little spring, then the labels */
/* (--t0: drawn again part way through, it carries on from there) */
.c-enter .c-line { stroke-dasharray: 1 1; animation: c-draw 1.1s cubic-bezier(0.32, 0.72, 0.24, 1) backwards; animation-delay: var(--t0, 0ms); }
.c-enter .c-band { animation: c-fade 0.9s ease-out backwards; animation-delay: calc(0.3s + var(--t0, 0ms)); }
.c-enter .c-col { transform-box: fill-box; transform-origin: 50% 100%; animation: c-grow 0.6s var(--spring) backwards; animation-delay: calc(var(--k, 0) * 14ms + var(--t0, 0ms)); }
/* (each pop a spring of its size and a fade of its own: a fade never overshoots) */
.c-enter .c-dot, .c-enter .c-label { transform-box: fill-box; transform-origin: 50% 50%; animation: c-pop 0.45s var(--spring) backwards, c-fade 0.3s var(--ease) backwards; animation-delay: calc(0.8s + var(--t0, 0ms)); }
@keyframes c-draw { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
@keyframes c-fade { from { opacity: 0; } }
@keyframes c-grow { from { transform: scaleY(0); } }
@keyframes c-pop { from { transform: scale(0.5); } }
/* (one waiting to be scrolled to holds where it starts from, so it isn't seen whole first and then put back to draw in) */
.c-wait .c-line { stroke-dasharray: 1 1; stroke-dashoffset: 1; }
.c-wait .c-band, .c-wait .c-dot, .c-wait .c-label { opacity: 0; }
.c-wait .c-col { transform-box: fill-box; transform-origin: 50% 100%; transform: scaleY(0); }
/* the climate's range draws in too: its bands spread out from the normal, the normal and the record drawn, then today */
.r-enter :is(.r-wide, .r-mid) { transform-box: fill-box; transform-origin: 50% 50%; animation: r-spread 0.9s var(--glide) backwards; animation-delay: var(--t0, 0ms); }
.r-enter .r-mid { animation-delay: calc(0.1s + var(--t0, 0ms)); }
.r-enter :is(.r-mean, .r-record, .r-text, .r-small) { animation: c-fade 0.6s var(--ease) backwards; animation-delay: calc(0.35s + var(--t0, 0ms)); }
.r-enter .r-value { transform-box: fill-box; transform-origin: 50% 50%; animation: c-pop 0.5s var(--spring) backwards, c-fade 0.3s var(--ease) backwards; animation-delay: calc(0.7s + var(--t0, 0ms)); }
.r-enter .r-vtext { animation: c-fade 0.4s var(--ease) backwards; animation-delay: calc(0.8s + var(--t0, 0ms)); }
.r-wait :is(.r-wide, .r-mid) { transform-box: fill-box; transform-origin: 50% 50%; transform: scaleX(0); }
.r-wait :is(.r-mean, .r-record, .r-text, .r-small, .r-value, .r-vtext) { opacity: 0; }
@keyframes r-spread { from { transform: scaleX(0); } }

/* ---------- motion, once, as things come into view (app.js motion()) ---------- */
/* the 16 days: each bar sweeps out from the low to the high, row after row; today's dot lands after */
.pre .d-fill { transform: scaleX(0); transform-origin: 0 50%; }
.play .d-fill { transform-origin: 0 50%; animation: sweep 0.8s var(--spring) backwards; animation-delay: calc(var(--i, 0) * 50ms + var(--t0, 0ms)); }
.pre .d-now { opacity: 0; }
.play .d-now { animation: land 0.5s var(--spring) backwards, c-fade 0.3s var(--ease) backwards; animation-delay: calc(0.5s + var(--i, 0) * 50ms + var(--t0, 0ms)); }
/* the compass needle swings round to the wind and settles, as a real one does */
.compass .needle-g { transform-box: view-box; transform-origin: 40px 40px; }
.pre .compass .needle-g { transform: rotate(-150deg); }
.play .compass .needle-g { animation: swing 1.4s cubic-bezier(0.3, 1.45, 0.45, 1) backwards; animation-delay: var(--t0, 0ms); }
/* the sun's path traced from sunrise to now, then the sun; at night, the sun below the horizon */
.pre .sunarc .done { stroke-dasharray: 1 1; stroke-dashoffset: 1; }
.play .sunarc .done { stroke-dasharray: 1 1; animation: c-draw 1.3s cubic-bezier(0.32, 0.72, 0.24, 1) backwards; animation-delay: var(--t0, 0ms); }
.pre .sunarc .sun, .pre .sunarc .under { opacity: 0; }
.sunarc .sun { transform-box: fill-box; transform-origin: 50% 50%; }
.play .sunarc .sun { animation: c-pop 0.5s var(--spring) backwards, c-fade 0.3s var(--ease) backwards; animation-delay: calc(1.05s + var(--t0, 0ms)); }
.play .sunarc .under { animation: c-fade 0.8s var(--ease) backwards; animation-delay: var(--t0, 0ms); }
.play .sunarc .sun.down { animation-delay: calc(0.35s + var(--t0, 0ms)); }
/* the UV and air knobs slide along to their reading */
.pre .meter i { opacity: 0; }
.play .meter i { animation: knob 1s var(--spring) backwards, knob-fade 0.6s var(--ease) backwards; animation-delay: calc(0.1s + var(--t0, 0ms)); }
/* the thermometer fills up from its bulb, the humidity bar fills along, the pressure needle swings round to its reading */
.thermo .th-fill { transform-box: fill-box; transform-origin: 50% 100%; }
.pre .thermo .th-fill { transform: scaleY(0); }
.pre .fbar i { transform: scaleX(0); transform-origin: 0 50%; }
.play .thermo .th-fill { animation: fill-up 1s var(--spring) backwards; animation-delay: calc(0.1s + var(--t0, 0ms)); }
.play .fbar i { transform-origin: 0 50%; animation: sweep 0.9s var(--spring) backwards; animation-delay: calc(0.1s + var(--t0, 0ms)); }
.pre .dial .dl-needle-g { transform: rotate(var(--sw, 0deg)); }
.play .dial .dl-needle-g { animation: dial 1.3s cubic-bezier(0.3, 1.35, 0.45, 1) backwards; animation-delay: var(--t0, 0ms); }
/* the tide comes in: its water rises, its line traces along, then where it is now */
.tidec .tc-water { transform-box: fill-box; transform-origin: 50% 100%; }
.pre .tidec .tc-water { transform: scaleY(0); }
.pre .tidec .tc-line { stroke-dasharray: 1 1; stroke-dashoffset: 1; }
.pre .tidec .tc-here, .pre .tidec .tc-mark { opacity: 0; }
.tidec .tc-here, .tidec .tc-mark { transform-box: fill-box; transform-origin: 50% 50%; }
.play .tidec .tc-water { animation: fill-up 1.1s var(--spring) backwards; animation-delay: var(--t0, 0ms); }
.play .tidec .tc-line { stroke-dasharray: 1 1; animation: c-draw 1.2s cubic-bezier(0.32, 0.72, 0.24, 1) backwards; animation-delay: var(--t0, 0ms); }
.play .tidec .tc-mark { animation: c-pop 0.4s var(--spring) backwards, c-fade 0.3s var(--ease) backwards; animation-delay: calc(0.9s + var(--t0, 0ms)); }
.play .tidec .tc-here { animation: c-pop 0.5s var(--spring) backwards, c-fade 0.3s var(--ease) backwards; animation-delay: calc(1.05s + var(--t0, 0ms)); }
@keyframes fill-up { from { transform: scaleY(0); } }
@keyframes dial { from { transform: rotate(var(--sw, 0deg)); } }
@keyframes sweep { from { transform: scaleX(0); } }
@keyframes land { from { scale: 0.3; } }
@keyframes swing { from { transform: rotate(-150deg); } }
/* (moved, not laid out afresh each frame: from the start of the meter, its width (cqw) times how far along it is) */
@keyframes knob { from { transform: translateX(calc(-50% - var(--at, 0) * 1cqw)); } }
@keyframes knob-fade { from { opacity: 0.5; } }
@media (prefers-reduced-motion: reduce) {
  .pre .d-fill, .pre .compass .needle-g, .pre .thermo .th-fill, .pre .fbar i, .pre .dial .dl-needle-g, .pre .rbars rect, .pre .tidec .tc-water { transform: none; } .pre .d-now, .pre .sunarc .sun, .pre .sunarc .under, .pre .meter i, .pre .tidec .tc-here, .pre .tidec .tc-mark { opacity: 1; } .pre .sunarc .done, .pre .tidec .tc-line { stroke-dashoffset: 0; }
  .play .d-fill, .play .d-now, .play .compass .needle-g, .play .sunarc .done, .play .sunarc .sun, .play .sunarc .under, .play .meter i, .play .thermo .th-fill, .play .fbar i, .play .dial .dl-needle-g, .play .rbars rect, .play .tidec .tc-water, .play .tidec .tc-line, .play .tidec .tc-mark, .play .tidec .tc-here { animation: none; }
  .tile.opens, .tile.opens:active { transition: background-color var(--dur-base) var(--ease); transform: none; }
}

/* ---------- the cards settle into place as they're scrolled up into view ---------- */
/* (tied to the scroll itself, so nothing waits or is left behind; only where scroll-linked animation is
   understood in full, and not with Reduce Motion) */
@supports (animation-timeline: view()) and (animation-range: entry 0% entry 160px) {
  @media (prefers-reduced-motion: no-preference) {
    /* (not the radar while it's full screen: fixed in place, there's no scroll for it to follow) */
    main .card:not(.radar-big), main .ins, main .tile {
      animation: settle cubic-bezier(0.2, 0.7, 0.3, 1) both; animation-timeline: view(); animation-range: entry 0% entry 160px;
    }
    /* (once only: settled, as it's come all the way in (app.js settle), it's left where it is) */
    main :is(.card, .ins, .tile).settled:not(.rise) { animation: none; }
  }
}
@keyframes settle { from { opacity: 0.2; transform: translateY(28px) scale(0.965); } }
/* a day's sheet: the parts of the day come in one after another as it rises */
dialog.day-sheet[open] .part { animation: rise 0.55s var(--glide) backwards; }
dialog.day-sheet[open] .part:nth-child(2) { animation-delay: 0.05s; }
dialog.day-sheet[open] .part:nth-child(3) { animation-delay: 0.1s; }
dialog.day-sheet[open] .part:nth-child(4) { animation-delay: 0.15s; }
/* (with Reduce Motion, all of them dissolving in together, with the sheet: :nth-child(n), to be over the delays above) */
@media (prefers-reduced-motion: reduce) { dialog.day-sheet[open] .part:nth-child(n) { animation: c-fade 0.2s var(--ease) backwards; } }
@media (prefers-reduced-motion: reduce) { .c-enter .c-line, .c-enter .c-band, .c-enter .c-col, .c-enter .c-dot, .c-enter .c-label { animation: none; } }
.c-crossline { stroke: rgba(255, 255, 255, 0.7); stroke-width: 1; }
.c-hit { cursor: crosshair; }
.c-tip { position: absolute; z-index: 3; pointer-events: none; --tint: rgba(14, 22, 38, 0.72); border-radius: 14px; padding: 7px 11px; font-size: 12.5px; white-space: nowrap; }
.c-tip-title { color: var(--text-3); font-size: 11.5px; margin-bottom: 2px; }
.c-tip-row { display: flex; gap: 6px; align-items: baseline; }
.c-tip-row b { font-size: 14px; font-variant-numeric: tabular-nums; }
.c-tip-row span { color: var(--text-2); }
/* (the readout fades in where it comes and out as it goes, rather than blinking on and off: hidden, it's gone once it's
   faded; moving from one hour to the next, it just moves) */
.c-tip { transition: background-color var(--dur-base) var(--ease), --la 0.3s var(--ease), opacity 0.12s var(--ease), display 0.12s allow-discrete; }
.c-tip[hidden] { display: none; opacity: 0; }
@starting-style { .c-tip { opacity: 0; } }
/* (a chart's last picture, laid over the new one where it was as it fades away: charts.js put) */
.range { position: relative; }
:is(.chart, .range) > .c-old { position: absolute; left: 0; top: 0; pointer-events: none; }

/* nowcast */
.nowcast-text { margin: 0 0 8px; font-size: 16px; font-weight: 600; }
.solar-say { margin: 0; font-size: 17px; font-weight: 600; text-wrap: balance; }
.solar-text { margin: 4px 0 0; color: var(--text-2); }
.solar-chart { margin-top: 10px; color: var(--text); }
.solar-chart svg { display: block; }
.nowcast .card-head { margin-bottom: 10px; }
/* where the radar's timing the next hours: said quietly, beside the title */
.nc-src { display: inline-flex; align-items: center; gap: 5px; height: 22px; padding: 0 9px 0 7px; border-radius: 999px; font-size: 11px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; color: var(--text-2); background: rgba(255, 255, 255, 0.1); box-shadow: inset 0 0 0 0.5px rgba(255, 255, 255, 0.22); }
.nc-src .ct-icon svg { width: 13px; height: 13px; }

/* ---------- 16 days ---------- */
.days { list-style: none; margin: 0 -8px; padding: 0; }
.days li + li { border-top: 1px solid var(--line); margin-top: 0; }
.days li { padding: 0; }
.days li.far { border-top: 0; }
.far-note { display: block; font-size: 11.5px; font-weight: 650; letter-spacing: 0.04em; text-transform: uppercase; color: var(--text-3); padding: 14px 8px 6px; border-bottom: 1px solid var(--line); }
/* (every row the same height, whether or not there's a chance of rain under its icon) */
.day-row { display: grid; grid-template-columns: 4.6em 40px 2.6em 1fr 2.6em; align-items: center; gap: 8px; width: 100%; padding: 7px 8px; background: none; border: 0; border-radius: 16px; cursor: pointer; text-align: left; min-height: 58px; }
@media (hover: hover) { .day-row:hover { background-color: rgba(255, 255, 255, 0.07); } }
.day-row:active { background-color: rgba(255, 255, 255, 0.1); }
.d-name { font-weight: 600; font-size: 16px; line-height: 1.15; }
.d-name small { display: block; font-size: 11.5px; font-weight: 500; color: var(--text-3); }
.d-name small.unsure { color: var(--unsure, #ffd68a); }
.d-icon { display: flex; flex-direction: column; align-items: center; justify-content: center; height: 44px; line-height: 1; }
.d-icon > span:first-child { display: block; line-height: 0; }
.d-pop { font-size: 11.5px; font-weight: 650; color: var(--rain-text); margin-top: 1px; }
.d-lo { text-align: right; color: var(--text-3); font-weight: 560; font-variant-numeric: tabular-nums; }
.d-hi { font-weight: 650; font-variant-numeric: tabular-nums; }
/* the days by rain or by wind: when it falls, an hour a bar, and its chance and how much; or the wind, a line, with its
   gusts a band above it, and the strongest of each */
.days.v-rain .day-row, .days.v-wind .day-row { grid-template-columns: 4.6em 40px 1fr 4.6em; }
.d-chart { display: block; height: 26px; min-width: 0; }
.d-chart svg { display: block; width: 100%; height: 100%; overflow: visible; }
.dr rect { fill: var(--rain); }
.dr rect.dry { fill: rgba(255, 255, 255, 0.22); }
.dw .band { fill: rgba(63, 214, 194, 0.3); }
.dw .line { fill: none; stroke: #3fd6c2; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.d-val { display: flex; flex-direction: column; align-items: flex-end; line-height: 1.15; font-variant-numeric: tabular-nums; }
.d-val b { font-weight: 650; font-size: 16px; }
.d-val b.rain { color: var(--rain-text); }
.d-val b small.u { font-size: 12px; font-weight: 600; color: var(--text-2); }
.d-val > small { font-size: 12px; color: var(--text-3); font-weight: 500; }
/* the days' own switch: icons only, small */
.seg.icons { min-width: 0; grid-template-columns: repeat(3, 44px); }
.seg.icons button { padding: 0; display: grid; place-items: center; }
#daily .card-head { margin-bottom: 4px; }
.d-bar { position: relative; height: 6px; border-radius: 3px; background: rgba(0, 0, 0, 0.22); box-shadow: inset 0 0.5px 1px rgba(0, 0, 0, 0.3), 0 0.5px 0 rgba(255, 255, 255, 0.1); }
.d-fill { position: absolute; top: 0; bottom: 0; border-radius: 3px; background: linear-gradient(90deg, #7cc4ff, #8ee6a8, #ffd166, #ff9a4d, #ff5d5d); background-size: var(--span, 100%) 100%; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.35); }
.d-now { position: absolute; top: -3px; width: 12px; height: 12px; border-radius: 50%; background: #fff; box-shadow: 0 0 0 2px rgba(10, 16, 28, 0.6), 0 2px 6px rgba(0, 0, 0, 0.35); transform: translateX(-50%); }

/* ---------- insights ---------- */
/* the app's own insights, in one card: a row each, its title and a line of what it says (a tap for the rest) */
.ins-card { padding-bottom: 6px; }
.insights { display: flex; flex-direction: column; margin: 0 -4px; }
.ins-row { overflow: hidden; }
.ins-row + .ins-row { border-top: 0.5px solid var(--line); }
.ins-head { all: unset; box-sizing: border-box; width: 100%; display: flex; align-items: flex-start; gap: 11px; padding: 10px 4px; cursor: pointer; border-radius: 12px; -webkit-tap-highlight-color: transparent; transition: background-color var(--dur-fast); }
.ins-head:focus-visible { outline: 2px solid #fff; outline-offset: -2px; }
.ins-row.whole .ins-head { cursor: default; }
.ins-row .ins-icon { flex: none; width: 30px; height: 30px; border-radius: 9px; margin-top: 1px; }
.ins-words { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.ins-title { font-size: 15px; font-weight: 650; line-height: 1.3; }
.ins-line, .ins-short { font-size: 14px; line-height: 1.4; color: var(--text-2); display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 1; overflow: hidden; }
.ins-row.open .ins-line, .ins-row.fold .ins-line { -webkit-line-clamp: unset; }
/* one with its own short line: that, folded; the whole of it, open (fading in), and while it folds away */
.ins-row.has-short .ins-line, .ins-row.has-short.open .ins-short, .ins-row.has-short.fold .ins-short { display: none; }
.ins-row.has-short.open .ins-line, .ins-row.has-short.fold .ins-line { display: block; }
.ins-row.has-short.open .ins-line { animation: c-fade 0.3s var(--ease); }
.ins-chev { flex: none; display: inline-flex; margin-top: 8px; color: var(--text-3); transition: transform 0.4s var(--glide); }
.ins-row.open .ins-chev { transform: rotate(180deg); }
.ins-row.whole .ins-chev { visibility: hidden; }
/* open, a way on to its day or its hours (and one that goes somewhere is never just its line: always opens) */
.ins-go { all: unset; box-sizing: border-box; display: none; align-items: center; gap: 4px; margin: -4px 0 10px 45px; min-height: 32px; padding: 0 12px; border-radius: 999px; font-size: 14px; font-weight: 600; color: var(--tint-blue); background-color: rgba(159, 208, 255, 0.12); cursor: pointer; transition: background-color var(--dur-fast), opacity var(--dur-fast); }
.ins-go:active { opacity: 0.6; transition-duration: var(--dur-press); }
.ins-go span { display: inline-grid; transform: rotate(-90deg); }
.ins-row.open .ins-go, .ins-row.fold .ins-go { display: inline-flex; }
.ins-go:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
.ins-row.rise, .days li.rise { animation: rise 0.6s var(--glide) backwards; animation-delay: calc(var(--i, 0) * 50ms); }
.ins-more { all: unset; box-sizing: border-box; width: 100%; display: flex; align-items: center; justify-content: center; gap: 6px; padding: 11px 0 8px; border-top: 0.5px solid var(--line); font-size: 14px; font-weight: 600; color: var(--text-2); cursor: pointer; transition: background-color var(--dur-fast), opacity var(--dur-fast); }
/* (all of them shown: a way back to the first few, its chevron the other way up) */
.ins-more.less svg { transform: rotate(180deg); }
.ins-more:focus-visible { outline: 2px solid #fff; outline-offset: -2px; border-radius: 10px; }
.ins-more:active { opacity: 0.6; }
@media (hover: hover) { .ins-head:hover, .ins-more:hover { background-color: rgba(255, 255, 255, 0.05); } .ins-row.whole .ins-head:hover { background-color: transparent; } .ins-go:hover { background-color: rgba(159, 208, 255, 0.2); } }
@media (prefers-reduced-motion: reduce) { .ins-row.rise, .days li.rise, .ins-row.has-short.open .ins-line { animation: c-fade 0.2s var(--ease) backwards; } .ins-chev { transition: none; } }
.ins { border-radius: 22px; padding: 13px 15px 14px; display: grid; grid-template-columns: 32px 1fr; gap: 2px 11px; }
.ins-icon { grid-row: span 2; width: 32px; height: 32px; border-radius: 11px; display: grid; place-items: center;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.22), rgba(255, 255, 255, 0.08)); box-shadow: inset 0 1px 0.5px rgba(255, 255, 255, 0.5), inset 0 -1px 0.5px rgba(255, 255, 255, 0.1); }
.ins h3 { margin: 0; font-size: 15.5px; font-weight: 650; line-height: 1.3; }
.ins p { margin: 0; font-size: 14.5px; color: var(--text-2); line-height: 1.42; }
/* warnings: glass tinted by what they're about */
.ins[data-level="alert"] { --tint: rgba(129, 19, 26, 0.51); --rim: linear-gradient(135deg, rgba(255, 150, 140, 0.85), rgba(255, 90, 79, 0.25) 35%, rgba(255, 90, 79, 0.1) 65%, rgba(255, 150, 140, 0.6)); }
.ins[data-level="alert"] .ins-icon { background: linear-gradient(180deg, #ff7a70, #e8453a); color: #fff; }
.ins[data-level="warn"] { --tint: rgba(101, 68, 14, 0.49); --rim: linear-gradient(135deg, rgba(255, 214, 138, 0.85), rgba(255, 176, 32, 0.25) 35%, rgba(255, 176, 32, 0.1) 65%, rgba(255, 214, 138, 0.6)); }
.ins[data-level="warn"] .ins-icon { background: linear-gradient(180deg, #ffc94d, #f5a10f); color: #241700; }
.ins[data-level="good"] .ins-icon, .ins-row[data-level="good"] .ins-icon { background: linear-gradient(180deg, rgba(52, 199, 89, 0.45), rgba(52, 199, 89, 0.2)); color: #d5fbe0; }
.ins[data-level="tip"] .ins-icon, .ins-row[data-level="tip"] .ins-icon { background: linear-gradient(180deg, rgba(93, 178, 255, 0.45), rgba(93, 178, 255, 0.2)); color: #e1f0ff; }
.ins .tag { font-size: 11px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; margin-right: 6px; }
/* official warnings: in their own colour, the whole card opening the warning (from its title, so it's said as a button) */
.ins.official > p { grid-column: 2; }
.ins.official .ins-from { font-size: 13px; color: var(--text-3); margin-bottom: 2px; }
.ins-open { all: unset; cursor: pointer; }
.ins-open::after { content: ""; position: absolute; inset: 0; z-index: 1; border-radius: inherit; }
.ins-open:focus-visible::after { outline: 2px solid #fff; outline-offset: 2px; }
.ins.official { transition: transform var(--dur-release) var(--spring), background-color var(--dur-base) var(--ease), --la 0.3s var(--ease); }
.ins.official:active { transform: scale(0.985); transition-duration: var(--dur-press); }
.ins.official[data-colour="yellow"] { --tint: rgba(133, 106, 6, 0.6); --rim: linear-gradient(135deg, rgba(255, 238, 150, 0.85), rgba(255, 214, 10, 0.25) 35%, rgba(255, 214, 10, 0.1) 65%, rgba(255, 238, 150, 0.6)); }
.ins.official[data-colour="yellow"] .ins-icon { background: linear-gradient(180deg, #ffe45c, #f2c200); color: #231c00; }
.ins.official[data-colour="orange"] .ins-icon { background: linear-gradient(180deg, #ffad5c, #ff8a00); color: #2a1300; }
/* several at once: one banner saying what they are, that opens to all of them (app.js cards) */
.warn-sum { grid-template-columns: 32px 1fr 18px; }
.warn-sum > p { grid-column: 2; }
.warn-sum .ws-chev { grid-column: 3; grid-row: 1 / span 2; align-self: center; color: var(--text-2); transition: transform 0.4s var(--glide); }
.warn-sum.open .ws-chev { transform: rotate(180deg); }
@media (prefers-reduced-motion: reduce) { .warn-sum .ws-chev { transition: none; } }

/* ---------- best times ---------- */
.win-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
/* (an odd one out at the end across the row, rather than a gap beside it; three to a row, the last row's one or two
   share it) */
.win-grid > .win:last-child:nth-child(odd) { grid-column: 1 / -1; }
@media (min-width: 640px) and (max-width: 979px) {
  .win-grid { grid-template-columns: repeat(6, 1fr); }
  .win-grid > .win, .win-grid > .win:last-child:nth-child(odd) { grid-column: span 2; }
  .win-grid > .win:last-child:nth-child(3n+1) { grid-column: 1 / -1; }
  .win-grid > .win:nth-last-child(2):nth-child(3n+1), .win-grid > .win:nth-last-child(2):nth-child(3n+1) + .win { grid-column: span 3; }
}
.win { border-radius: var(--r-inner); padding: 11px 12px 12px; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
/* the name and its rating side by side, the rating on a line of its own when the name needs the room */
/* the same lines in every card (what, when and how good, the hours, why), so side by side they line up */
.win-name { font-weight: 650; font-size: 14.5px; display: flex; gap: 6px; align-items: center; min-width: 0; }
.win-name > span:first-child { display: inline-flex; flex: none; }
.win-rate { flex: none; font-size: 11.5px; font-weight: 700; padding: 3px 9px; border-radius: 999px; }
.win-rate[data-r="Great"] { background-color: rgba(52, 199, 89, 0.34); color: #d8fbe2; }
.win-rate[data-r="Good"] { background-color: rgba(93, 178, 255, 0.34); color: #e1f0ff; }
.win-rate[data-r="Fair"] { background-color: rgba(255, 204, 110, 0.24); color: #ffeccb; }
.win-rate[data-r="Poor"] { color: var(--text-2); background-color: rgba(255, 255, 255, 0.06); }
.win-day { display: flex; align-items: center; justify-content: space-between; gap: 6px; margin-top: 6px; font-size: 13px; font-weight: 600; color: var(--text-2); }
.win-time { font-size: 16px; font-weight: 650; line-height: 1.3; white-space: nowrap; font-variant-numeric: tabular-nums; }
.win-text { font-size: 12.5px; color: var(--text-2); line-height: 1.35; }
/* the ones not worth it today or tomorrow: named in a line, under the rest (a tap shows them, faded) */
.win.poor { opacity: 0.62; }
.win-poor { all: unset; box-sizing: border-box; display: flex; align-items: center; gap: 6px; width: 100%; margin-top: 0; padding: 10px 0; min-height: 44px; font-size: 13.5px; line-height: 1.4; color: var(--text-2); cursor: pointer; transition: opacity var(--dur-fast); }
.win-poor b { font-weight: 600; color: var(--text-3); }
.win-poor > span:last-child { flex: none; display: inline-flex; color: var(--text-3); }
.win-poor:focus-visible { outline: 2px solid #fff; outline-offset: 2px; border-radius: 6px; }
.win-grid:empty { display: none; }
.win-grid:empty + .win-poor { margin-top: 0; }

/* ---------- this time of year ---------- */
.facts { list-style: none; margin: 10px 0 0; padding: 0; display: grid; grid-template-columns: 1fr 1fr; gap: 10px 14px; }
/* (on a wide screen, the room it'll take kept while its thirty years are gathered: it doesn't grow under the eye and
   push the column's other cards about) */
@media (min-width: 980px) { #climate-body > p.muted:only-child { min-height: 230px; } }
.facts li { font-size: 13px; color: var(--text-3); }
.facts b { display: block; font-size: 16px; color: #fff; font-weight: 620; }
.r-wide { fill: rgba(255, 255, 255, 0.14); }
.r-mid { fill: rgba(255, 255, 255, 0.24); }
.r-mean { stroke: #fff; stroke-width: 2; }
.r-record { stroke: #ff9a6b; stroke-width: 2; }
.r-value { fill: var(--temp); stroke: rgba(14, 22, 36, 0.9); stroke-width: 2; }
.r-text { fill: var(--text-2); font-size: 11.5px; }
.r-small { fill: var(--text-3); font-size: 11px; }
.r-vtext { fill: #fff; font-size: 12.5px; font-weight: 700; }

/* ---------- tiles ---------- */
.tiles { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
@media (min-width: 640px) and (max-width: 979px) { .tiles { grid-template-columns: repeat(3, 1fr); } }
.tile { border-radius: 24px; padding: 13px 14px; min-height: 136px; display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.tile.wide { grid-column: span 2; }
.tile h3 { margin: 0 0 2px; font-size: 12px; font-weight: 650; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-3); display: flex; align-items: center; gap: 6px; }
.tile .big, .detail-now .big { font-size: 30px; font-weight: 500; line-height: 1.1; }
.tile .big small, .detail-now .big small { font-size: 15px; font-weight: 500; color: var(--text-2); margin-left: 3px; }
/* (the Sun's: its word under the time where the two don't fit side by side, "10:48pm Sunset" on a narrow phone, rather
   than out over the card's edge; only the Sun's, so the wind's figure and its unit never part) */
.tile[data-kind="sun"] .big { display: flex; flex-wrap: wrap; align-items: baseline; column-gap: 3px; }
.tile[data-kind="sun"] .big small { margin-left: 0; }
.tile p, .detail-now p { margin: 0; font-size: 13px; color: var(--text-2); line-height: 1.35; }
.tile .sub { margin-top: auto; }
.detail-now .sub { margin-top: 6px; }
.meter { position: relative; container-type: inline-size; height: 6px; border-radius: 3px; margin: 8px 0 4px; background: linear-gradient(90deg, #34c759, #d7e34b, #ffb020, #ff5a4f, #b45cff); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.3); }
.meter i { position: absolute; top: -4px; width: 14px; height: 14px; border-radius: 50%; background: #fff; box-shadow: 0 0 0 2px rgba(10, 16, 28, 0.5), 0 2px 6px rgba(0, 0, 0, 0.35); transform: translateX(-50%); }
.compass { width: 74px; height: 74px; margin: 4px auto 0; display: block; }
.compass .ring { fill: rgba(255, 255, 255, 0.05); stroke: rgba(255, 255, 255, 0.3); stroke-width: 1.5; }
.compass .tick { stroke: rgba(255, 255, 255, 0.45); stroke-width: 1; }
.compass text { fill: var(--text-3); font-size: 9px; font-weight: 700; }
.compass .needle { fill: #fff; }
.wind-row { display: flex; align-items: center; justify-content: space-between; gap: 6px; }
/* a tile that opens: its title a button over all of it, a little chevron to say so; it gives under a finger */
.tile.opens { cursor: pointer; transition: transform var(--dur-release) var(--spring), filter 0.25s, background-color var(--dur-base) var(--ease), --la 0.3s var(--ease); }
.tile.opens:active { transform: scale(0.97); filter: brightness(1.12); transition-duration: var(--dur-press); }
.tile-open { all: unset; flex: 1; min-width: 0; cursor: pointer; }
.tile-open::after { content: ""; position: absolute; inset: 0; z-index: 3; border-radius: inherit; }
.tile-open:focus-visible::after { outline: 2px solid #fff; outline-offset: 2px; }
.tile-chev { display: inline-flex; flex: none; transform: rotate(-90deg); opacity: 0.8; }
@media (hover: hover) { .tile.opens:hover { filter: brightness(1.08); } }
/* a tile in full, in its own sheet: what it says now, a little larger, then its hours */
.detail-now { border-radius: var(--r-inner); padding: 14px 16px 15px; display: flex; flex-direction: column; gap: 3px; }
.detail-now .big { font-size: 40px; }
.detail-now .big small { font-size: 18px; }
.detail-now p { font-size: 14.5px; }
.detail-now .meter, .detail-now .fbar { margin: 10px 0 5px; }
.detail-about { margin: 16px 2px 4px; font-size: 14px; line-height: 1.45; color: var(--text-2); }
.detail-sheet .sheet-head h2 { display: flex; align-items: center; gap: 8px; }
/* which tile of them it is (a swipe sideways for the next) */
.detail-dots { display: flex; justify-content: center; gap: 7px; margin: -4px 0 6px; }
.detail-dots i { width: 6px; height: 6px; border-radius: 50%; background: rgba(255, 255, 255, 0.28); transition: background-color 0.3s, transform 0.4s var(--spring); }
.detail-dots i.on { background: #fff; transform: scale(1.15); }
/* the rain tile's next 24 hours, an hour a bar */
.rbars { display: block; width: 100%; height: 26px; margin: 8px 0 2px; }
.rbars rect { fill: #5aa9f0; }
.rbars rect.dry { fill: rgba(255, 255, 255, 0.18); }
.rbars rect { transform-box: fill-box; transform-origin: 50% 100%; }
.pre .rbars rect { transform: scaleY(0); }
.play .rbars rect { animation: fill-up 0.8s var(--spring) backwards; animation-delay: calc(0.1s + var(--t0, 0ms)); }
.dt-icon { display: inline-flex; color: var(--text-3); }
.ways { display: grid; grid-template-columns: repeat(8, 1fr); gap: 4px; text-align: center; }
.way { display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 8px 0; border-radius: 12px; }
.way .w-time { font-size: 12px; font-weight: 600; color: var(--text-3); }
.way .w-arrow { display: inline-flex; color: #fff; }
.way b { font-size: 14px; font-weight: 650; font-variant-numeric: tabular-nums; }
/* feels like: a thermometer */
.thermo { width: 40px; height: 74px; display: block; margin: 2px 6px 0 0; }
.thermo .th-glass { fill: rgba(255, 255, 255, 0.07); stroke: rgba(255, 255, 255, 0.34); stroke-width: 1.4; }
.thermo .th-mark { fill: #fff; }
/* humidity: a bar filled to it */
.fbar { position: relative; height: 6px; border-radius: 3px; margin: 8px 0 4px; background: rgba(0, 0, 0, 0.22); box-shadow: inset 0 0.5px 1px rgba(0, 0, 0, 0.3), 0 0.5px 0 rgba(255, 255, 255, 0.1); }
.fbar i { position: absolute; left: 0; top: 0; bottom: 0; border-radius: 3px; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.35); }
.fbar.wet i { background: linear-gradient(90deg, #a9dcff, #5aa9f0 60%, #2f74d0); }
/* pressure: a dial */
.dial { width: 74px; height: 74px; display: block; }
.tile .dial { width: 64px; height: 64px; margin-right: 2px; }
/* the smallest phones (320 across): the tiles' dials and figures a little smaller so they fit their tile, a best time's
   day and rating free to wrap, and the days' rows a little tighter */
@media (max-width: 359px) {
  .tile .compass, .tile .dial { width: 52px; height: 52px; }
  .tile .big, .detail-now .big { font-size: 26px; }
  .win-day { flex-wrap: wrap; }
  .win-time { white-space: normal; }
  .day-row { grid-template-columns: 3.9em 34px 2.4em 1fr 2.4em; gap: 6px; }
  .days.v-rain .day-row, .days.v-wind .day-row { grid-template-columns: 3.9em 34px 1fr 4.2em; }
}
.dial .dl-ticks { stroke: rgba(255, 255, 255, 0.4); stroke-width: 1.2; stroke-linecap: round; fill: none; }
.dial .dl-needle { stroke: #fff; stroke-width: 3.2; stroke-linecap: round; }
.dial .dl-needle-g { transform-box: view-box; transform-origin: 40px 40px; }
.dial .dl-way { stroke: #fff; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; fill: none; }
/* visibility: a scale from fog to clear, its ends named */
.meter.clear { background: linear-gradient(90deg, rgba(190, 198, 210, 0.35), rgba(190, 210, 230, 0.7) 45%, #8fd0ff); }
.ends { display: flex; justify-content: space-between; font-size: 11px; font-weight: 600; color: var(--text-3); margin-top: -1px; }
.sunarc { width: 100%; max-width: 340px; height: auto; display: block; margin: 4px auto; }
.sunarc .arc { fill: none; stroke: rgba(255, 255, 255, 0.3); stroke-width: 1.5; stroke-dasharray: 3 4; }
.sunarc .done { fill: none; stroke: #ffd166; stroke-width: 2; }
.sunarc .hz { stroke: rgba(255, 255, 255, 0.35); stroke-width: 1; }
.sunarc .sun { fill: #ffd166; stroke: rgba(14, 22, 36, 0.9); stroke-width: 2; }
.sunarc .under { fill: none; stroke: rgba(255, 255, 255, 0.14); stroke-width: 1.2; stroke-dasharray: 2 4; }
.sunarc .sun.down { fill: #ffd166; opacity: 0.55; }
/* the sun's tile: its path across the sky under when it next sets or rises; bigger in its sheet */
.tile .sunarc { margin: 2px auto 0; }
.detail-now .sunarc { max-width: 260px; margin: 6px 0 0; }
.kv.moons dd span { display: inline-block; vertical-align: -3px; margin-right: 6px; }
.moon-row { display: flex; align-items: center; gap: 10px; margin: 2px 0; }
/* the sea: how warm, the waves, and the tide's next day as a little curve */
.sea-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.tidec { width: 168px; max-width: 54vw; height: auto; display: block; overflow: visible; }
.tidec .tc-water { fill: rgba(90, 200, 250, 0.2); }
.tidec .tc-line { fill: none; stroke: #5ac8fa; stroke-width: 2; stroke-linecap: round; }
.tidec .tc-mark { fill: #5ac8fa; stroke: rgba(14, 22, 36, 0.9); stroke-width: 1.2; }
.tidec .tc-now { stroke: rgba(255, 255, 255, 0.35); stroke-width: 1; stroke-dasharray: 2 3; }
.tidec .tc-here { fill: #fff; stroke: rgba(14, 22, 36, 0.9); stroke-width: 1.6; }
.detail-now .tidec { width: 200px; }
.kv.tides { margin: 10px 0 2px; }
.kv { display: grid; grid-template-columns: auto 1fr; gap: 1px 10px; font-size: 13px; color: var(--text-2); margin: 0; }
.kv dt { color: var(--text-3); }
.kv dd { margin: 0; text-align: right; font-variant-numeric: tabular-nums; color: #fff; }

/* ---------- foot: small print, as the Weather app has it (no panel; centred and quiet) ---------- */
.foot { max-width: 1180px; margin: 6px auto 0; padding: 0 var(--pad) 22px; font-size: 11.5px; line-height: 1.5; color: #fff; text-align: center;
  text-shadow: 0 0 3px rgba(0, 0, 0, 0.45), 0 1px 2px rgba(0, 0, 0, 0.45), 0 0 10px rgba(0, 0, 0, 0.25); }   /* (to read over a pale sky too) */
.foot p { margin: 2px auto; max-width: 60ch; }
/* (the words small, the places to tap not: each reaches past its words, without moving the lines apart) */
.foot .link { font-size: inherit; padding: 13px 4px; margin: -13px -4px; }
/* (its links and buttons alike, Refresh too: underlined in the line's own colour, as the Weather app's are) */
.foot a, .foot .link { color: inherit; font-weight: inherit; text-decoration: underline; text-decoration-color: rgba(255, 255, 255, 0.45); text-underline-offset: 2px; }
.foot a { padding: 13px 2px; margin: -13px -2px; }
.foot a { transition: opacity var(--dur-fast); }
.foot a:active { opacity: 0.55; transition-duration: var(--dur-press); }
/* a plain button: tinted text, as on iOS */
.link { background: none; border: 0; padding: 4px 2px; cursor: pointer; color: var(--tint-blue); font-size: inherit; font-weight: 600; }
.link:active { opacity: 0.55; transition-duration: var(--dur-press); }
/* (pointed at, with a mouse: a link, or a word that does something, fades a little, as the site's do) */
@media (hover: hover) and (pointer: fine) { .link:hover, .foot a:hover, .credits a:hover, .credits-lead a:hover, .warn-link a:hover, .acct-new a:hover, .win-poor:hover { opacity: 0.75; } }

/* ---------- sheets: floating glass ---------- */
/* (fixed, as a modal dialog is by default, so it stays put if the page behind scrolls, as when a keyboard opens) */
dialog.sheet { position: fixed; --tint: rgba(26, 34, 52, 0.74); padding: 0; color: var(--text); width: calc(100% - 16px); max-width: 560px; max-height: 86vh; max-height: 86svh;
  border-radius: 34px; margin: auto 8px 8px; overflow: hidden;
  -webkit-backdrop-filter: blur(34px) saturate(190%); backdrop-filter: blur(34px) saturate(190%);
  box-shadow: var(--edge), 0 30px 80px -10px rgba(0, 0, 0, 0.55); }
/* opening, it comes up from below on iOS's own curve (not faded in: Safari leaves a fading pane of glass unblurred,
   then snaps it frosted); the dim fades in with it. Opened again while it was going, it comes back up from where it
   had got to (--in-t, --in-o, --dim-o: app.js openSheet) */
dialog.sheet[open] { display: flex; flex-direction: column; animation: sheet-in var(--dur-sheet-in) var(--glide); transition: transform 0.45s var(--glide), background-color var(--dur-base) var(--ease), --la 0.3s var(--ease); }
dialog.sheet::backdrop { background: rgba(0, 0, 0, 0.38); }
dialog.sheet[open]::backdrop { animation: dim-in var(--dur-sheet-in) var(--glide); }
@keyframes sheet-in { from { transform: var(--in-t, translateY(calc(100% + 12px))); opacity: var(--in-o, 1); } }
@keyframes dim-in { from { opacity: var(--dim-o, 0); } }
/* closing: it slides away from wherever it is (still rising, or where a finger left it: --from-t, --from-o, app.js
   closeSheet), the dim going with it; dragged, it follows the finger */
dialog.sheet.closing { animation: sheet-out var(--dur-sheet-out) var(--glide) forwards; pointer-events: none; }
dialog.sheet.closing::backdrop { animation: dim-out var(--dur-sheet-out) var(--glide) forwards; }
dialog.sheet.dragging { transition: none; }
@keyframes sheet-out { from { transform: var(--from-t, none); opacity: var(--from-o, 1); } to { transform: translateY(calc(100% + 12px)); } }
@keyframes dim-out { from { opacity: var(--dim-o, 1); } to { opacity: 0; } }
@media (min-width: 700px) {
  @keyframes sheet-in { from { transform: var(--in-t, translateY(24px) scale(0.98)); opacity: var(--in-o, 0); } }
  @keyframes sheet-out { from { transform: var(--from-t, none); opacity: var(--from-o, 1); } to { transform: translateY(24px) scale(0.98); opacity: 0; } }
}
/* (with Reduce Motion, a sheet and its dim dissolve in and out where they are, quickly) */
@keyframes sheet-fade-in { from { opacity: var(--in-o, 0); } }
@keyframes sheet-fade-out { from { opacity: var(--from-o, 1); } to { opacity: 0; } }
/* while a sheet is up, the page behind steps back, and holds still: its glass unblurred, and nothing on it (or the
   sky) moving (under the dim it looks the same, and the sheet's own glass isn't blurred afresh every frame) */
.page { transition: transform 0.5s var(--glide); }
/* (named one by one, the panes of glass and the hero's icon, the one thing on the page that moves of itself: a rule
   for everything on the page would have every one of its thousands of parts restyled as a sheet came and went) */
body.sheet-up .page :is(.card, .ins, .tile, .section-title, .c-tip, .icon-btn, .place, .pill-btn, .seg, .radar-chip, .radar-hint, .map-zoom, :is(.radar-centre, .map-layers), .radar-credit, .rc-t, .radar-dry, .layer-menu),
body.sheet-up .top::before,
/* (and the same behind the radar full screen, its map over all of it: all but the radar's own) */
body.no-scroll .page :is(.card, .ins, .tile, .section-title, .c-tip, .icon-btn, .place, .pill-btn, .seg):not(.radar, .radar *), body.no-scroll .top::before { -webkit-backdrop-filter: none !important; backdrop-filter: none !important; animation-play-state: paused !important; }
@property --recede { syntax: "<number>"; inherits: false; initial-value: 1; }
body.sheet-up .page { transform: translateY(calc(var(--recede, 1) * 10px)) scale(calc(1 - var(--recede, 1) * 0.06)); }
body.sheet-drag .page { transition: none; }
@media (min-width: 700px) { body.sheet-up .page { transform: scale(calc(1 - var(--recede, 1) * 0.025)); } }
/* (the radar full screen stays put under a sheet: a page that steps back would carry it with it) */
body.sheet-up .page:has(.radar-big) { transform: none; }
@media (min-width: 700px) { dialog.sheet { margin: auto; max-height: 84vh; } }
/* places, and settings: always the same height on a phone, so neither jumps as results come and go, or from one of
   Settings' folders to another */
@media (max-width: 699px) { #places, #settings { height: 86vh; height: 86svh; } }
@media (min-width: 700px) { #settings { height: min(720px, 84vh); } }
@media (prefers-reduced-motion: reduce) {
  dialog.sheet[open] { animation: sheet-fade-in 0.2s var(--ease); }
  dialog.sheet.closing { animation: sheet-fade-out 0.2s var(--ease) forwards; }
  dialog.sheet[open]::backdrop { animation: dim-in 0.2s var(--ease); }
  dialog.sheet.closing::backdrop { animation: dim-out 0.2s var(--ease) forwards; }
  .page, body.sheet-up .page { transition: none; transform: none; }
}
/* the header stays put; what scrolls up under it fades away (the scroll edge) */
.sheet-head { position: relative; z-index: 4; flex: none; display: flex; align-items: center; justify-content: space-between; padding: 20px 20px 4px; }
.sheet-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 16px 20px calc(20px + env(safe-area-inset-bottom));
  -webkit-mask-image: linear-gradient(180deg, transparent, #000 16px); mask-image: linear-gradient(180deg, transparent, #000 16px); }
/* the grabber */
.sheet-head::before { content: ""; position: absolute; top: 7px; left: 50%; width: 38px; height: 5px; margin-left: -19px; border-radius: 3px; background: rgba(255, 255, 255, 0.32); }
@media (min-width: 700px) { .sheet-head::before { display: none; } }
.sheet-head h2 { margin: 0; font-size: 20px; font-weight: 700; }
.sheet-head h2:focus { outline: none; }
.sheet-sub { font-size: 12.5px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-3); margin: 18px 0 6px; }
/* search: a capsule */
.search input { width: 100%; padding: 12px 16px 12px 42px; border-radius: 999px; font-size: 16px; background-color: rgba(118, 118, 128, 0.26);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-opacity='.7' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='6.5'/%3E%3Cpath d='M20 20l-4.2-4.2'/%3E%3C/svg%3E"), var(--sheen);
  background-repeat: no-repeat; background-position: 14px center, 0 0; background-size: 18px, auto; }
.search input::placeholder { color: var(--text-3); }
.search input:focus { outline: none; box-shadow: inset 0 1px 0.5px rgba(255, 255, 255, 0.5), 0 0 0 3px rgba(159, 208, 255, 0.45); }
.results, .saved { list-style: none; margin: 8px 0 0; padding: 0; }
.results li + li, .saved li + li { border-top: 1px solid var(--line); }
.row-btn { display: flex; align-items: center; gap: 10px; width: 100%; padding: 11px 8px; background: none; border: 0; border-radius: 16px; cursor: pointer; text-align: left; min-height: 50px; }
@media (hover: hover) { .row-btn:hover { background-color: rgba(255, 255, 255, 0.07); } }
.row-btn .rb-main { flex: 1; min-width: 0; }
.row-btn .rb-name { font-weight: 600; display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.row-btn .rb-sub { font-size: 13px; color: var(--text-3); display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.row-btn[aria-current="true"] .rb-name::after { content: " · showing"; font-weight: 500; color: var(--text-3); font-size: 13px; }
/* the saved places: a card each, in its own sky (iOS's Weather list); swiped left, it narrows to make room for a Delete
   beside it, a rounded button of its own (iOS 27's swipe actions), so nothing on it is cut off */
.saved { display: flex; flex-direction: column; gap: 10px; }
.saved li + li { border-top: 0; }
#here:empty { display: none; }
#here + .sheet-sub { margin-top: 22px; }
.pc-li { position: relative; }
.place-card { position: relative; z-index: 1; display: flex; justify-content: space-between; gap: 12px; width: 100%; min-height: 104px; padding: 14px 16px 12px; border: 0; border-radius: 22px; cursor: pointer; text-align: left; color: #fff;
  background: linear-gradient(160deg, var(--pa, #3a5a86), var(--pb, #22324c)); box-shadow: inset 0 1px 0.5px rgba(255, 255, 255, 0.4), inset 0 -1px 0.5px rgba(255, 255, 255, 0.1), 0 0 0 0.5px rgba(0, 0, 0, 0.3);
  transition: width 0.35s var(--glide), filter var(--dur-fast); text-shadow: 0 1px 8px rgba(0, 0, 0, 0.25); }
.place-card[aria-current="true"] { box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.55), inset 0 1px 0.5px rgba(255, 255, 255, 0.4), 0 0 0 0.5px rgba(0, 0, 0, 0.3); }
.pc-li.swiped .place-card, .pc-li:has(.pc-del:focus-visible) .place-card { width: calc(100% - 100px); }
.pc-l, .pc-r { display: flex; flex-direction: column; min-width: 0; }
.pc-r { align-items: flex-end; justify-content: space-between; }
.pc-name { font-size: 21px; font-weight: 700; line-height: 1.15; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pc-here { display: inline-grid; vertical-align: 1px; }
.pc-sub { font-size: 13px; font-weight: 600; color: rgba(255, 255, 255, 0.85); margin-top: 2px; }
.pc-cond { font-size: 13px; font-weight: 500; color: rgba(255, 255, 255, 0.85); margin-top: auto; padding-top: 10px; }
.pc-temp { font-size: 44px; font-weight: 300; line-height: 1; letter-spacing: -1px; }
.pc-hl { font-size: 13px; font-weight: 600; color: rgba(255, 255, 255, 0.85); white-space: pre; }
.pc-del { position: absolute; inset: 0 0 0 auto; width: 92px; border: 0; border-radius: 22px; background: #ff453a; color: #fff; font-size: 13px; font-weight: 600; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; cursor: pointer;
  box-shadow: inset 0 1px 0.5px rgba(255, 255, 255, 0.35), 0 0 0 0.5px rgba(0, 0, 0, 0.3); transform: scale(0.6); opacity: 0; transition: transform 0.35s var(--spring), opacity 0.2s; }
.pc-li.swiped .pc-del, .pc-del:focus-visible { transform: none; opacity: 1; }
.pc-del:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
.pc-bin { display: none; position: absolute; z-index: 2; right: 10px; top: 50%; transform: translateY(-50%); width: 34px; height: 34px; border-radius: 50%; border: 0; background: rgba(0, 0, 0, 0.35); color: #fff; place-items: center; cursor: pointer; }
/* (with a mouse, the bin fades in over the card as it's pointed at, its temperature fading away under it; out of the
   way of the keyboard when it isn't shown: the card's Delete is the keyboard's) */
@media (hover: hover) and (pointer: fine) {
  .pc-bin { display: grid; visibility: hidden; opacity: 0; transition: opacity var(--dur-fast), visibility 0s var(--dur-fast), background-color var(--dur-fast); }
  .pc-li:hover .pc-bin { visibility: visible; opacity: 1; transition: opacity var(--dur-fast), visibility 0s, background-color var(--dur-fast); }
  .pc-bin:hover { background-color: rgba(0, 0, 0, 0.5); }
  .pc-r { transition: opacity var(--dur-fast); }
  .pc-li:hover .pc-r { opacity: 0; }
  .place-card:hover { filter: brightness(1.08); }
}
:is(.place-card, .acct-chip)[data-sky="clear-day"] { --pa: #3d86d6; --pb: #1f5fae; } :is(.place-card, .acct-chip)[data-sky="partly-day"] { --pa: #4c7fb8; --pb: #2c5f99; }
:is(.place-card, .acct-chip)[data-sky="cloudy-day"] { --pa: #6a7d93; --pb: #43566c; } :is(.place-card, .acct-chip)[data-sky="rain-day"] { --pa: #4f6176; --pb: #303f52; }
:is(.place-card, .acct-chip)[data-sky="snow-day"] { --pa: #7d93ad; --pb: #4f6580; } :is(.place-card, .acct-chip)[data-sky="fog"] { --pa: #858f9b; --pb: #59626e; } :is(.place-card, .acct-chip)[data-sky="storm"] { --pa: #3a4256; --pb: #1c2130; }
:is(.place-card, .acct-chip)[data-sky="clear-night"] { --pa: #1b2950; --pb: #070d22; } :is(.place-card, .acct-chip)[data-sky="partly-night"] { --pa: #22305a; --pb: #0c1428; }
:is(.place-card, .acct-chip)[data-sky="cloudy-night"] { --pa: #2e3747; --pb: #151b27; } :is(.place-card, .acct-chip)[data-sky="rain-night"] { --pa: #283142; --pb: #10151f; } :is(.place-card, .acct-chip)[data-sky="snow-night"] { --pa: #36435e; --pb: #1b2335; }
@media (prefers-reduced-motion: reduce) { .place-card, .pc-del { transition: opacity var(--dur-fast), filter var(--dur-fast); } }
#use-location { color: var(--tint-blue); font-weight: 600; margin-top: 4px; }
/* searching, the results take the list's place (as iOS's search does): the list fading out of their way, and back in
   as the search is cleared */
.pl-list { transition: opacity var(--dur-fast) var(--ease); transition: opacity var(--dur-fast) var(--ease), display var(--dur-fast) allow-discrete; }
#places.searching .pl-list { display: none; opacity: 0; }
@starting-style { #places:not(.searching) .pl-list { opacity: 0; } }
/* (and "Searching…" while they come, if they're a moment coming) */
.results .searching { padding: 12px 8px; }

/* settings: groups */
fieldset.opt { border: 0; margin: 0 0 18px; padding: 0; display: flex; flex-wrap: wrap; gap: 8px; }
fieldset.opt legend { font-size: 13px; color: var(--text-3); font-weight: 600; margin-bottom: 8px; padding: 0 4px; }
fieldset.opt label { display: inline-flex; align-items: center; gap: 8px; padding: 9px 14px; border-radius: 999px; cursor: pointer; font-size: 15px; min-height: 42px; }
/* a choice of one (°C or °F…): a segmented control, a lens of glass gliding to the chosen one (which, and how
   many there are, found with :has) */
fieldset.opt:has(> .choice) { display: block; }
.choice { position: relative; isolation: isolate; --n: 2; --i: 0; display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; width: 100%; padding: 3px; border-radius: 999px; background-color: rgba(0, 0, 0, 0.18); }
.choice:has(> label:nth-child(3)) { --n: 3; }
.choice:has(> label:nth-child(4)) { --n: 4; }
.choice:has(> label:nth-child(2) > input:checked) { --i: 1; }
.choice:has(> label:nth-child(3) > input:checked) { --i: 2; }
.choice:has(> label:nth-child(4) > input:checked) { --i: 3; }
.choice::before { content: ""; position: absolute; z-index: 0; top: 3px; bottom: 3px; left: 3px; width: calc((100% - 6px) / var(--n)); border-radius: 999px;
  transform: translateX(calc(var(--i) * 100%)); transition: transform 0.42s var(--glide);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.34), rgba(255, 255, 255, 0.14));
  box-shadow: inset 0 1px 0.5px rgba(255, 255, 255, 0.7), inset 0 -1px 0.5px rgba(255, 255, 255, 0.16), 0 4px 12px -2px rgba(0, 0, 0, 0.3); }
.choice:not(:has(input:checked))::before { opacity: 0; }
@media (prefers-reduced-motion: reduce) { .choice::before { transition: none; } }
.choice > label { z-index: 1; }
fieldset.opt label:has(input[type="radio"]) { justify-content: center; background: none; box-shadow: none; -webkit-backdrop-filter: none; backdrop-filter: none; min-height: 36px; padding: 7px 8px; font-weight: 600; color: var(--text-2); white-space: nowrap; }
fieldset.opt label:has(input[type="radio"]:checked) { color: #fff; }
fieldset.opt input[type="radio"] { position: absolute; inset: 0; z-index: 3; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
fieldset.opt label:has(input[type="radio"]:focus-visible) { outline: 2px solid #fff; outline-offset: 2px; }
/* switches */
label.switch { display: flex; width: 100%; justify-content: flex-start; gap: 12px; }
.switch input[type="checkbox"] { -webkit-appearance: none; appearance: none; order: 9; margin: 0 0 0 auto; flex: none; position: relative; width: 52px; height: 32px; border-radius: 999px; cursor: pointer;
  background: rgba(120, 120, 128, 0.36); box-shadow: inset 0 0 0 0.5px rgba(255, 255, 255, 0.14), inset 0 1px 2px rgba(0, 0, 0, 0.25); transition: background-color 0.3s; }
.switch input[type="checkbox"]::before { content: ""; position: absolute; top: 2px; left: 2px; width: 28px; height: 28px; border-radius: 999px;
  background: linear-gradient(180deg, #ffffff, #eef1f6); box-shadow: 0 3px 8px rgba(0, 0, 0, 0.28), 0 1px 1px rgba(0, 0, 0, 0.12), inset 0 -1px 1px rgba(0, 0, 0, 0.06);
  transition: transform 0.45s var(--spring), width 0.25s var(--spring); }
.switch input[type="checkbox"]:checked { background: var(--good); }
.switch input[type="checkbox"]:checked::before { transform: translateX(20px); }
/* pressed, the knob stretches like a drop of glass */
.switch input[type="checkbox"]:active::before { width: 34px; background: linear-gradient(180deg, rgba(255, 255, 255, 0.92), rgba(240, 244, 250, 0.82)); }
.switch input[type="checkbox"]:checked:active::before { transform: translateX(14px); }
.switch input[type="checkbox"]:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
/* a time to choose (app.js fillTimes: a quarter of an hour apart, said as the Clock setting says them), in a chip */
select.at { -webkit-appearance: none; appearance: none; font: inherit; font-variant-numeric: tabular-nums; color: inherit; background: rgba(118, 118, 128, 0.26); border: 0; border-radius: 10px;
  padding: 5px 10px; box-shadow: inset 0 1px 0.5px rgba(255, 255, 255, 0.25); cursor: pointer; }
select.at:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
.at-row select.at { margin-left: auto; }
/* notifications for each saved place: rain alerts and official warnings, each a chip; and the briefing's place */
.np-row { display: flex; align-items: center; gap: 8px; min-height: 52px; padding: 0 12px 0 16px; }
.np-name { flex: 1; min-width: 0; font-size: 16px; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.np-name small { display: block; font-size: 12px; font-weight: 500; color: var(--text-3); }
.np-chip { position: relative; flex: none; font: inherit; font-size: 13px; font-weight: 600; min-height: 34px; padding: 0 13px; border-radius: 999px; border: 0; cursor: pointer; color: var(--text-2);
  background-color: rgba(255, 255, 255, 0.08); box-shadow: inset 0 0 0 0.5px rgba(255, 255, 255, 0.12); transition: background-color 0.2s, color 0.2s; }
/* (a finger's 44 points to tap, above and below it, as it looks; not either side, into the chip beside it) */
.np-chip::after { content: ""; position: absolute; inset: -5px 0; border-radius: inherit; }
.np-chip[aria-pressed="true"] { color: #fff; background-color: #2f6fde; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25); }
@media (hover: hover) and (pointer: fine) { .np-chip:hover { background-color: rgba(255, 255, 255, 0.14); } .np-chip[aria-pressed="true"]:hover { background-color: #3b7cf0; } }
.np-chip:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
.brief-for select.at { max-width: 60%; text-overflow: ellipsis; }
.at-row { transition: opacity var(--dur-fast); }
#notify-set:not(:has(input[name="brief"]:checked)) .at-row { opacity: 0.5; }

/* your account (weather/account.js), at the top of Settings: signed out, what it's for and how to sign in; signed in,
   who, whether your places are in step, and where notifications go */
.acct { display: grid; gap: 10px; margin: 2px 0 22px; }
.acct-card { display: flex; gap: 14px; align-items: center; padding: 14px 16px; border-radius: 20px; background-color: rgba(255, 255, 255, 0.08); box-shadow: inset 0 0 0 0.5px rgba(255, 255, 255, 0.14); }
.acct-ic, .acct-av { flex: none; display: grid; place-items: center; border-radius: 50%; color: #fff; background: linear-gradient(160deg, #6fb0ff, #2b62d6); box-shadow: 0 4px 14px -4px rgba(45, 111, 224, 0.7); }
.acct-ic { width: 44px; height: 44px; }
.acct-av { width: 48px; height: 48px; font-size: 21px; font-weight: 700; }
.acct-txt { display: grid; gap: 3px; min-width: 0; }
.acct-txt b { font-size: 16px; font-weight: 650; overflow-wrap: anywhere; }
.acct-txt span { font-size: 13.5px; line-height: 1.35; color: var(--text-2); overflow-wrap: anywhere; }
.acct-btn { display: flex; align-items: center; justify-content: center; gap: 8px; min-height: 48px; padding: 0 18px; border-radius: 999px; border: 0; font: inherit; font-size: 16px; font-weight: 600; cursor: pointer; color: var(--text); background-color: rgba(255, 255, 255, 0.1);
  transition: filter var(--dur-fast), background-color var(--dur-fast), transform var(--dur-release) var(--spring), opacity var(--dur-fast); }
.acct-btn:not(:disabled):active { transform: scale(0.97); transition-duration: var(--dur-press); }
@media (hover: hover) and (pointer: fine) { .acct-btn:not(:disabled):hover { filter: brightness(1.12); } }
.acct-btn.primary { background: linear-gradient(180deg, #4f95ff, #2563d9); color: #fff; box-shadow: 0 8px 22px -10px rgba(37, 99, 217, 0.9), inset 0 1px 0 rgba(255, 255, 255, 0.25); }
a.acct-btn { text-decoration: none; }
.acct-btn:disabled { opacity: 0.55; cursor: default; }
.acct-btn:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
.acct-btn > span { display: inline-grid; }
.acct-rows { list-style: none; margin: 0; padding: 2px 16px; border-radius: 18px; background-color: rgba(255, 255, 255, 0.06); }
.acct-rows li { display: flex; justify-content: space-between; align-items: center; gap: 12px; min-height: 44px; padding: 8px 0; font-size: 14.5px; }
.acct-rows li + li { border-top: 0.5px solid rgba(255, 255, 255, 0.12); }
.acct-rows li > span:last-child { color: var(--text-2); text-align: right; display: inline-flex; gap: 5px; align-items: center; min-width: 0; }
.acct-ok { color: #7fe0a0 !important; }
/* the account's card: a way to its own page */
.acct-card.go { width: 100%; border: 0; font: inherit; color: inherit; text-align: left; cursor: pointer; transition: transform var(--dur-release) var(--spring), background-color var(--dur-fast); }
.acct-card.go:active { transform: scale(0.98); background-color: rgba(255, 255, 255, 0.12); transition-duration: var(--dur-press); }
@media (hover: hover) and (pointer: fine) { .acct-card.go:hover { background-color: rgba(255, 255, 255, 0.11); } }
.acct-card.go:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
.acct-card .acct-txt { flex: 1; }
.acct-chev { flex: none; display: inline-grid; color: var(--text-2); }
.acct-chev svg { transform: rotate(-90deg); }
.acct-bad { color: #ffb4a8 !important; }
.notify-acct { display: grid; gap: 8px; justify-items: start; }
.notify-acct:empty { display: none; }
.notify-acct .note { margin: 0; }
.acct-card.go .acct-txt span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.acct-av { overflow: hidden; }
.acct-av img { width: 100%; height: 100%; object-fit: cover; display: block; }
.acct-btn.small { min-height: 38px; padding: 0 14px; font-size: 14px; }
.acct-btn.quiet { background-color: transparent; color: var(--text-2); }
/* your profile, being changed: the photo and its buttons, then your name and handle */
.acct-said { margin: 0 4px; font-size: 13px; line-height: 1.4; color: var(--text-2); }
.acct-said:empty { display: none; }
.acct-said.bad { color: #ffb4a8; }
/* the places in step with the account, said beside "Saved" */

/* the day */
/* the days along the top of a day's sheet, as Weather has them: the day, and its date in a circle when it's the one shown */
.day-strip { flex: none; display: flex; gap: 2px; overflow-x: auto; scrollbar-width: none; padding: 6px 14px 4px; scroll-padding-inline: 14px;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 14px, #000 calc(100% - 14px), transparent); mask-image: linear-gradient(90deg, transparent, #000 14px, #000 calc(100% - 14px), transparent); }
.day-strip::-webkit-scrollbar { display: none; }
.ds-day { flex: none; display: flex; flex-direction: column; align-items: center; gap: 3px; min-width: 46px; min-height: 52px; padding: 4px 2px; border: 0; background: none; border-radius: 14px; cursor: pointer; color: var(--text-2); }
.ds-day span { font-size: 11.5px; font-weight: 650; letter-spacing: 0.02em; text-transform: uppercase; color: var(--text-3); }
.ds-day b { display: grid; place-items: center; width: 30px; height: 30px; border-radius: 50%; font-size: 15px; font-weight: 600; font-variant-numeric: tabular-nums; transition: background-color 0.3s, color 0.3s, transform 0.4s var(--spring); }
.ds-day[aria-current] b { background: #fff; color: #0d1626; transform: scale(1.06); }
.ds-day[aria-current] span { color: #fff; }
.ds-day:active b { transform: scale(0.9); transition-duration: var(--dur-press); }
@media (hover: hover) and (pointer: fine) { .ds-day:not([aria-current]):hover b { background-color: rgba(255, 255, 255, 0.12); } }
/* a day slides in from the side it was moved to (by the arrow keys or the strip; swiped, it follows the finger: app.js) */
#day-body, #detail-body { touch-action: pan-y pinch-zoom; }
#day-body.from-right, #detail-body.from-right { animation: from-right 0.4s var(--glide); }
#day-body.from-left, #detail-body.from-left { animation: from-left 0.4s var(--glide); }
@keyframes from-right { from { opacity: 0; transform: translateX(36px); } }
@keyframes from-left { from { opacity: 0; transform: translateX(-36px); } }
@media (prefers-reduced-motion: reduce) { #day-body:is(.from-right, .from-left), #detail-body:is(.from-right, .from-left) { animation: c-fade 0.18s var(--ease); } .ds-day b { transition: background-color var(--dur-fast), color var(--dur-fast); } }
.day-top { display: flex; align-items: center; gap: 12px; margin: 2px 0 10px; }
.day-top .wi { width: 58px; height: 58px; }
.day-top .dt-main { font-size: 18px; font-weight: 650; }
.day-top .dt-sub { color: var(--text-2); }
.day-desc { font-size: 16px; line-height: 1.5; margin: 0 0 14px; }
.parts { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; margin-bottom: 14px; }
.part { border-radius: var(--r-inner); padding: 9px 4px; display: flex; flex-direction: column; align-items: center; gap: 2px; text-align: center; }
.part .p-name { font-size: 12px; color: var(--text-3); font-weight: 600; }
.part .p-temp { font-weight: 650; }
.part .p-pop { font-size: 12px; color: var(--rain-text); font-weight: 600; min-height: 15px; }
.day-section { margin: 18px 0 6px; font-size: 12.5px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-3); font-weight: 650; }
.stats { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.stats + .models, .stats + .stats, .conf + .stats { margin-top: 10px; }
.stat { border-radius: 16px; padding: 10px 12px; }
.stat span { display: block; font-size: 12px; color: var(--text-3); }
.stat b { font-size: 16px; font-weight: 620; }
.models { width: 100%; border-collapse: collapse; font-size: 14px; font-variant-numeric: tabular-nums; }
.models th { text-align: left; font-size: 12px; color: var(--text-3); font-weight: 600; padding: 4px 0; }
.models td, .models th { padding: 7px 4px; border-bottom: 1px solid var(--line); }
.models td:not(:first-child), .models th:not(:first-child) { text-align: right; }
.conf { display: flex; align-items: center; gap: 10px; margin: 4px 0 8px; }
.conf-bar { flex: 1; height: 6px; border-radius: 3px; background: rgba(0, 0, 0, 0.22); position: relative; overflow: hidden; box-shadow: inset 0 0.5px 1px rgba(0, 0, 0, 0.3); }
.conf-bar i { position: absolute; inset: 0 auto 0 0; background: linear-gradient(90deg, #7cc4ff, var(--tint-blue)); border-radius: 3px; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4); }
.conf b { font-size: 14px; }

/* ---------- radar ---------- */
/* a button's two glyphs (play and pause; full screen and back) in one place: the one shown grows in as the other
   shrinks and blurs away, as iOS swaps its symbols */
.icon-btn > .g-on, .icon-btn > .g-off { grid-area: 1 / 1; position: relative; z-index: 3; transition: opacity 0.2s, transform 0.42s var(--spring), filter 0.2s; }
[data-on="1"] > .g-off, [data-on="0"] > .g-on, :not([data-on]) > .g-on { opacity: 0; transform: scale(0.3); filter: blur(4px); }
@media (prefers-reduced-motion: reduce) { .icon-btn > .g-on, .icon-btn > .g-off { transition: none; } }
/* full screen: the card grows from its place (a view transition, radar.js) on iOS's curve, what's in it changing over
   quickly at the start rather than the two showing through each other all the way */
::view-transition-group(radar) { animation-duration: 0.42s; animation-timing-function: var(--glide); }
::view-transition-old(radar), ::view-transition-new(radar) { animation-duration: 0.16s; }
::view-transition-old(root), ::view-transition-new(root) { animation-duration: 0.2s; }
/* (turning to another place: the sky and the bar crossfade as long as the page takes to come in, not ahead of it,
   app.js turnPage; with Reduce Motion, the page itself dissolves into the next) */
:root.turning::view-transition-old(root), :root.turning::view-transition-new(root) { animation-duration: 0.4s; }
:root.vt-fade::view-transition-image-pair(page) { isolation: isolate; }
:root.vt-fade::view-transition-old(page) { animation: vt-out 0.2s var(--ease) both; mix-blend-mode: plus-lighter; }
:root.vt-fade::view-transition-new(page) { animation: vt-in 0.2s var(--ease) both; mix-blend-mode: plus-lighter; }
@keyframes vt-out { to { opacity: 0; } }
@keyframes vt-in { from { opacity: 0; } }
/* the next hours in a line above the map: it speaks of rain, so it's not said under the wind, say, nor where the card
   above is saying it already; and it folds away (and opens) there, the map under it moving up smoothly, rather than
   the map jumping a line under a finger */
.radar-note { display: grid; grid-template-rows: 1fr; margin: 8px 0 0; font-size: 15px; font-weight: 600;
  transition: grid-template-rows 0.32s var(--glide), margin-top 0.32s var(--glide), opacity var(--dur-fast) var(--ease), visibility 0s; }
.radar-note > span, .radar-status > span { min-height: 0; overflow: hidden; }
.radar-note:has(> span:empty), .radar-note.off, [data-layer]:not([data-layer="rain"]) .radar-note, .radar.said-above:not(.radar-big) .radar-note {
  grid-template-rows: 0fr; margin-top: 0; opacity: 0; visibility: hidden;
  transition: grid-template-rows 0.32s var(--glide), margin-top 0.32s var(--glide), opacity 0.15s var(--ease), visibility 0s 0.32s; }
.radar-wrap { position: relative; margin-top: 12px; }
/* (the wind's arrows over the map, under its controls: radar.js arrows) */
/* the wind's flow over the map (radar.js): over the map, under its controls */
.wind-flow { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 2; pointer-events: none; border-radius: var(--r-inner); }
.radar.radar-big .wind-flow { border-radius: 0; }
/* (shown, it fades in, and hidden, out, once it's faded gone: drawn into the vector map, it's faded there instead,
   mapgl.js flow) */
.wind-flow { transition: opacity 0.4s var(--ease), display 0.4s allow-discrete; }
.wind-flow[hidden] { display: none; opacity: 0; }
@starting-style { .wind-flow:not([hidden]) { opacity: 0; } }
/* (on the vector map, drawn into the map itself, under its names: radar.js intoMap) */
.wind-flow.in-map { visibility: hidden; }
.radar-map { isolation: isolate; height: 320px; border-radius: var(--r-inner); overflow: hidden; background: #0e1420; box-shadow: inset 0 0 0 0.5px rgba(255, 255, 255, 0.14), 0 6px 20px -8px rgba(0, 0, 0, 0.5); }
.radar-chip { position: absolute; top: 10px; right: 10px; z-index: 500; pointer-events: none; box-sizing: border-box; display: inline-flex; justify-content: center; overflow: hidden; white-space: nowrap; font-size: 11.5px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; padding: 4px 11px; border-radius: 999px; color: #fff; background-color: rgba(14, 22, 38, 0.5); transition: background-color 0.4s var(--glide), color 0.4s var(--glide); }
.radar-chip[data-kind="model"] { background-color: rgba(255, 204, 110, 0.78); color: #2a1d00; }
/* its word, Radar or Forecast: the one not said lies over it, out of sight (the radar's above, as it's before; the
   forecast's below), so going from one to the other, one rises away as the other rises in, and back (radar.js chipTo) */
/* (the one going quickly, the one coming a moment after, so they hardly cross) */
.radar-chip .rc-l { display: block; transition: opacity 0.3s var(--glide) 0.07s, transform 0.5s var(--glide), filter 0.3s var(--glide) 0.07s; }
.radar-chip:not([data-kind="model"]) .rc-l[data-k="model"], .radar-chip[data-kind="model"] .rc-l[data-k="radar"] {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; opacity: 0; filter: blur(2px); transform: translateY(10px) scale(0.9);
  transition: opacity 0.15s, transform 0.4s var(--glide), filter 0.15s; }
.radar-chip[data-kind="model"] .rc-l[data-k="radar"] { transform: translateY(-10px) scale(0.9); }
@media (prefers-reduced-motion: reduce) { .radar-chip .rc-l { transition: opacity 0.2s; transform: none !important; filter: none !important; } }
/* "Tap to explore": at the map's foot with its scale and its ©, as far in from the edge, the same height as the ©; in
   once the credits have folded away (they share the foot) */
.radar-hint { position: absolute; bottom: 10px; left: 50%; transform: translateX(-50%); z-index: 500; pointer-events: none; display: inline-flex; align-items: center; height: 26px; padding: 0 12px; white-space: nowrap; font-size: 12.5px; font-weight: 600; border-radius: 999px; background-color: rgba(14, 22, 38, 0.5); }
.radar-hint:not([hidden]) { animation: hint-in 0.45s var(--glide) both; }
@keyframes hint-in { from { opacity: 0; transform: translateX(-50%) translateY(6px); } }
@media (prefers-reduced-motion: reduce) { .radar-hint:not([hidden]) { animation: none; } }
/* the dock, as Apple's Weather map has it: play, and what's on show (its kind over its day and time), then the
   timeline; in the card under the map, full screen a glass panel over the map's foot */
.radar { --fill: #fff; --rest: rgba(255, 255, 255, 0.18); --tick: rgba(255, 255, 255, 0.5); --panel: rgba(26, 30, 40, 0.74); --ink: #fff; --ink-2: var(--text-2); }
.radar.light-map.radar-big { --fill: #1c1c1e; --rest: rgba(60, 60, 67, 0.16); --tick: rgba(60, 60, 67, 0.4); --panel: rgba(250, 250, 252, 0.8); --ink: #1c1c1e; --ink-2: rgba(60, 60, 67, 0.72); }
.radar-dock { display: grid; grid-template-columns: auto minmax(0, 1fr); grid-template-areas: "play time" "track track"; align-items: center; gap: 8px 12px; margin-top: 12px; }
.radar-bar { display: contents; }
.radar-play { grid-area: play; }
.radar-track { grid-area: track; min-width: 0; }
/* the timeline: a groove filled up to where it is (no knob to speak of: the fill's end is it), a tick at each real
   frame, and Now marked; positions are along the thumb's travel (14px in from each end), so the marks meet it */
/* (44 tall to press, in the space of 30: it reaches 7px into the space above and below) */
/* (where it's filled to, and Now: eased when it's moved on all at once, as to Now with another layer chosen, rather than
   jumping there: .jump, radar.js; never while it plays, or under a finger) */
@property --f { syntax: "<number>"; inherits: true; initial-value: 1; }
@property --nowf { syntax: "<number>"; inherits: true; initial-value: 1; }
.radar-slider.jump { transition: --f var(--dur-base) var(--glide), --nowf var(--dur-base) var(--glide); }
.radar-slider { --f: 1; --nowf: 1; -webkit-appearance: none; appearance: none; width: 100%; height: 44px; margin: -7px 0; display: block; background: transparent; cursor: pointer; }
.radar-slider::-webkit-slider-runnable-track { height: 8px; border-radius: 999px;
  --pos: calc(14px + (100% - 28px) * var(--f)); --now: calc(14px + (100% - 28px) * var(--nowf));
  background:
    linear-gradient(90deg, transparent calc(var(--now) - 1px), var(--tick) calc(var(--now) - 1px) calc(var(--now) + 1px), transparent calc(var(--now) + 1px)),
    linear-gradient(90deg, var(--fill) 0 var(--pos), transparent var(--pos)),
    var(--rest); }
.radar-slider::-moz-range-track { height: 8px; border-radius: 999px; background: var(--rest); }
.radar-slider::-moz-range-progress { height: 8px; border-radius: 999px; background: var(--fill); }
/* (the thumb: the fill's rounded end, a size up when it's held) */
.radar-slider::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 14px; height: 14px; margin-top: -3px; border-radius: 50%; border: 0;
  background: var(--fill); box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3); transition: transform 0.4s var(--spring); }
.radar-slider::-moz-range-thumb { width: 14px; height: 14px; border-radius: 50%; border: 0; background: var(--fill); box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3); }
.radar-slider:active::-webkit-slider-thumb { transform: scale(1.5); }
.radar-slider:focus-visible { outline: none; }
.radar-slider:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 3px var(--tint-blue), 0 1px 4px rgba(0, 0, 0, 0.3); }
.radar-scale { position: relative; height: 20px; margin: 2px 14px 0; }
.rs-l { position: absolute; top: 2px; transform: translateX(-50%); font-size: 11.5px; color: var(--ink-2); white-space: nowrap; font-variant-numeric: tabular-nums; }
.rs-now { color: var(--ink); font-weight: 700; }
/* (a tick on the track at each real frame: the minutes between are worked out; lost under the fill once it's passed) */
.rs-t { position: absolute; top: -19px; width: 2px; height: 4px; margin-left: -1px; border-radius: 1px; background: var(--tick); pointer-events: none; }
/* (where the models' hours begin, after the next two: a hairline across the track, and "Hourly" over it) */
.rs-div { position: absolute; top: -23px; width: 1.5px; height: 12px; margin-left: -0.75px; border-radius: 1px; background: var(--ink-2); opacity: 0.7; pointer-events: none; }
.rs-hourly { position: absolute; top: -38px; transform: translateX(4px); font-size: 10px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; color: var(--ink-2); white-space: nowrap; pointer-events: none; }
/* the readout: what's on show over its day and time and how long ago or ahead */
.radar-time { grid-area: time; margin: 0; min-width: 0; font-variant-numeric: tabular-nums; color: var(--ink); }
.radar-time .rt-k { display: block; font-size: 16px; font-weight: 650; line-height: 1.25; }
.radar-time .rt-rel { display: block; font-size: 13px; color: var(--ink-2); font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* the legend: the radar's colours as one bar, light to extreme, and snow's beside it (radar.js: --stops, --at) */
.radar-legend { display: flex; align-items: flex-start; gap: 14px; margin: 12px 0 0; font-size: 11.5px; color: var(--text-2); }
.rl-title { display: none; }
.rl-rain { flex: 1; min-width: 0; }
.rl-bar { display: block; height: 8px; border-radius: 999px; background: linear-gradient(90deg, var(--stops)); box-shadow: inset 0 0 0 0.5px rgba(255, 255, 255, 0.25); }
.rl-words { position: relative; height: 16px; margin-top: 4px; }
.rl-words span { position: absolute; top: 0; left: var(--at); transform: translateX(-50%); white-space: nowrap; }
.rl-words span:first-child { transform: none; left: 0; }
.rl-words span:last-child { transform: translateX(-100%); left: 100%; }
.rl-snow { flex: none; width: 64px; display: flex; flex-direction: column; gap: 4px; }
/* the wind's: the wind or its gusts (radar.js gustSwitch), a small segmented choice beside its colours */
.rl-switch { flex: none; display: inline-flex; margin-top: -4px; padding: 2px; border-radius: 999px; background-color: rgba(0, 0, 0, 0.2); box-shadow: inset 0 0 0 0.5px rgba(255, 255, 255, 0.12); }
.rl-switch button { font: inherit; font-weight: 600; color: inherit; min-height: 28px; padding: 0 11px; border: 0; border-radius: 999px; background: none; cursor: pointer; transition: background-color 0.25s var(--glide), color 0.25s var(--glide); }
.rl-switch button[aria-pressed="true"] { background-color: rgba(255, 255, 255, 0.22); color: var(--text); box-shadow: 0 1px 3px rgba(0, 0, 0, 0.18); }
.rl-switch button:focus-visible { outline-offset: 1px; }
@media (hover: hover) and (pointer: fine) { .rl-switch button:not([aria-pressed="true"]):hover { background-color: rgba(255, 255, 255, 0.1); } }
.radar.light-map.radar-big .rl-switch button:focus-visible { outline-color: #1c1c1e; }

/* full screen, as Apple's Weather map: the map to every edge, an × top left, its controls top right, the legend in a
   panel under the ×, and the dock in glass at the foot */
.radar.radar-big { position: fixed; inset: 0; z-index: 20; border-radius: 0; display: block; padding: 0; overflow: hidden; --tint: rgba(10, 16, 28, 0.9); --top: calc(env(safe-area-inset-top) + 12px);
  -webkit-backdrop-filter: none; backdrop-filter: none; }
.radar.radar-big::before { display: none; }
.radar.radar-big .card-title, .radar.radar-big .radar-note { display: none; }
.radar.radar-big .radar-full { position: absolute; z-index: 600; top: var(--top); left: max(16px, env(safe-area-inset-left)); width: 44px; height: 44px; }
.radar.radar-big .radar-wrap { position: absolute; inset: 0; margin: 0; }
.radar.radar-big .radar-map { height: 100%; border-radius: 0; box-shadow: none; }
.radar.radar-big .map-ctl { top: var(--top); right: max(16px, env(safe-area-inset-right)); }
.radar.radar-big .radar-dry { top: calc(var(--top) + 10px); }
.radar.radar-big .map-scale, .radar.radar-big .radar-credit { bottom: calc(env(safe-area-inset-bottom) + 168px); }
.radar.radar-big .map-scale { left: max(16px, env(safe-area-inset-left)); }
.radar.radar-big .radar-credit { right: max(16px, env(safe-area-inset-right)); }
.radar.radar-big .radar-legend, .radar.radar-big .radar-dock {
  position: absolute; z-index: 600; color: var(--ink); background-color: var(--panel); -webkit-backdrop-filter: blur(24px) saturate(170%); backdrop-filter: blur(24px) saturate(170%);
  box-shadow: inset 0 1px 0.5px rgba(255, 255, 255, 0.45), 0 0 0 0.5px rgba(0, 0, 0, 0.12), 0 12px 32px -8px rgba(0, 0, 0, 0.35); }
.radar.radar-big .radar-legend { top: calc(var(--top) + 58px); left: max(16px, env(safe-area-inset-left)); margin: 0; flex-direction: column; gap: 10px; padding: 12px 16px 12px 14px; border-radius: 18px; font-size: 13px; color: var(--ink-2); }
.radar.radar-big .rl-title { display: block; font-size: 14px; font-weight: 600; color: var(--ink); }
.radar.radar-big .rl-rain { flex: none; display: flex; gap: 10px; height: 132px; }
.radar.radar-big .rl-rain .rl-bar { width: 6px; height: 100%; background: linear-gradient(0deg, var(--stops)); }
.radar.radar-big .rl-words { width: 72px; height: 100%; margin: 0; }
.radar.radar-big .rl-words span { left: 0; top: auto; bottom: var(--at); transform: translateY(50%); }
.radar.radar-big .rl-words span:first-child { transform: none; bottom: 0; }
.radar.radar-big .rl-words span:last-child { transform: none; left: 0; top: 0; bottom: auto; }
.radar.radar-big .rl-snow { flex-direction: row; align-items: center; gap: 10px; width: auto; }
.radar.radar-big .rl-snow .rl-bar { width: 6px; height: 22px; background: linear-gradient(0deg, var(--stops)); }
.radar.radar-big .rl-switch { margin: 0; align-self: stretch; }
.radar.radar-big .rl-switch button { flex: 1; }
.radar.radar-big .rl-switch button[aria-pressed="true"] { color: var(--ink); }
.radar.light-map.radar-big .rl-switch { background-color: rgba(0, 0, 0, 0.07); }
.radar.light-map.radar-big .rl-switch button[aria-pressed="true"] { background-color: #fff; }
.radar.radar-big .radar-dock { left: max(12px, env(safe-area-inset-left)); right: max(12px, env(safe-area-inset-right)); bottom: calc(env(safe-area-inset-bottom) + 12px); margin: 0 auto; max-width: 560px; padding: 14px 16px 8px; border-radius: 28px; }
.radar.light-map.radar-big .radar-play, .radar.light-map.radar-big .radar-full { background-color: rgba(120, 120, 128, 0.16); color: #1c1c1e; -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px); }
.radar.light-map.radar-big .radar-full { background-color: rgba(255, 255, 255, 0.8); box-shadow: 0 0 0 0.5px rgba(0, 0, 0, 0.1), 0 6px 18px -6px rgba(0, 0, 0, 0.3); }
.radar.radar-big .radar-status { display: none; }
/* (and what's missing, under it, the same way) */
.radar-status { display: grid; grid-template-rows: 1fr; margin-top: 8px;
  transition: grid-template-rows 0.32s var(--glide), margin-top 0.32s var(--glide), opacity var(--dur-fast) var(--ease), visibility 0s; }
.radar-status:is(:has(> span:empty), .off) { grid-template-rows: 0fr; margin-top: 0; opacity: 0; visibility: hidden;
  transition: grid-template-rows 0.32s var(--glide), margin-top 0.32s var(--glide), opacity 0.15s var(--ease), visibility 0s 0.32s; }
body.no-scroll { overflow: hidden; }
.radar .leaflet-container { background: #0e1420; font: inherit; }
/* OpenStreetMap's map, turned dark (the radar above it keeps its colours), where the vector map can't be drawn */
/* the radar's tiles, drawn smooth (Leaflet asks Safari to keep tiles crisp, which would show their pixels) */
.radar .rv-tiles .leaflet-tile { image-rendering: auto; }
.radar .base-tiles { filter: invert(1) hue-rotate(180deg) brightness(0.85) contrast(0.85) saturate(0.35); }
/* the vector map fades in once the country's drawn, not land-coloured first with the sea filling in after */
.radar-map .maplibregl-canvas { opacity: 0; transition: opacity 0.4s ease; }
/* (a place's page beside this one: its map as it was last shown, a picture) */
.radar-still { display: block; width: 100%; height: 100%; object-fit: cover; }
.radar-map.drawn .maplibregl-canvas { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .radar-map .maplibregl-canvas { transition: none; } }
/* the map's controls, in glass on it: zoom in and out in one capsule, back to the place below it */
.map-ctl { position: absolute; top: 10px; right: 10px; z-index: 500; display: flex; flex-direction: column; align-items: center; gap: 10px; }
.map-zoom { display: flex; flex-direction: column; border-radius: 22px; background-color: rgba(14, 22, 38, 0.42); }
.map-zoom > :first-child { border-radius: 22px 22px 0 0; }
.map-zoom > :last-child { border-radius: 0 0 22px 22px; }
.map-zoom button { position: relative; z-index: 3; width: 36px; height: 36px; display: grid; place-items: center; padding: 0; border: 0; background: transparent; color: #fff; cursor: pointer; }
.map-zoom button + button { box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14); }
.map-zoom button:disabled { color: rgba(255, 255, 255, 0.35); cursor: default; }
/* the map's buttons give under a finger and spring back, as the rest do */
.map-zoom button { transition: background-color 0.2s, transform 0.42s var(--spring), color 0.2s; }
.map-zoom button:not(:disabled):active { background: rgba(255, 255, 255, 0.22); transform: scale(0.86); transition-duration: 0.1s; }
@media (hover: hover) { .map-zoom button:not(:disabled):hover { background: rgba(255, 255, 255, 0.12); } }
.map-in, .map-out { position: relative; }
.map-in::after, .map-out::after, :is(.radar-centre, .map-layers)::after { content: ""; position: absolute; inset: -4px; border-radius: inherit; }
:is(.radar-centre, .map-layers) { width: 36px; height: 36px; display: grid; place-items: center; color: #fff; border-radius: 50%; cursor: pointer; padding: 0; background-color: rgba(14, 22, 38, 0.42); }
:is(.radar-centre, .map-layers) svg { position: relative; z-index: 3; }
/* the map's layers, chosen from a little menu of glass by its button (radar.js setKind) */
.layer-wrap { position: relative; }
.layer-menu { position: absolute; right: 46px; top: 0; z-index: 600; display: flex; flex-direction: column; min-width: 156px; padding: 5px; border-radius: 16px;
  background-color: rgba(14, 22, 38, 0.72); -webkit-backdrop-filter: var(--blur-ctl); backdrop-filter: var(--blur-ctl); box-shadow: inset 0 1px 0.5px rgba(255, 255, 255, 0.35), 0 0 0 0.5px rgba(0, 0, 0, 0.3), 0 10px 26px -8px rgba(0, 0, 0, 0.5);
  transform-origin: 100% 0; animation: menu-in 0.22s var(--glide); }
.layer-menu[hidden] { display: none; }
/* (it closes the way it opened, a little quicker: radar.js shut) */
@keyframes menu-in { from { opacity: 0; transform: scale(0.92); } }
.layer-menu button { -webkit-appearance: none; appearance: none; border: 0; background: none; color: #fff; font: inherit; font-size: 14px; font-weight: 500; text-align: left; padding: 9px 12px; border-radius: 11px; cursor: pointer; display: flex; align-items: center; gap: 8px; min-height: 40px; transition: background-color var(--dur-fast); }
@media (hover: hover) and (pointer: fine) { .layer-menu button:not([aria-pressed="true"]):hover { background-color: rgba(255, 255, 255, 0.08); } .radar.light-map .layer-menu button:not([aria-pressed="true"]):hover { background-color: rgba(0, 0, 0, 0.05); } }
.layer-menu button[aria-pressed="true"] { background: rgba(255, 255, 255, 0.16); font-weight: 650; }
.layer-menu button[aria-pressed="true"]::after { content: ""; width: 5px; height: 10px; margin: -3px 2px 0 auto; border: solid currentColor; border-width: 0 2px 2px 0; transform: rotate(45deg); }
.layer-menu button:focus-visible { outline: 2px solid #fff; outline-offset: -2px; }
.radar.light-map .layer-menu { background-color: rgba(255, 255, 255, 0.84); box-shadow: 0 0 0 0.5px rgba(0, 0, 0, 0.1), 0 10px 26px -8px rgba(0, 0, 0, 0.25); }
.radar.light-map .layer-menu button { color: #1c1c1e; }
.radar.light-map .layer-menu button[aria-pressed="true"] { background: rgba(0, 0, 0, 0.07); }
@media (prefers-reduced-motion: reduce) { .layer-menu { animation: c-fade 0.15s var(--ease); } }
/* on a phone, in the card (where a tap opens the map full screen, to pinch and pan), no zoom or back-to-the-place:
   the layers alone; full screen, all of them */
@media (pointer: coarse) { .radar:not(.radar-big) :is(.map-zoom, .radar-centre) { display: none; } }
/* the scale: a bracket drawn on the map, as Maps does */
.map-scale { position: absolute; left: 10px; bottom: 12px; z-index: 500; pointer-events: none; box-sizing: border-box; white-space: nowrap; color: #fff; border: 2px solid rgba(255, 255, 255, 0.9); border-top: 0; border-radius: 0 0 3px 3px; padding: 0 6px 1px; font-size: 11px; font-weight: 650; line-height: 1.3;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.85), 0 0 6px rgba(0, 0, 0, 0.5); box-shadow: 0 1px 1px rgba(0, 0, 0, 0.35); }
/* the place, as Apple's Weather map marks it: its temperature and sky in a bubble the colour of how warm it is
   (radar.js mark), pointing down to a dot at the very spot, its name under that */
.map-pin { position: relative; width: 0; height: 0; pointer-events: none; color: #fff; }
.mp-dot { position: absolute; left: -4px; top: -4px; width: 8px; height: 8px; box-sizing: border-box; border-radius: 50%; background: #fff; border: 1.5px solid var(--pin, #3f72c6); box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35); }
.mp-bubble { position: absolute; left: 0; bottom: 11px; transform: translateX(-50%); width: 54px; height: 54px; box-sizing: border-box; border-radius: 50%; border: 2.5px solid #fff;
  background: var(--pin, #3f72c6); box-shadow: 0 4px 14px rgba(0, 0, 0, 0.32); display: grid; justify-items: center; align-content: center; gap: 1px;
  transform-origin: 50% 100%; transition: opacity 0.25s var(--ease), scale 0.4s var(--spring), background-color 0.3s var(--ease); }
.mp-bubble::after { content: ""; position: absolute; left: 50%; bottom: -9px; transform: translateX(-50%); border: 6px solid transparent; border-top: 7px solid #fff; border-bottom: 0; }
.mp-t { font-size: 17px; font-weight: 700; line-height: 1; letter-spacing: -0.02em; padding-left: 0.2em; }
.mp-i { display: block; width: 22px; height: 22px; }
.mp-i svg { width: 22px; height: 22px; display: block; }
/* on the temperature's layer, the temperature there at the time on show, alone; on the wind's, as Apple's has it, a
   white bubble: which way it's from, how strong, and in what ("WSW / 14 / MPH") */
.mp-dir, .mp-u { display: none; }
.map-pin[data-kind] .mp-i { display: none; }
.map-pin[data-kind="temp"] .mp-t { font-size: 19px; }
.map-pin[data-kind="wind"] .mp-bubble { background: #fff; color: #1c1c1e; gap: 0; }
.map-pin[data-kind="wind"] :is(.mp-dir, .mp-u) { display: block; font-size: 9.5px; font-weight: 700; line-height: 1.1; letter-spacing: 0.02em; }
.map-pin[data-kind="wind"] .mp-t { font-size: 18px; padding-left: 0; line-height: 1.05; }
.map-pin[data-kind="wind"] .mp-dot { border-color: #2c6cb8; }
.mp-name { position: absolute; left: 0; top: 8px; transform: translateX(-50%); white-space: nowrap; font-size: 12px; font-weight: 600;
  text-shadow: 0 0 2px rgba(8, 11, 17, 0.9), 0 0 6px rgba(8, 11, 17, 0.6); }
.light-map .mp-name { color: #1c1c1e; text-shadow: 0 0 2px #fff, 0 0 6px rgba(255, 255, 255, 0.9); }
/* the other saved places (radar.js drawOthers): smaller bubbles than the place's own, each with its name under it, a tap
   going to it; on the wind's layer white, with which way it's from */
.map-other { position: relative; display: block; width: 0; height: 0; padding: 0; border: 0; background: none; color: #fff; font: inherit; cursor: pointer; pointer-events: auto; -webkit-tap-highlight-color: transparent; }
.mo-b { position: absolute; left: 0; bottom: 9px; transform: translateX(-50%); min-width: 36px; height: 36px; padding: 0 6px; box-sizing: border-box; border-radius: 999px; border: 2px solid #fff;
  background: var(--pin, #3f72c6); box-shadow: 0 3px 10px rgba(0, 0, 0, 0.3); display: grid; justify-items: center; align-content: center;
  transform-origin: 50% 100%; transition: transform 0.2s var(--spring), opacity 0.25s var(--ease), scale 0.35s var(--spring), background-color 0.3s var(--ease); }
.mo-b::after { content: ""; position: absolute; left: 50%; bottom: -7px; transform: translateX(-50%); border: 4px solid transparent; border-top: 5px solid #fff; border-bottom: 0; }
.mo-v { font-size: 13.5px; font-weight: 700; line-height: 1; letter-spacing: -0.01em; }
.mo-d { display: none; font-size: 7.5px; font-weight: 750; line-height: 1; letter-spacing: 0.02em; }
.mo-dot { position: absolute; left: -3px; top: -3px; width: 6px; height: 6px; border-radius: 50%; background: #fff; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.4); }
.mo-n { position: absolute; left: 0; top: 6px; transform: translateX(-50%); white-space: nowrap; font-size: 11px; font-weight: 600; text-shadow: 0 0 2px rgba(8, 11, 17, 0.9), 0 0 6px rgba(8, 11, 17, 0.6); }
.light-map .mo-n { color: #1c1c1e; text-shadow: 0 0 2px #fff, 0 0 6px rgba(255, 255, 255, 0.9); }
.map-other[data-kind="wind"] .mo-b { background: #fff; color: #1c1c1e; }
.map-other[data-kind="wind"] .mo-d { display: block; }
.map-other[data-empty="1"] .mo-b { opacity: 0; scale: 0.6; }
/* (each comes in as it's put on the map, as the place's own does, rather than popping up there) */
@starting-style { .map-other .mo-b { opacity: 0; scale: 0.6; } }
.map-other:active .mo-b { transform: translateX(-50%) scale(0.92); }
.map-other:focus-visible { outline: none; }
.map-other:focus-visible .mo-b { outline: 2px solid #fff; outline-offset: 2px; }
/* a reading where the map's tapped (radar.js readAt): the layer's say there, and any warning it's in, over a dot */
.map-read { position: relative; display: block; width: 0; height: 0; padding: 0; border: 0; background: none; font: inherit; cursor: pointer; pointer-events: auto; -webkit-tap-highlight-color: transparent; }
.mr-b { position: absolute; left: 0; bottom: 12px; transform: translateX(calc(-50% + var(--dx, 0px))); display: grid; gap: 2px; width: max-content; max-width: 172px; padding: 6px 11px 7px; border-radius: 12px; white-space: nowrap; text-align: center;
  color: #fff; background-color: rgba(18, 24, 36, 0.86); box-shadow: 0 0 0 0.5px rgba(255, 255, 255, 0.18), 0 6px 18px -4px rgba(0, 0, 0, 0.45); animation: read-in 0.22s var(--glide) backwards; }
.mr-v { font-size: 13.5px; font-weight: 650; line-height: 1.15; }
.mr-w { font-size: 11px; font-weight: 650; line-height: 1.15; color: #ffd60a; white-space: normal; text-wrap: balance; }
.mr-w:empty { display: none; }
.map-read[data-warn="amber"] .mr-w, .map-read[data-warn="orange"] .mr-w { color: #ffb340; }
.map-read[data-warn="red"] .mr-w { color: #ff6961; }
.mr-dot { position: absolute; left: -5px; top: -5px; width: 10px; height: 10px; box-sizing: border-box; border-radius: 50%; background: #fff; border: 2.5px solid rgba(18, 24, 36, 0.86); }
.light-map .mr-b { color: #1c1c1e; background-color: rgba(255, 255, 255, 0.92); box-shadow: 0 0 0 0.5px rgba(0, 0, 0, 0.12), 0 6px 18px -4px rgba(0, 0, 0, 0.3); }
.light-map .mr-w { color: #a07800; }
.light-map .map-read[data-warn="amber"] .mr-w, .light-map .map-read[data-warn="orange"] .mr-w { color: #b85c00; }
.light-map .map-read[data-warn="red"] .mr-w { color: #c4271d; }
/* (a point down to its spot; beside it, or under it, where over it would cover the place's own bubble or name) */
.mr-b::after { content: ""; position: absolute; left: calc(50% - var(--dx, 0px)); bottom: -6px; transform: translateX(-50%); border: 6px solid transparent; border-top-color: rgba(18, 24, 36, 0.86); border-bottom: 0; }
.map-read:is(.side, .side-l) .mr-b { bottom: auto; top: 0; transform: translateY(-50%); }
.map-read.side .mr-b { left: calc(14px + var(--dx, 0px)); }
.map-read.side-l .mr-b { left: auto; right: calc(14px - var(--dx, 0px)); }
.map-read.below .mr-b { bottom: auto; top: 30px; }
.map-read.side .mr-b::after { left: -6px; top: 50%; bottom: auto; transform: translateY(-50%); border: 6px solid transparent; border-right-color: rgba(18, 24, 36, 0.86); border-left: 0; }
.map-read.side-l .mr-b::after { left: auto; right: -6px; top: 50%; bottom: auto; transform: translateY(-50%); border: 6px solid transparent; border-left-color: rgba(18, 24, 36, 0.86); border-right: 0; }
.map-read.below .mr-b::after { bottom: auto; top: -6px; border: 6px solid transparent; border-bottom-color: rgba(18, 24, 36, 0.86); border-top: 0; }
.light-map .mr-b::after { border-top-color: rgba(255, 255, 255, 0.92); }
.light-map .map-read.side .mr-b::after { border-top-color: transparent; border-right-color: rgba(255, 255, 255, 0.92); }
.light-map .map-read.side-l .mr-b::after { border-top-color: transparent; border-left-color: rgba(255, 255, 255, 0.92); }
.light-map .map-read.below .mr-b::after { border-top-color: transparent; border-bottom-color: rgba(255, 255, 255, 0.92); }
/* (it comes in, wherever it's put beside its spot, and goes the same way, a little quicker: radar.js) */
@keyframes read-in { from { opacity: 0; translate: 0 4px; scale: 0.94; } }
@media (prefers-reduced-motion: reduce) { .mr-b { animation: c-fade 0.15s var(--ease); } .mo-b, .mp-bubble { transition: opacity var(--dur-fast); } }
/* (before the page has its temperature: the dot alone) */
.map-pin:not([data-on="1"]) .mp-bubble { opacity: 0; scale: 0.6; }
.mp-name { transition: opacity 0.25s var(--ease); }
.map-pin:not([data-on="1"]) .mp-name { opacity: 0; }
.map-pin-at { width: 0 !important; height: 0 !important; }
/* the radar's chip (Radar or Forecast): said in the dock now, as Apple's map says it; kept for its state */
.radar-chip { display: none !important; }
/* on the day map, the controls on it in light glass, their ink dark, as Apple's */
.radar.light-map .radar-map, .radar.light-map .leaflet-container { background: #f2f1ee; }
.radar.light-map .map-zoom, .radar.light-map :is(.radar-centre, .map-layers), .radar.light-map .radar-credit, .radar.light-map .radar-hint, .radar.light-map .radar-dry {
  background-color: rgba(255, 255, 255, 0.8); color: #1c1c1e; box-shadow: 0 0 0 0.5px rgba(0, 0, 0, 0.1), 0 6px 18px -6px rgba(0, 0, 0, 0.3); }
.radar.light-map .map-zoom button { color: #1c1c1e; }
.radar.light-map .map-zoom button + button { box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.1); }
.radar.light-map .map-zoom button:disabled { color: rgba(60, 60, 67, 0.3); }
.radar.light-map .map-scale { color: #1c1c1e; border-color: rgba(28, 28, 30, 0.8); text-shadow: 0 0 2px #fff, 0 0 5px rgba(255, 255, 255, 0.9); box-shadow: none; }
.radar.light-map .base-tiles { filter: saturate(0.2) brightness(1.04) contrast(0.92); }
/* the map's credits: in full for a few seconds as it first appears, then a © (that opens them all) */
.radar-credit { position: absolute; right: 10px; bottom: 10px; z-index: 500; display: grid; place-items: center; width: 26px; height: 26px; padding: 0; border-radius: 13px; cursor: pointer;
  color: #fff; font: inherit; font-size: 11px; line-height: 1; background-color: rgba(14, 22, 38, 0.5); transition: transform 0.42s var(--spring), filter 0.25s; }
.radar-credit > .rc-c { position: relative; z-index: 3; font-size: 13px; font-weight: 600; }
/* (its names in a line or two (radar.js credited), in glass reaching left from the ©: the © itself never changes size, so
   nothing moves as they fold away into it, clipped back to it) */
.radar-credit .rc-t { position: absolute; right: 0; bottom: 0; z-index: 1; box-sizing: border-box; min-height: 26px; padding: 4px 28px 4px 10px; border-radius: 13px; white-space: pre; text-align: left; line-height: 1.3;
  color: inherit; background-color: rgba(14, 22, 38, 0.62); -webkit-backdrop-filter: var(--blur-ctl); backdrop-filter: var(--blur-ctl); box-shadow: inset 0 1px 0.5px rgba(255, 255, 255, 0.35);
  clip-path: inset(0 round 13px); transition: clip-path 0.6s var(--glide), opacity 0.3s 0.25s; pointer-events: none; }
.radar.light-map .radar-credit .rc-t { background-color: rgba(255, 255, 255, 0.82); box-shadow: 0 0 0 0.5px rgba(0, 0, 0, 0.1); }
.radar-credit.folded .rc-t { clip-path: inset(0 0 0 calc(100% - 26px) round 13px); opacity: 0; }
.radar-credit:active { transform: scale(0.88); filter: brightness(1.18); transition-duration: 0.1s; }
@media (hover: hover) { .radar-credit.folded:hover .rc-t, .radar-credit.folded:focus-visible .rc-t { clip-path: inset(0 round 13px); opacity: 1; transition: clip-path 0.4s var(--glide), opacity 0.15s; } }
/* (a picture over the map fading away under the next: mapleaf.js fadeOut) */
.radar .rv-was { transition: opacity 0.26s ease; }
/* (and on that map, the rain and the temperature or wind fade into each other as the layer's changed, as they do on the
   vector map: mapgl.js opacity) */
.radar :is(.rv-mix, .rv-field) { transition: opacity 0.26s var(--ease); }
@media (prefers-reduced-motion: reduce) { .radar :is(.rv-was, .rv-mix, .rv-field) { transition: none; } }
@media (prefers-reduced-motion: reduce) { .radar-credit, .radar-credit .rc-t { transition: none; } }

/* ---------- credits ---------- */
/* each source a row in a group, as Settings lists them; out to its site */
.credits { list-style: none; margin: 0; padding: 0 14px; border-radius: 18px; }
.credits li + li { border-top: 1px solid var(--line); }
/* an official warning, in full */
.warn-from { margin: 2px 0 0; font-size: 14px; font-weight: 600; color: var(--text-2); }
.warn-badge { display: inline-block; padding: 2px 9px; border-radius: 999px; font-size: 11.5px; font-weight: 750; letter-spacing: 0.04em; text-transform: uppercase; vertical-align: 1px;
  background: linear-gradient(180deg, #ffc94d, #f5a10f); color: #241700; }
.warning-sheet[data-colour="yellow"] .warn-badge { background: linear-gradient(180deg, #ffe45c, #f2c200); color: #231c00; }
.warning-sheet[data-colour="orange"] .warn-badge { background: linear-gradient(180deg, #ffad5c, #ff8a00); color: #2a1300; }
.warning-sheet[data-colour="red"] .warn-badge { background: linear-gradient(180deg, #ff7a70, #e8453a); color: #fff; }
.warn-when { margin: 4px 0 0; font-size: 14px; color: var(--text-3); }
.warn-headline { margin: 14px 0 0; font-size: 17px; font-weight: 600; line-height: 1.38; }
#warning-body > p:not([class]) { margin: 0 0 10px; font-size: 15px; line-height: 1.5; color: var(--text-2); }
.warn-list { margin: 0; padding-left: 20px; font-size: 15px; line-height: 1.5; color: var(--text-2); }
.warn-list li { margin: 0 0 6px; }
.warn-link { margin: 16px 0 0; }
.warn-link a { display: inline-flex; align-items: center; min-height: 44px; color: var(--tint-blue); font-weight: 600; text-decoration: none; transition: opacity var(--dur-fast); }
.credits a { display: flex; align-items: center; gap: 12px; min-height: 52px; padding: 10px 0; color: inherit; text-decoration: none; transition: opacity 0.2s; }
.credits a:active { opacity: 0.55; transition-duration: var(--dur-press); }
.credits a > span { flex: 1; min-width: 0; }
.credits b { display: block; font-weight: 600; }
.credits small { display: block; margin-top: 2px; font-size: 13px; line-height: 1.35; color: var(--text-3); }
.credits .cr-out { flex: none; color: var(--text-3); }
/* (Open-Meteo's credit, as it asks for it, over the sources it brings) */
.credits-lead { margin: 0 4px 10px; font-size: 13px; line-height: 1.4; color: var(--text-2); }
.credits-lead a { color: var(--tint-blue); text-decoration: none; transition: opacity var(--dur-fast); }
.credits-note { margin: 22px 4px 0; padding-top: 14px; border-top: 1px solid var(--line); font-size: 12.5px; line-height: 1.45; color: var(--text-3); }

/* ---------- accuracy ---------- */
.models.acc td { white-space: nowrap; }
.best { margin-left: 6px; font-size: 11px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; padding: 2px 8px; border-radius: 999px; background-color: rgba(52, 199, 89, 0.34); color: #d8fbe2; vertical-align: 1px; display: inline-block; }
.tuned-note { color: #cfe7ff; margin: -4px 0 12px; }
.models .tuned-row td { color: #cfe7ff; font-weight: 650; }

/* ---------- settings: a short list of folders, each opening over it (app.js setGo) ---------- */
#settings .sheet-head { justify-content: flex-start; gap: 10px; }
#settings .sheet-head h2 { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.set-back[hidden] { display: none; }
.set-back svg { transform: rotate(90deg); }
/* a folder slides in from the right over the one it opened from, which goes back and fades as it does, and back out to
   the right again as the one under it comes back (app.js setShow); the one going laid over where it was meanwhile, out
   of the way (--top: where it was, scrolled), and the sheet never scrolled sideways by them */
#settings .sheet-body { position: relative; overflow-x: hidden; }
.set-page.set-out { position: absolute; left: 20px; right: 20px; top: var(--top, 16px); pointer-events: none; }
/* (something on its way out (a title's old words, the way back as it goes, a list's old rows): a copy laid over where it
   was as it fades, never in the way, never read out: app.js ghost) */
.ghost { position: absolute; margin: 0; pointer-events: none; box-sizing: border-box; }
/* a group of rows, as iOS's Settings has them: one rounded pane, a hairline between rows (from where the words start) */
.grp { list-style: none; margin: 0; padding: 0; border-radius: 22px; background: linear-gradient(180deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.05));
  box-shadow: inset 0 1px 0.5px rgba(255, 255, 255, 0.25), inset 0 0 0 0.5px rgba(255, 255, 255, 0.08); overflow: hidden; }
.grp:empty { display: none; }
.grp + .grp { margin-top: 18px; }
.grp > li + li { background: linear-gradient(rgba(255, 255, 255, 0.11), rgba(255, 255, 255, 0.11)) no-repeat 16px 0 / calc(100% - 16px) 0.5px; }
.grp > li > label.switch, .grp > li > label.at-row { display: flex; align-items: center; gap: 12px; min-height: 52px; padding: 0 16px; font-size: 16px; cursor: pointer; }
.grp-head { margin: 24px 16px 7px; font-size: 13px; font-weight: 600; color: var(--text-3); text-transform: uppercase; letter-spacing: 0.05em; }
.grp-foot { margin: 7px 16px 0; font-size: 13px; line-height: 1.4; color: var(--text-3); }
.grp-foot + .grp, .grp-foot + fieldset { margin-top: 22px; }
/* (signing out: one row of its own, its words in red, in the middle) */
.grp-out { display: block; width: 100%; min-height: 52px; padding: 0 16px; border: 0; background: none; font: inherit; font-size: 16px; color: #ff6961; text-align: center; cursor: pointer; transition: background-color var(--dur-fast); }
.grp-out:disabled { opacity: 0.55; cursor: default; }
.set-page .note { margin: 14px 16px 0; font-size: 13.5px; line-height: 1.4; color: var(--text-2); }
.set-page .note:empty { display: none; }
.set-page .notify-acct { margin: 10px 16px 0; }
/* (its note a footnote like the rest: in line with them, not indented twice) */
.set-page .notify-acct .note { margin: 0; font-size: 13px; color: var(--text-3); }
.set-page fieldset.opt { margin-bottom: 20px; }
.set-page fieldset.opt legend { margin-bottom: 7px; padding: 0 16px; font-size: 13px; font-weight: 600; color: var(--text-3); text-transform: uppercase; letter-spacing: 0.05em; }
/* the list: each folder a row, its own coloured icon, what's in it said beside it, and a chevron */
.folders > li + li { background-position: 58px 0; background-size: calc(100% - 58px) 0.5px; }
.folder { display: flex; align-items: center; gap: 14px; width: 100%; min-height: 52px; padding: 0 16px 0 14px; border: 0; background: none; color: inherit; font: inherit; font-size: 16px; text-align: left; cursor: pointer;
  transition: background-color 0.2s; }
.folder:active { background-color: rgba(255, 255, 255, 0.09); transition-duration: 0.05s; }
@media (hover: hover) and (pointer: fine) { .folder:hover { background-color: rgba(255, 255, 255, 0.06); } .grp-out:hover { background-color: rgba(255, 105, 97, 0.1); } .act-open:hover { background-color: rgba(255, 255, 255, 0.06); } }
.folder:focus-visible { outline: 2px solid #fff; outline-offset: -3px; border-radius: 16px; }
.folder::after { content: ""; flex: none; width: 7px; height: 7px; margin: 0 2px 0 2px; border: solid var(--text-3); border-width: 2px 2px 0 0; transform: rotate(45deg); }
.f-ic { flex: none; display: grid; place-items: center; width: 30px; height: 30px; border-radius: 8px; color: #fff; background: linear-gradient(180deg, var(--c1), var(--c2));
  box-shadow: inset 0 1px 0.5px rgba(255, 255, 255, 0.35), 0 2px 6px -2px rgba(0, 0, 0, 0.35); }
.f-ic[data-c="red"] { --c1: #ff6a5f; --c2: #e5352b; }
.f-ic[data-c="orange"] { --c1: #ffb340; --c2: #f58a00; }
.f-ic[data-c="green"] { --c1: #52d973; --c2: #25ad49; }
.f-ic[data-c="grey"] { --c1: #a2abba; --c2: #6c7587; }
.f-ic[data-c="blue"] { --c1: #5cb2ff; --c2: #1f72e6; }
.f-ic[data-c="purple"] { --c1: #b590ff; --c2: #7a4fe0; }
.f-k { flex: none; }
.f-k small { display: block; margin-top: 1px; font-size: 13px; color: var(--text-3); }
#alerts-row .folder { min-height: 62px; }
#alerts-row .f-v { color: var(--tint-blue); font-weight: 600; }
/* Arrange your page: each card a row, a switch to show it, and a handle to drag it by (settings.js drawArrange) */
.arrange li { position: relative; display: flex; align-items: center; }
.grp.arrange > li > label.switch { padding-right: 6px; }
.arrange li.dragging { z-index: 2; background: rgba(60, 72, 96, 0.96); border-radius: 14px; box-shadow: 0 10px 28px rgba(0, 0, 0, 0.4); transition: none !important; }
.arrange li.shifting { transition: transform 0.25s var(--glide); }
.arrange .switch { flex: 1; min-width: 0; }
.arr-grip { flex: none; width: 44px; height: 48px; margin-left: 2px; display: grid; place-items: center; border: 0; background: none; color: var(--text-3); cursor: grab; touch-action: none; }
.arr-grip:active { cursor: grabbing; color: var(--text); }
.arr-grip:focus-visible { outline: 2px solid #fff; outline-offset: -4px; border-radius: 12px; }
.arrange li.is-off .switch { color: var(--text-3); }
/* a card switched off there, left off the page */
main [data-off] { display: none !important; }
@media (prefers-reduced-motion: reduce) { .arrange li.shifting { transition: none; } }
.f-v { flex: 1; min-width: 0; text-align: right; color: var(--text-2); font-size: 15px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* signing in, a folder of its own */
.pill-btn { border-radius: 999px; padding: 10px 18px; font-size: 14px; font-weight: 600; cursor: pointer; }
.pill-btn > * { position: relative; z-index: 3; }
/* an activity: its name and limits (a way to its own page), and its switch */
.act { display: flex; align-items: center; }
.act-open { flex: 1; min-width: 0; display: flex; align-items: center; gap: 12px; min-height: 60px; padding: 8px 4px 8px 16px; border: 0; background: none; color: inherit; font: inherit; text-align: left; cursor: pointer; border-radius: 16px; transition: background-color var(--dur-fast); }
.act-open:active { background-color: rgba(255, 255, 255, 0.08); }
.act-open:focus-visible { outline: 2px solid #fff; outline-offset: -3px; }
.act-icon { flex: none; display: inline-flex; color: var(--text-2); }
.act-txt { flex: 1; min-width: 0; display: grid; gap: 2px; }
.act-txt b { font-size: 16px; font-weight: 600; }
.act-lim { font-size: 13px; line-height: 1.35; color: var(--text-3); }
.act-chev { flex: none; display: inline-grid; color: var(--text-3); }
.act-chev svg { transform: rotate(-90deg); }
.grp > li > label.act-on { flex: none; width: auto; padding: 0 16px 0 6px; min-height: 60px; }
.act-edit { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; width: 100%; padding: 16px; border-radius: 22px; }
.fld { display: flex; flex-direction: column; gap: 4px; font-size: 12.5px; color: var(--text-3); background: none !important; box-shadow: none !important; -webkit-backdrop-filter: none !important; backdrop-filter: none !important; padding: 0 !important; min-height: 0 !important; border-radius: 0 !important; }
fieldset.opt label.fld { align-items: stretch; }
.fld.wide { grid-column: span 2; }
.fld-in { display: flex; align-items: center; gap: 6px; }
.fld input, .fld select { background: rgba(118, 118, 128, 0.26); border: 0; border-radius: 12px; padding: 9px 11px; color: #fff; font-size: 15px; width: 100%; min-width: 0; box-shadow: inset 0 1px 0.5px rgba(255, 255, 255, 0.22); }
.fld input:focus, .fld select:focus { outline: none; box-shadow: inset 0 1px 0.5px rgba(255, 255, 255, 0.3), 0 0 0 3px rgba(159, 208, 255, 0.45); }
.fld input:-webkit-autofill { box-shadow: inset 0 1px 0.5px rgba(255, 255, 255, 0.22), inset 0 0 0 100px rgba(118, 118, 128, 0.26); }
.fld input:-webkit-autofill:focus { box-shadow: inset 0 1px 0.5px rgba(255, 255, 255, 0.3), inset 0 0 0 100px rgba(118, 118, 128, 0.26), 0 0 0 3px rgba(159, 208, 255, 0.45); }
.fld small { color: var(--text-3); }
.act-btns { grid-column: span 2; display: flex; gap: 16px; align-items: center; }
/* (both a finger's 44 points, and Remove at the other end from Done) */
.act-btns .pill-btn { min-height: 44px; }
.act-btns .link { min-height: 44px; padding: 0 10px; margin-left: auto; }
.link.danger { color: #ffb3ad; }
select option { color: #fff; background: #1c2434; }

/* ---------- a word under the bar ---------- */
/* something just done that couldn't be (the location not found, say): said under the bar for a few seconds, in glass,
   where it was asked for, then away (app.js toast) */
.toast { position: fixed; z-index: 30; top: calc(env(safe-area-inset-top) + 74px); left: 50%; translate: -50% 0; width: max-content; max-width: min(420px, calc(100vw - 32px));
  padding: 10px 16px; border-radius: 18px; font-size: 14px; line-height: 1.35; font-weight: 600; color: #fff; text-align: center; pointer-events: none;
  background-color: rgba(26, 34, 52, 0.82); -webkit-backdrop-filter: blur(22px) saturate(180%); backdrop-filter: blur(22px) saturate(180%);
  box-shadow: inset 0 1px 0.5px rgba(255, 255, 255, 0.35), 0 0 0 0.5px rgba(0, 0, 0, 0.3), 0 12px 30px -10px rgba(0, 0, 0, 0.5); }
.toast:empty { display: none; }
/* (over an open sheet too, where the browser has a top layer: app.js toast; there, only where the rule above puts it) */
.toast[popover] { right: auto; bottom: auto; margin: 0; border: 0; overflow: visible; }

/* ---------- when transparency is turned down, or contrast up ---------- */
@media (prefers-reduced-transparency: reduce) {
  .card, .ins, .tile, .section-title, dialog.sheet, .c-tip, .icon-btn, .place, .pill-btn, .seg, .radar-chip, .radar-hint, .search input, fieldset.opt label, .win-rate, .best,
  .map-zoom, :is(.radar-centre, .map-layers), .radar-credit, .top::before, .radar-dry {
    -webkit-backdrop-filter: none !important; backdrop-filter: none !important; background-image: none !important; }
  .top::before { background: rgb(20, 28, 44); }
  .radar.radar-big .radar-legend, .radar.radar-big .radar-dock { -webkit-backdrop-filter: none; backdrop-filter: none; background-color: rgb(28, 32, 42); }
  .radar.light-map.radar-big .radar-legend, .radar.light-map.radar-big .radar-dock { background-color: rgb(248, 248, 250); }
  .top.scrolled .place, .top.scrolled .icon-btn { background-color: rgb(52, 62, 80); }
  .card, .ins, .tile, .section-title, dialog.sheet, .c-tip { background-color: rgb(28, 36, 52); }
  .ins[data-level="alert"] { background-color: rgb(96, 24, 20); }
  .ins[data-level="warn"] { background-color: rgb(84, 56, 8); }
  .ins.official[data-colour="yellow"] { background-color: rgb(94, 74, 4); }
  .icon-btn, .place, .pill-btn, .radar-chip, .radar-hint, fieldset.opt label, :is(.radar-centre, .map-layers), .map-zoom,
  .radar-credit { background-color: rgb(52, 62, 80); }
  /* (the map's layers menu, its credits, and a word under the bar: solid too, nothing on the map showing through) */
  .layer-menu, .radar-credit .rc-t, .toast { -webkit-backdrop-filter: none !important; backdrop-filter: none !important; background-color: rgb(28, 36, 52); }
  .radar.light-map :is(.layer-menu, .radar-credit .rc-t) { background-color: rgb(248, 248, 250); }
}
@media (prefers-contrast: more) {
  :root { --text-2: #fff; --text-3: rgba(255, 255, 255, 0.88); --line: rgba(255, 255, 255, 0.3); }
  body { --tint: rgba(10, 14, 24, 0.7); }
  dialog.sheet, .c-tip { --tint: rgba(10, 14, 24, 0.85); }
  .card::before, .ins::before, .tile::before, .icon-btn::before, .place::before { background: rgba(255, 255, 255, 0.6); }
}

/* signing in, as on every page of the site: "or with your email" between a passkey and the form; a forgotten password and
   a new account on the account's own page */
.acct-new { margin: 0; text-align: center; font-size: 14px; color: var(--text-2, rgba(255, 255, 255, 0.7)); }
.acct-new a { color: #9cc6ff; font-weight: 600; text-decoration: none; transition: opacity var(--dur-fast); }

/* ---------- signing in on the account's page: the way there, and back ---------- */
/* The account's page is a sky of its own (a deep blue, or with a light appearance the palest lilac) with a warm dawn
   along its foot, and your photo in a circle a third of the way down. Going there, that sky comes in over everything
   (app.js handOff: in the top layer, over Settings), so that page opens on what was already in sight. Back from it (#signin=…), the page opens on the picture it ended on (early.js): your photo comes into it where
   the page had it, the picture fades as Settings comes up, and the photo flies down into the
   account's card, your places ticked off under it as they go with the account (app.js arriveFrom). None of it takes a tap:
   a tap goes to what's under it */
/* (the account page's sky exactly, and its dawn) */
:root { --acct-sky: #f3f0fb; --acct-sky-a: #e9eefc; --acct-sky-c: #f7f8fc;
  --acct-heaven: radial-gradient(120% 80% at 50% -10%, var(--acct-sky-a), var(--acct-sky) 52%, var(--acct-sky-c));
  --acct-dawn: radial-gradient(120% 50% at 50% 112%, rgba(255, 190, 150, 0.55), rgba(255, 160, 200, 0.22) 45%, transparent 72%), radial-gradient(110% 60% at 50% -12%, rgba(160, 200, 255, 0.22), transparent 62%); }
@media (prefers-color-scheme: dark) { :root { --acct-sky: #0a0f26; --acct-sky-a: #121a3c; --acct-sky-c: #05060e; } }
.handoff { position: fixed; inset: 0; width: auto; height: auto; margin: 0; padding: 0; border: 0; overflow: hidden; background: none; color: var(--text); pointer-events: none; }
.handoff-sky { position: absolute; inset: 0; opacity: 0; background: var(--acct-heaven); }
.back-in { position: fixed; inset: 0; z-index: 50; pointer-events: none;
  background: var(--acct-dawn), var(--acct-heaven);
  /* (should the script never take it on, it goes by itself after a few seconds; taken on, .held, the script sees it goes) */
  animation: back-in-off var(--dur-base) var(--ease) 6s forwards; }
.back-in.held { animation: none; }
@keyframes back-in-off { to { opacity: 0; visibility: hidden; } }
/* your photo, or your initial, as the account's page shows it; it becomes the card's as it flies (.back-in-card fading in) */
.back-in-av { position: fixed; inset: auto; left: calc(50% - 39px); top: calc(30% - 39px); width: 78px; height: 78px; margin: 0; padding: 0; border: 0;
  z-index: 51; isolation: isolate; overflow: hidden; display: grid; place-items: center; border-radius: 50%; pointer-events: none;
  color: #fff; font-size: 34px; font-weight: 700; line-height: 1;
  background: linear-gradient(160deg, #78b6ff, #3157d8 70%, #6a3fd8); box-shadow: 0 12px 30px -12px rgba(49, 87, 216, 0.7); }
.back-in-card { position: absolute; inset: 0; z-index: -1; border-radius: inherit; opacity: 0; background: linear-gradient(160deg, #6fb0ff, #2b62d6); }
.back-in-av img { position: absolute; inset: 0; z-index: 1; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity var(--dur-fast) var(--ease); }
.back-in-av img.loaded { opacity: 1; }
/* your places, going with your account as you sign in: each in its own sky, as in Places, ticked off one after another */
.acct-moved { display: grid; gap: 8px; margin: 0 4px; }
.acct-moved p { margin: 0; font-size: 13px; line-height: 1.4; color: var(--text-2); }
.acct-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.acct-chip { display: inline-flex; align-items: center; gap: 6px; max-width: 100%; min-height: 30px; padding: 0 12px 0 6px; border-radius: 999px; font-size: 13.5px; font-weight: 650; color: #fff;
  background: linear-gradient(160deg, var(--pa, #3a5a86), var(--pb, #22324c)); box-shadow: inset 0 1px 0.5px rgba(255, 255, 255, 0.4), 0 0 0 0.5px rgba(0, 0, 0, 0.3); text-shadow: 0 1px 6px rgba(0, 0, 0, 0.25); }
.acct-chip > span:last-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.acct-chip.more { padding: 0 12px; background: rgba(255, 255, 255, 0.1); }
.acct-tick { flex: none; display: grid; place-items: center; width: 19px; height: 19px; border-radius: 50%; background: var(--good); box-shadow: 0 2px 6px -2px rgba(0, 0, 0, 0.4); }
/* (autofill keeps the field as designed: the browser's yellow fill is held off for good, and the words keep their colour;
   iPhones show the yellow before the transition can hold it off, as a suggestion's offered, so it's clipped to the words
   too, under their own colour, and a field with a background of its own paints it back with an inset shadow) */
input:-webkit-autofill, input:-webkit-autofill:hover, input:-webkit-autofill:focus, textarea:-webkit-autofill, select:-webkit-autofill {
  -webkit-text-fill-color: var(--text); caret-color: var(--text);
  transition: background-color 0s 600000s, color 0s 600000s;
  -webkit-background-clip: text; background-clip: text;
}
