/*
 * The weather card (Today) and the forecast of the Weather page (Stephan
 * 2026-10-07, "Lebendigkeit"): condition glyphs, skies, the hour strip, the
 * days. Pi 4 rules hold: only transform and opacity move, no filter or
 * backdrop-filter, gradients are painted once and never animated; a change
 * of the sky cross-fades a second layer (opacity, one shot).
 *
 * Colours: every text token keeps 4.5:1 on both ends of every sky and on
 * the rain band; every part a glyph is read by (cloud, drops, snow, fog,
 * moon, the sun's rays and contour) keeps 3:1 on the skies and on the
 * card (tests/weather-tokens.test.js reads this file).
 */
@layer tokens {
  :root,
  :root[data-theme="night"] {
    --wx-sun: #ffc23d;
    --wx-sun-edge: #ffc23d;
    --wx-moon: #efe4bd;
    --wx-cloud: #d3d9e1;
    --wx-cloud-back: #8e99a8;
    --wx-drop: #5ab0f5;
    --wx-bolt: #ffc23d;
    --wx-snow: #e4edf7;
    --wx-fog: #9ca6b3;
    --wx-pop: #8fc8f7;
    --wx-wet-band: rgba(90, 176, 245, 0.14);
    --wx-range-track: #2a2f36;
    --wx-range-fill: #7fb3e3;
    --wx-hairline: rgba(255, 255, 255, 0.10);
    --wx-veil: rgba(255, 255, 255, 0.06);
    --wx-warning: #ecb862;
  }

  :root[data-theme="day"] {
    /* The sun keeps its yellow; rays and contour in a darker amber reach 3:1 (decision 2026-10-07). */
    --wx-sun: #ffc533;
    --wx-sun-edge: #9a5c00;
    --wx-moon: #5f6a96;
    --wx-cloud: #627287;
    --wx-cloud-back: #aab6c5;
    --wx-drop: #1a6fbc;
    --wx-bolt: #ffc533;
    --wx-snow: #44739f;
    --wx-fog: #627287;
    --wx-pop: #0a5694;
    --wx-wet-band: rgba(28, 116, 196, 0.10);
    --wx-range-track: #d5dce4;
    --wx-range-fill: #4f93d1;
    --wx-hairline: rgba(16, 24, 40, 0.10);
    --wx-veil: rgba(255, 255, 255, 0.62);
    /* An old forecast on the pale skies: --warning is 4.3:1 on the clear sky, this 5.5:1. */
    --wx-warning: #7e4c00;
  }

  /* Skies: a vertical gradient per condition and time of day, two tokens
     each. Night theme: deep tints that end in the card surface; day theme:
     pale tints under dark text. */
  [data-sky="clear-day"] { --sky-a: #0f3155; --sky-b: #151e29; }
  [data-sky="partly-day"] { --sky-a: #18334f; --sky-b: #161d26; }
  [data-sky="clear-night"] { --sky-a: #141d3b; --sky-b: #15171c; }
  [data-sky="partly-night"] { --sky-a: #172036; --sky-b: #15171c; }
  [data-sky="cloudy"] { --sky-a: #20262e; --sky-b: #16181b; }
  [data-sky="fog"] { --sky-a: #23272c; --sky-b: #16181b; }
  [data-sky="rain"] { --sky-a: #132435; --sky-b: #15191e; }
  [data-sky="thunder"] { --sky-a: #201b36; --sky-b: #16171d; }
  [data-sky="snow"] { --sky-a: #1b2734; --sky-b: #15191e; }
  :root[data-theme="day"] [data-sky="clear-day"] { --sky-a: #cde4f9; --sky-b: #f1f7fd; }
  :root[data-theme="day"] [data-sky="partly-day"] { --sky-a: #d5e3f1; --sky-b: #f2f5f9; }
  :root[data-theme="day"] [data-sky="clear-night"] { --sky-a: #d4d9ee; --sky-b: #f1f2f9; }
  :root[data-theme="day"] [data-sky="partly-night"] { --sky-a: #d7dbe9; --sky-b: #f2f3f8; }
  :root[data-theme="day"] [data-sky="cloudy"] { --sky-a: #dde2e8; --sky-b: #f3f5f7; }
  :root[data-theme="day"] [data-sky="fog"] { --sky-a: #e3e5e7; --sky-b: #f5f6f7; }
  :root[data-theme="day"] [data-sky="rain"] { --sky-a: #cfd9e4; --sky-b: #eef2f6; }
  :root[data-theme="day"] [data-sky="thunder"] { --sky-a: #d9d6e7; --sky-b: #f2f1f7; }
  :root[data-theme="day"] [data-sky="snow"] { --sky-a: #dfe9f2; --sky-b: #f6f9fc; }
}

@layer pages {
  /* ------------------------------------------------------------------
     Condition glyphs (src/ui/icons/conditions.js): one <svg> per moving part
     ------------------------------------------------------------------ */
  .wx-glyph {
    position: relative;
    display: inline-block;
    flex: none;
    width: var(--glyph, 40px);
    height: var(--glyph, 40px);
  }

  .wx-glyph > svg {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    overflow: visible;
  }

  .wx-sun { fill: var(--wx-sun); stroke: var(--wx-sun-edge); stroke-width: 1.1; }
  .wx-rays { fill: none; stroke: var(--wx-sun-edge); stroke-width: 2.3; stroke-linecap: round; }
  .wx-moon,
  .wx-star { fill: var(--wx-moon); }
  .wx-cloud { fill: var(--wx-cloud); }
  .wx-cloud-back { fill: var(--wx-cloud-back); }
  .wx-drop { fill: none; stroke: var(--wx-drop); stroke-width: 2.2; stroke-linecap: round; }
  .wx-drop-fine { fill: none; stroke: var(--wx-drop); stroke-width: 2; stroke-linecap: round; }
  .wx-bolt { fill: var(--wx-bolt); stroke: var(--wx-sun-edge); stroke-width: 0.9; stroke-linejoin: round; }
  .wx-flake { fill: none; stroke: var(--wx-snow); stroke-width: 1.35; stroke-linecap: round; }
  .wx-fogbar { fill: none; stroke: var(--wx-fog); stroke-width: 2.4; stroke-linecap: round; }

  /* A slot that swaps its glyph on a change: old and new stack while they cross-fade. */
  .wx-glyph-slot {
    position: relative;
    display: inline-grid;
    flex: none;
  }

  .wx-glyph-slot > .wx-glyph {
    grid-area: 1 / 1;
  }

  /* ------------------------------------------------------------------
     The weather glyph lives (Stephan 2026-10-09; ui/motion/ambient.js):
     it moves continuously while the screen is awake, a deliberate
     exception to the one-shot rule of 2026-10-07 (CLAUDE.md). Only
     transform and opacity, each on a layer of its own (the compositor
     runs them, no repaint). A glyph has no animation at all unless the
     root's gate is on (awake, the tab visible: installAmbientGate()), its
     slot is in view (weatherMotion().watch()), no sheet makes the page
     inert and motion is not reduced: asleep it is removed, not paused
     behind the black screen. Hours and days stand still.
     ------------------------------------------------------------------ */
  @keyframes wx-turn {
    from { transform: rotate(0deg); }
    to { transform: rotate(360deg); }
  }

  @keyframes wx-twinkle {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.3; }
  }

  @keyframes wx-drift {
    from { transform: translateX(-4%); }
    to { transform: translateX(4%); }
  }

  @keyframes wx-glide {
    from { transform: translateX(-7%); }
    to { transform: translateX(7%); }
  }

  @keyframes wx-fall {
    0% { transform: translateY(-14%); opacity: 0; }
    20% { opacity: 1; }
    75% { opacity: 1; }
    100% { transform: translateY(16%); opacity: 0; }
  }

  @keyframes wx-flake {
    0% { transform: translate(0, -12%); opacity: 0; }
    20% { opacity: 1; }
    50% { transform: translate(3%, 1%); }
    80% { opacity: 1; }
    100% { transform: translate(0, 14%); opacity: 0; }
  }

  @keyframes wx-flash {
    0%, 7%, 15%, 100% { opacity: 1; }
    3%, 11% { opacity: 0.3; }
  }

  @media (prefers-reduced-motion: no-preference) {
    :root[data-ambient="on"] .app-main:not([inert]) .wx-glyph-slot[data-in-view="true"] > .wx-glyph:last-child[data-day="true"] > svg[data-layer="rays"] {
      animation: wx-turn 60s linear infinite;
    }

    :root[data-ambient="on"] .app-main:not([inert]) .wx-glyph-slot[data-in-view="true"] > .wx-glyph:last-child > svg[data-layer="star1"] {
      animation: wx-twinkle 3.6s ease-in-out infinite;
    }

    :root[data-ambient="on"] .app-main:not([inert]) .wx-glyph-slot[data-in-view="true"] > .wx-glyph:last-child > svg[data-layer="star2"] {
      animation: wx-twinkle 3.6s ease-in-out -1.8s infinite;
    }

    :root[data-ambient="on"] .app-main:not([inert]) .wx-glyph-slot[data-in-view="true"] > .wx-glyph:last-child[data-condition="partly_cloudy"] > svg[data-layer="cloud"],
    :root[data-ambient="on"] .app-main:not([inert]) .wx-glyph-slot[data-in-view="true"] > .wx-glyph:last-child[data-condition="cloudy"] > svg[data-layer="front"] {
      animation: wx-drift 7s ease-in-out infinite alternate;
    }

    :root[data-ambient="on"] .app-main:not([inert]) .wx-glyph-slot[data-in-view="true"] > .wx-glyph:last-child[data-condition="cloudy"] > svg[data-layer="back"] {
      animation: wx-drift 9s ease-in-out infinite alternate-reverse;
    }

    :root[data-ambient="on"] .app-main:not([inert]) .wx-glyph-slot[data-in-view="true"] > .wx-glyph:last-child[data-condition="fog"] > svg[data-layer="bar1"] {
      animation: wx-glide 6s ease-in-out infinite alternate;
    }

    :root[data-ambient="on"] .app-main:not([inert]) .wx-glyph-slot[data-in-view="true"] > .wx-glyph:last-child[data-condition="fog"] > svg[data-layer="bar2"] {
      animation: wx-glide 6s ease-in-out infinite alternate-reverse;
    }

    /* Drops fall one after another (negative delays: already in motion when the glyph appears). */
    :root[data-ambient="on"] .app-main:not([inert]) .wx-glyph-slot[data-in-view="true"] > .wx-glyph:last-child > svg:is([data-layer="d1"], [data-layer="d2"], [data-layer="d3"], [data-layer="d4"], [data-layer="d5"]) {
      animation: wx-fall 1.4s linear infinite;
    }

    :root[data-ambient="on"] .app-main:not([inert]) .wx-glyph-slot[data-in-view="true"] > .wx-glyph:last-child > svg[data-layer="d2"] { animation-delay: -0.55s; }
    :root[data-ambient="on"] .app-main:not([inert]) .wx-glyph-slot[data-in-view="true"] > .wx-glyph:last-child > svg[data-layer="d3"] { animation-delay: -0.25s; }
    :root[data-ambient="on"] .app-main:not([inert]) .wx-glyph-slot[data-in-view="true"] > .wx-glyph:last-child > svg[data-layer="d4"] { animation-delay: -0.85s; }
    :root[data-ambient="on"] .app-main:not([inert]) .wx-glyph-slot[data-in-view="true"] > .wx-glyph:last-child > svg[data-layer="d5"] { animation-delay: -1.1s; }

    :root[data-ambient="on"] .app-main:not([inert]) .wx-glyph-slot[data-in-view="true"] > .wx-glyph:last-child[data-condition="drizzle"] > svg {
      animation-duration: 1.9s;
    }

    :root[data-ambient="on"] .app-main:not([inert]) .wx-glyph-slot[data-in-view="true"] > .wx-glyph:last-child[data-condition="heavy_rain"] > svg {
      animation-duration: 1s;
    }

    :root[data-ambient="on"] .app-main:not([inert]) .wx-glyph-slot[data-in-view="true"] > .wx-glyph:last-child > svg:is([data-layer="f1"], [data-layer="f2"], [data-layer="f3"]) {
      animation: wx-flake 2.8s linear infinite;
    }

    :root[data-ambient="on"] .app-main:not([inert]) .wx-glyph-slot[data-in-view="true"] > .wx-glyph:last-child > svg[data-layer="f2"] { animation-delay: -1s; }
    :root[data-ambient="on"] .app-main:not([inert]) .wx-glyph-slot[data-in-view="true"] > .wx-glyph:last-child > svg[data-layer="f3"] { animation-delay: -1.9s; }

    :root[data-ambient="on"] .app-main:not([inert]) .wx-glyph-slot[data-in-view="true"] > .wx-glyph:last-child[data-condition="thunder"] > svg[data-layer="bolt"] {
      animation: wx-flash 5s linear infinite;
    }
  }

  /* ------------------------------------------------------------------
     Skies: two stacked layers; a change fades the upper one in
     ------------------------------------------------------------------ */
  .wx-sky-host {
    isolation: isolate;
    overflow: hidden;
  }

  .wx-sky {
    position: absolute;
    inset: 0;
    z-index: -1;
    border-radius: inherit;
    pointer-events: none;
  }

  .wx-sky-layer {
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, var(--sky-a, transparent) 0%, var(--sky-b, transparent) 100%);
  }

  .wx-sky-layer:not([data-sky]) {
    display: none;
  }

  /* ------------------------------------------------------------------
     Today: the weather card
     ------------------------------------------------------------------ */
  .weather-card[data-layout="forecast"] {
    gap: 0;
    padding: 14px var(--space-4) 12px;
  }

  .weather-card[data-layout="forecast"] > .weather-measured-layout,
  .weather-card[data-layout="measured"] > .wx-forecast-layout {
    display: none;
  }

  .wx-forecast-layout {
    display: flex;
    flex-direction: column;
    min-width: 0;
  }

  /* Without a forecast: the card as before (pages.css .weather-card). */
  .weather-measured-layout {
    display: flex;
    flex-direction: column;
    gap: 10px;
    min-width: 0;
  }

  .wx-now {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    min-width: 0;
  }

  .wx-now-text {
    flex: 1;
    min-width: 0;
  }

  .wx-now-line {
    display: flex;
    align-items: baseline;
    gap: var(--space-2);
    min-width: 0;
  }

  .wx-temp-now {
    flex: none;
    font-size: var(--type-title3-size);
    line-height: var(--type-title3-line);
    letter-spacing: var(--type-title3-tracking);
    font-weight: var(--weight-semibold);
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
  }

  .wx-condition {
    min-width: 0;
    font-size: var(--type-headline-size);
    line-height: var(--type-headline-line);
    letter-spacing: var(--type-headline-tracking);
    font-weight: var(--weight-medium);
    white-space: nowrap;
  }

  /* The rain line: always one line (decision 2026-10-07). */
  .wx-when {
    display: flex;
    align-items: center;
    gap: 6px;
    min-width: 0;
    font-size: var(--type-body-size);
    line-height: var(--type-body-line);
    letter-spacing: var(--type-body-tracking);
    color: var(--text-secondary);
    white-space: nowrap;
  }

  .wx-when[data-tone="rain"] {
    color: var(--wx-pop);
    font-weight: var(--weight-medium);
  }

  .wx-when > .icon {
    flex: none;
  }

  /* Hours: the time, the glyph, a percentage inside the rain band, else the temperature. */
  .wx-hours {
    display: grid;
    grid-template-columns: repeat(var(--hours, 6), minmax(0, 1fr));
    margin-top: var(--space-2);
    text-align: center;
  }

  .wx-hour {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    padding: 4px 0 3px;
    border-radius: var(--radius-sm);
  }

  .wx-hour[data-wet="true"] {
    background: var(--wx-wet-band);
  }

  .wx-hour[data-wet="true"] + .wx-hour[data-wet="true"] {
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
  }

  .wx-hour[data-wet="true"]:has(+ .wx-hour[data-wet="true"]) {
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
  }

  .wx-hour-time,
  .wx-hour-value {
    font-size: var(--type-caption-size);
    line-height: var(--type-caption-line);
    letter-spacing: var(--type-caption-tracking);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
  }

  .wx-hour-time {
    color: var(--text-secondary);
  }

  .wx-hour[data-now="true"] .wx-hour-time {
    color: var(--text-primary);
    font-weight: var(--weight-semibold);
  }

  .wx-hour-value {
    font-weight: var(--weight-medium);
  }

  .wx-hour-value[data-kind="pop"] {
    color: var(--wx-pop);
  }

  /* Waiting for the first forecast: the strip keeps its height, empty. */
  .wx-hours[data-empty="true"] {
    visibility: hidden;
  }

  .wx-hours[data-empty="true"]::before {
    content: "";
    grid-column: 1 / -1;
    height: 69px;
  }

  /* The rain in millimetres (Stephan 2026-10-09): measured over 24 h with its info button, expected, the honest rule. */
  .wx-measured {
    margin-top: var(--space-2);
    padding-top: var(--space-2);
    border-top: 1px solid var(--wx-hairline);
    font-size: var(--type-caption-size);
    line-height: var(--type-caption-line);
    letter-spacing: var(--type-caption-tracking);
    color: var(--text-secondary);
  }

  .wx-measured-line {
    display: flex;
    align-items: center;
    gap: 6px;
  }

  .wx-measured-line > .icon {
    flex: none;
  }

  .wx-measured-text {
    min-width: 0;
  }

  .wx-measured-text b {
    font-weight: var(--weight-semibold);
    color: var(--text-primary);
    white-space: nowrap;
  }

  /* Under the text of the first line (the icon's 16 px and the gap). */
  .wx-expected {
    padding-left: 22px;
  }

  /* The rule led by the info button that explains it, in the column of the first line's icon, so the rule keeps
     its one line on the kiosk; its text under the text above (18 px of the button in the layout, 4 px gap). */
  .wx-rule {
    display: flex;
    align-items: center;
    gap: 4px;
  }

  .wx-rule-text {
    min-width: 0;
  }

  /* The circle-i as large as the rain icon and on its edge; the 48 px reach shifted up 2 px, so the kiosk's card
     does not clip it below its last line. At the display size's smaller step the box grows up and to the right
     only (twice --info-grow, components.css), down and to the left it would leave the card; the padding keeps
     the icon and its pressed disc where they are. */
  .wx-rule > .info-button {
    margin: calc(-16px - 2 * var(--info-grow)) calc(-14px - 2 * var(--info-grow)) -12px -16px;
    padding: calc(2 * var(--info-grow)) calc(2 * var(--info-grow)) 0 0;
  }

  .wx-rule > .info-button::before {
    inset: calc(8px + 2 * var(--info-grow)) calc(8px + 2 * var(--info-grow)) 8px 8px;
  }

  .wx-rule > .info-button > .icon {
    width: 16px;
    height: 16px;
  }

  .wx-stale {
    margin-top: 6px;
    font-size: var(--type-caption-size);
    line-height: var(--type-caption-line);
    letter-spacing: var(--type-caption-tracking);
    color: var(--wx-warning);
  }

  /* An old forecast leads to the forecast (weather-card.js): a link in the
     line, in the line's warning colour. */
  .wx-stale > .link-row.is-inline {
    color: inherit;
  }

  /* Kiosk: the upcoming runs end at a row boundary (runs-card.js snapToRows); the runs below. Below its line
     the room its link's touch box reaches into, with the card's padding (next rule). */
  .runs-more {
    flex: none;
    margin-top: var(--space-1);
    margin-bottom: calc(var(--touch-min) - var(--type-caption-line) - var(--space-1) - var(--space-4));
    font-size: var(--type-caption-size);
    line-height: var(--type-caption-line);
    letter-spacing: var(--type-caption-tracking);
    color: var(--text-secondary);
  }

  /* Its touch box reaches down from the list's edge, not up into the last
     row in view (a finger low on that row is the row's): the caption's
     line at its top, the rest of the touch height below it, inside the
     card. */
  .runs-more-link.is-inline {
    margin-top: calc(-1 * var(--space-1));
    margin-bottom: calc(var(--type-caption-line) + var(--space-1) - var(--touch-min));
    padding-top: var(--space-1);
    padding-bottom: calc(var(--touch-min) - var(--type-caption-line) - var(--space-1));
  }

  /* ------------------------------------------------------------------
     Weather page: "Now" with the sky, the forecast
     ------------------------------------------------------------------ */
  .wx-hero {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    margin-top: var(--space-1);
  }

  .wx-hero-text {
    min-width: 0;
  }

  .wx-hero-text > .current-hero {
    margin-top: 0;
  }

  .wx-hero-condition {
    font-size: var(--type-title3-size);
    line-height: var(--type-title3-line);
    letter-spacing: var(--type-title3-tracking);
    font-weight: var(--weight-medium);
  }

  .wx-hero-range {
    color: var(--text-secondary);
  }

  .wx-hero-when {
    margin-top: var(--space-3);
    font-size: var(--type-headline-size);
    line-height: var(--type-headline-line);
    letter-spacing: var(--type-headline-tracking);
  }

  /* The rain line leads to its hours (plan of 2026-10-10): one line in the layout, the touch height for a finger. */
  .wx-when-link {
    width: fit-content;
    max-width: 100%;
    margin: calc(var(--space-3) - (var(--touch-min) - var(--type-headline-line)) / 2) 0
      calc((var(--type-headline-line) - var(--touch-min)) / 2);
    padding: calc((var(--touch-min) - var(--type-headline-line)) / 2) 0;
    text-align: left;
  }

  .wx-when-chevron {
    flex: none;
    color: var(--text-tertiary);
  }

  /* The forecast day sheet (sheets/weather/forecast-day-sheet.js). */
  .forecast-day-sheet {
    display: grid;
    gap: var(--space-4);
    padding-bottom: var(--space-2);
  }

  .forecast-day-sky {
    display: flex;
    align-items: center;
    gap: var(--space-3);
  }

  .forecast-day-sky > .prose {
    margin-top: 0;
  }

  .forecast-day-hours {
    display: grid;
    gap: var(--space-2);
  }

  .forecast-day-sheet > .history-note {
    margin-top: 0;
  }

  /* Station tiles on the sky: a light veil (a colour with alpha, no blur). */
  .current-card[data-sky] .weather-tile {
    background: var(--wx-veil);
  }

  .wx-forecast-note {
    margin-top: var(--space-1);
    color: var(--text-secondary);
  }

  .wx-forecast-part {
    min-width: 0;
  }

  .wx-section-key {
    margin: var(--space-2) 0 var(--space-1);
    font-size: var(--type-caption-size);
    line-height: var(--type-caption-line);
    letter-spacing: var(--type-caption-tracking);
    color: var(--text-secondary);
  }

  .wx-strip {
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
  }

  .wx-strip::-webkit-scrollbar {
    display: none;
  }

  .wx-strip > .wx-hours {
    display: flex;
    width: max-content;
    margin-top: 0;
  }

  .wx-strip .wx-hour {
    width: 48px;
    padding: 6px 0 5px;
  }

  .wx-days {
    display: flex;
    flex-direction: column;
    margin: 0;
    padding: 0;
    list-style: none;
  }

  .wx-day {
    border-top: 1px solid var(--hairline);
    font-variant-numeric: tabular-nums;
  }

  .wx-day-row {
    display: grid;
    grid-template-columns: 52px 28px 44px 34px minmax(40px, 1fr) 34px;
    align-items: center;
    gap: var(--space-2);
    width: 100%;
    min-height: 40px;
    text-align: left;
  }

  /* A day leads to its sheet (plan of 2026-10-10): the touch height, a chevron at the end. */
  .wx-day-row.is-link {
    grid-template-columns: 52px 28px 44px 34px minmax(40px, 1fr) 34px 16px;
    min-height: var(--touch-min);
  }

  .wx-day-chevron {
    color: var(--text-tertiary);
  }

  .wx-day:first-child {
    border-top: 0;
  }

  .wx-day-name {
    font-weight: var(--weight-medium);
  }

  .wx-day-pop {
    font-size: var(--type-caption-size);
    line-height: var(--type-caption-line);
    letter-spacing: var(--type-caption-tracking);
    font-weight: var(--weight-medium);
    color: var(--wx-pop);
  }

  .wx-day-min {
    text-align: right;
    color: var(--text-secondary);
  }

  .wx-day-max {
    text-align: right;
    font-weight: var(--weight-medium);
  }

  .wx-range {
    position: relative;
    height: 5px;
    border-radius: var(--radius-full);
    background: var(--wx-range-track);
    overflow: hidden;
  }

  .wx-range > i {
    position: absolute;
    top: 0;
    bottom: 0;
    border-radius: var(--radius-full);
    background: var(--wx-range-fill);
  }

  .wx-source {
    margin-top: var(--space-3);
    font-size: var(--type-caption-size);
    line-height: var(--type-caption-line);
    letter-spacing: var(--type-caption-tracking);
    color: var(--text-secondary);
  }

  .wx-source[data-stale="true"] {
    color: var(--wx-warning);
  }

  /*
   * Kiosk (Stephan 2026-10-08): the forecast card gives way to its two parts.
   * "Now" (heading, note, 24 hours) stands in the right column under the
   * measured rain, beside the tall "Jetzt"; "week" (the seven days, in two
   * columns of rows: down, then across) below both in full width. The second
   * row takes only what "Jetzt" needs beyond the rain card (1fr), so the hours
   * start right under it. Without the forecast card the grid stays as it was.
   */
  @container app (min-width: 960px) {
    .weather-grid:has(> .wx-forecast-card:not([hidden])) {
      grid-template-rows: auto 1fr;
    }

    .weather-grid:has(> .wx-forecast-card:not([hidden])) > .current-card {
      grid-row: 1 / span 2;
      grid-column: 1;
    }

    .weather-grid:has(> .wx-forecast-card:not([hidden])) > .rain-card {
      grid-row: 1;
      grid-column: 2;
    }

    /*
     * The hours stay on the first screen whatever the rain card holds (review
     * 2026-10-09: two days in the 24 hours and "Regnet gerade" ended the strip
     * at 676 px). The page's title is the nav item beside it, so it is kept for
     * screen readers only, as Today's page head (layout.css); a day of the
     * rain list is one line, its kind and when, the amount at the end.
     */
    .page-weather:has(> .weather-grid > .wx-forecast-card:not([hidden])) > .history-head {
      position: absolute;
      width: 1px;
      height: 1px;
      min-height: 0;
      overflow: hidden;
      clip-path: inset(50%);
      white-space: nowrap;
    }

    .weather-grid:has(> .wx-forecast-card:not([hidden])) .rain-phase {
      min-height: 0;
    }

    .weather-grid:has(> .wx-forecast-card:not([hidden])) .rain-phase-text {
      flex-direction: row;
      flex-wrap: wrap;
      align-items: baseline;
      gap: 0 var(--space-2);
    }

    /*
     * The worst case of the first screen: "Regnet gerade", the rain pause
     * in two lines and two days in the list, yesterday's marked "Nicht
     * mitgezählt" (the engine's phantom rain note from 02:00 on; the badge
     * takes the row to two lines in German). It ended the strip at 613 px
     * (2026-10-10, without the badge), then at 611 px with it. While the
     * card carries a note about the rain now, the notes follow the totals
     * and the list's head follows the notes at a group's gap, the days
     * follow the range control closely, and the forecast's heading has no
     * 32 px row of its own (it holds no control): the note follows it as a
     * subtitle. The strip ends at 595 px then, 577 px without the badge.
     */
    .weather-grid:has(> .wx-forecast-card:not([hidden])) .rain-now,
    .weather-grid:has(> .wx-forecast-card:not([hidden])) .rain-pause-line {
      margin-top: var(--space-2);
    }

    .weather-grid:has(> .wx-forecast-card:not([hidden])) .rain-now:not([hidden]) + .rain-pause-line {
      margin-top: var(--space-1);
    }

    .weather-grid:has(> .wx-forecast-card:not([hidden])) .rain-now:not([hidden]) ~ .rain-phases-head,
    .weather-grid:has(> .wx-forecast-card:not([hidden])) .rain-pause-line:not([hidden]) ~ .rain-phases-head,
    .weather-grid:has(> .wx-forecast-card:not([hidden])) :is(.rain-now, .rain-pause-line):not([hidden]) ~ .rain-days > .rain-phases-head {
      margin-top: var(--space-2);
    }

    .weather-grid:has(> .wx-forecast-card:not([hidden])) .rain-phases {
      margin-top: var(--space-1);
    }

    .wx-forecast-now > .history-card-head {
      min-height: 0;
    }

    .wx-forecast-card {
      display: contents;
    }

    /* The card's look (components.css .card) on each part. */
    .wx-forecast-now,
    .wx-forecast-week {
      position: relative;
      z-index: var(--z-content);
      min-width: 0;
      padding: var(--space-4);
      border-radius: var(--radius-card);
      background: var(--surface-1);
      box-shadow: var(--card-edge);
    }

    .wx-forecast-now {
      grid-row: 2;
      grid-column: 2;
    }

    .wx-forecast-week {
      grid-row: 3;
      grid-column: 1 / -1;
    }

    .wx-forecast-week > .wx-forecast-part:first-child > .wx-section-key {
      margin-top: 0;
    }

    .wx-days {
      display: grid;
      grid-template-rows: repeat(4, auto);
      grid-auto-flow: column;
      grid-auto-columns: minmax(0, 1fr);
      column-gap: var(--space-8);
    }

    .wx-day:nth-child(5) {
      border-top: 0;
    }
  }

  @container app (max-width: 699px) {
    .wx-hero {
      gap: var(--space-3);
    }
  }
}
