/**
 * WS40 Consolle — frontend layout (structural base, Phase 3).
 * Palette/tokens shared with the WS40 Dashboard. Phase 4 refines the chrome
 * (charts, compass, webcam) — this file owns the zone grid + block shells.
 */

.ws40con {
    --ws40con-blue: #1f6fd6;
    --ws40con-ink: #0f1c2e;
    --ws40con-amber: #d97706;
    --ws40con-canvas: #eef2f7;
    --ws40con-card-bg: #ffffff;
    --ws40con-border: #dbe4ef;
    --ws40con-muted: #5b6b7f;
    --ws40con-radius: 16px;
    --ws40con-gap: 14px;
    --ws40con-shadow: 0 1px 2px rgba(15, 28, 46, 0.04), 0 2px 6px rgba(15, 28, 46, 0.05);

    display: block;
    background: var(--ws40con-canvas);
    color: var(--ws40con-ink);
    border-radius: var(--ws40con-radius);
    padding: var(--ws40con-gap);
    font-size: calc(14px * var(--ws40con-fs, 1));
    line-height: 1.45;
    box-sizing: border-box;
    width: 100%;
    /* Containment guard: stay shrinkable as a flex/grid child of the theme,
       never exceed the available width, and clip any horizontal bleed so a
       single wide block can never push the whole page into horizontal scroll. */
    min-width: 0;
    max-width: 100%;
    overflow-x: clip;
}

.ws40con *,
.ws40con *::before,
.ws40con *::after {
    box-sizing: inherit;
}

/* ── Host-theme armour ───────────────────────────────────────────────────
   Third-party themes style semantic tags aggressively and those rules leak
   into the Consolle. Measured on live installs: a magazine theme forced
   `height:38px` on every <button>, so the cards (which need ~62px) spilled
   outside their own box; another theme forced `white-space:nowrap` +
   `text-overflow:ellipsis` on <dt> and hung a decorative 16x2px `::before`
   bar before every label, truncating the text and prefixing it with a dash.

   This block only NEUTRALISES what a host theme can impose — it never sets
   Consolle design, which lives in the sections below and overrides it by
   source order. Scoped to bare tags inside .ws40con, so the Consolle's own
   pseudo-elements (e.g. .ws40con-stat__striphld scroll shadows, on a div)
   are deliberately untouched.

   `!important` is required, not lazy: on the real sites the theme rules won
   on specificity against our own class selectors. Do not remove it.
   <dd> is excluded from the white-space reset: .ws40con-full__val keeps
   `nowrap` by design, so a number and its unit never split across lines. */

.ws40con button,
.ws40con dl,
.ws40con dt,
.ws40con dd,
.ws40con h1,
.ws40con h2,
.ws40con h3,
.ws40con h4,
.ws40con p,
.ws40con small,
.ws40con table,
.ws40con tr,
.ws40con td {
    height: auto !important;
    min-height: 0 !important;
    max-height: none !important;
    text-overflow: clip !important;
    font-family: inherit;
    font-style: inherit;
    text-transform: none;
    letter-spacing: normal;
    text-decoration: none;
    text-shadow: none;
    float: none;
    list-style: none;
}

.ws40con button,
.ws40con dl,
.ws40con dt,
.ws40con h1,
.ws40con h2,
.ws40con h3,
.ws40con h4,
.ws40con p,
.ws40con small {
    white-space: normal !important;
}

/* Decorative markers/bars themes attach to headings, list terms and buttons. */
.ws40con button::before, .ws40con button::after,
.ws40con dl::before,     .ws40con dl::after,
.ws40con dt::before,     .ws40con dt::after,
.ws40con dd::before,     .ws40con dd::after,
.ws40con h1::before,     .ws40con h1::after,
.ws40con h2::before,     .ws40con h2::after,
.ws40con h3::before,     .ws40con h3::after,
.ws40con h4::before,     .ws40con h4::after,
.ws40con p::before,      .ws40con p::after,
.ws40con small::before,  .ws40con small::after {
    content: none !important;
}

/* ── Zones ───────────────────────────────────────────────────────────── */

/* Top band: full width — uses negative margins to escape any flex/grid context */
.ws40con__zone--top {
    display: block;
    width: 100%;
    max-width: 100%;
    margin-bottom: var(--ws40con-gap);
    /* Ensure it's never constrained by a sibling grid */
    align-self: stretch;
    grid-column: 1 / -1;
}

/* Bottom band: full width, mirrors the top band (sits below the column grid) */
.ws40con__zone--bottom {
    display: block;
    width: 100%;
    max-width: 100%;
    margin-top: var(--ws40con-gap);
    align-self: stretch;
    grid-column: 1 / -1;
}

/* Direction: vertical — blocks stacked (top & bottom) */
.ws40con__zone--top.ws40con__zone--v,
.ws40con__zone--bottom.ws40con__zone--v {
    display: flex;
    flex-direction: column;
    gap: var(--ws40con-gap);
}

/* Direction: horizontal — blocks side by side, equal width, wrap on small screens */
.ws40con__zone--top.ws40con__zone--h,
.ws40con__zone--bottom.ws40con__zone--h {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    gap: var(--ws40con-gap);
    align-items: stretch;
}

.ws40con__zone--top.ws40con__zone--h > .ws40con-block,
.ws40con__zone--bottom.ws40con__zone--h > .ws40con-block {
    flex: 1 1 240px;
    min-width: 0;
}

@media (max-width: 600px) {
    .ws40con__zone--top.ws40con__zone--h,
    .ws40con__zone--bottom.ws40con__zone--h {
        flex-direction: column;
        flex-wrap: nowrap;
    }
    .ws40con__zone--top.ws40con__zone--h > .ws40con-block,
    .ws40con__zone--bottom.ws40con__zone--h > .ws40con-block {
        flex-basis: auto;
        width: 100%;
    }
}

/* ── Column grid ─────────────────────────────────────────────────────── */

.ws40con__grid {
    display: grid;
    width: 100%;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--ws40con-gap);
    align-items: start;
}

.ws40con__grid.has-left {
    grid-template-columns: 20% minmax(0, 1fr); /* fallback, overridden inline */
}

.ws40con__grid.has-right {
    grid-template-columns: minmax(0, 1fr) 25%; /* fallback, overridden inline */
}

.ws40con__grid.has-left.has-right {
    grid-template-columns: 20% minmax(0, 1fr) 25%; /* fallback, overridden inline */
}

.ws40con__col {
    display: flex;
    flex-direction: column;
    gap: var(--ws40con-gap);
    min-width: 0;
}

/* ── Block shell ─────────────────────────────────────────────────────── */

.ws40con-block {
    background: var(--ws40con-card-bg);
    border: 1px solid var(--ws40con-border);
    border-radius: var(--ws40con-radius);
    /* Elevation is driven by the Appearance control (--ws40con-shadow). */
    box-shadow: var(--ws40con-shadow);
    overflow: hidden;
    /* Never let flex/grid content-sizing (e.g. a wrapping column flex on mobile)
       grow the card past its container; this keeps wide inner content scrollable
       instead of clipped, in every zone/orientation. */
    min-width: 0;
    max-width: 100%;
    /* Header always on top, body below — never side-by-side regardless of zone context. */
    display: flex;
    flex-direction: column;
}

.ws40con-block__head {
    background: var(--ws40con-blue);
    color: #fff;
    padding: 8px 14px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
}

.ws40con-block__head-extra {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-shrink: 0;
}

.ws40con-block__title {
    margin: 0;
    font-size: calc(13px * var(--ws40con-fs, 1));
    font-weight: 600;
    letter-spacing: 0.02em;
    text-transform: uppercase;
}

.ws40con-block__body {
    padding: 12px 14px;
    min-width: 0;
}

.ws40con-empty {
    margin: 0;
    color: var(--ws40con-muted);
    font-style: italic;
}

/* ── Cards ───────────────────────────────────────────────────────────── */

.ws40con-cards .ws40con-block__body {
    padding: 10px;
}

.ws40con-cards__grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
    gap: 10px;
}

.ws40con-card {
    appearance: none;
    border: 1px solid var(--ws40con-border);
    border-left: 4px solid var(--ws40con-accent, var(--ws40con-border));
    border-radius: 12px;
    background: var(--ws40con-card-bg);
    padding: 10px 12px;
    text-align: left;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    gap: 4px;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

/* Per-metric accent colours (match the WS40 Dashboard palette). */
.ws40con-card[data-ws40con-field="temp"]     { --ws40con-accent: #e0533d; }
.ws40con-card[data-ws40con-field="humidity"] { --ws40con-accent: #2f8fd6; }
.ws40con-card[data-ws40con-field="pressure"] { --ws40con-accent: #7c6fd6; }
.ws40con-card[data-ws40con-field="wind"]     { --ws40con-accent: #13a89a; }
.ws40con-card[data-ws40con-field="gust"]     { --ws40con-accent: #0d9488; }
.ws40con-card[data-ws40con-field="rain"]     { --ws40con-accent: #2563eb; }
.ws40con-card[data-ws40con-field="feels"]    { --ws40con-accent: #f0743a; }
.ws40con-card[data-ws40con-field="dew"]      { --ws40con-accent: #06b6d4; }
.ws40con-card[data-ws40con-field="uv"]       { --ws40con-accent: #eab308; }

.ws40con-card:hover,
.ws40con-card:focus-visible {
    border-color: var(--ws40con-accent, var(--ws40con-blue));
    outline: none;
}

.ws40con-card.is-active {
    border-color: var(--ws40con-accent, var(--ws40con-blue));
    box-shadow: 0 0 0 2px var(--ws40con-accent, var(--ws40con-blue));
}

.ws40con-card__label {
    color: var(--ws40con-muted);
    font-size: calc(11px * var(--ws40con-fs, 1));
    line-height: 1.25;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    /* Long words (e.g. German "Luftfeuchtigkeit") wrap cleanly instead of overflowing. */
    overflow-wrap: anywhere;
    word-break: break-word;
    hyphens: auto;
}

.ws40con-card__value {
    font-size: calc(20px * var(--ws40con-fs, 1));
    font-weight: 700;
    color: var(--ws40con-ink);
    /* Keep the number and its unit together; allow wrap only between words. */
    overflow-wrap: break-word;
}

/* ── Chart ───────────────────────────────────────────────────────────── */

.ws40con-chart__tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-bottom: 10px;
}

.ws40con-chart__period {
    appearance: none;
    border: 1px solid var(--ws40con-border);
    background: var(--ws40con-card-bg);
    color: var(--ws40con-muted);
    border-radius: 999px;
    font-size: calc(12px * var(--ws40con-fs, 1));
    padding: 4px 12px;
    cursor: pointer;
}

.ws40con-chart__period.is-active {
    background: var(--ws40con-blue);
    border-color: var(--ws40con-blue);
    color: #fff;
}

.ws40con-chart__canvas {
    position: relative;
    min-height: 220px;
}

.ws40con-chart__el {
    width: 100%;
    height: 220px;
    display: block;
}

/* ── Full data ───────────────────────────────────────────────────────── */

.ws40con-full__grid {
    columns: 200px;
    column-gap: 24px;
}

.ws40con-full__col {
    min-width: 0;
    break-inside: avoid;
    -webkit-column-break-inside: avoid;
    margin-bottom: 16px;
}

.ws40con-full__gtitle {
    margin: 0 0 4px;
    font-size: calc(11px * var(--ws40con-fs, 1));
    font-weight: 700;
    color: var(--ws40con-blue);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    border-bottom: 2px solid var(--ws40con-blue);
    padding-bottom: 4px;
}

.ws40con-full__list {
    margin: 0;
    padding: 0;
}

.ws40con-full__row {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: center;
    gap: 6px;
    border-bottom: 1px dashed var(--ws40con-border);
    padding: 4px 0;
    font-size: calc(13px * var(--ws40con-fs, 1));
}

/* Quando le icone sono attive, la riga ha uno slot icona fisso a sinistra */
.ws40con-full__icon {
    flex: 0 0 30px;
    width: 30px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.ws40con-full__label {
    color: var(--ws40con-muted);
    font-size: var(--ws40con-label-size, inherit);
    flex: 1 1 auto;
    min-width: 0;
    /* Long single words (e.g. German "Windgeschwindigkeit") wrap instead of overlapping the value. */
    overflow-wrap: anywhere;
    word-break: break-word;
    hyphens: auto;
    line-height: 1.25;
}

/* 3h trend indicator. The bare arrows (U+2191/2193/2192) are hairline glyphs:
   at the Consolle's body size they nearly vanished, and rising/falling/steady
   all rendered in the same ink. Filled triangles read at a glance, and the
   direction carries a colour. The mid tones are picked to stay legible on both
   the light card (#fff) and the dark one (#1a2030); a theme can override them
   through the two variables. */
.ws40con-full__trend {
    /* The triangle glyphs fill only part of their em box, so at the body size
       they read smaller than the text beside them. 18px balances them against a
       13px value; line-height 1 and the slight nudge keep the row height and the
       optical baseline unchanged. */
    font-size: calc(18px * var(--ws40con-fs, 1));
    line-height: 1;
    font-weight: 700;
    display: inline-block;
    vertical-align: -1px;
}
.ws40con-full__trend--up   { color: var(--ws40con-trend-up, #2e9e5b); }
.ws40con-full__trend--down { color: var(--ws40con-trend-down, #e0574f); }
.ws40con-full__trend--flat { color: var(--ws40con-muted); font-size: calc(13px * var(--ws40con-fs, 1)); }
/* Signed 3h value shown next to the trend arrow (e.g. "+0,8 °C · 3h"). Slightly
   smaller than the glyph so the arrow stays the primary cue; inherits the
   direction colour from the parent. */
.ws40con-full__trendval { font-size: calc(11px * var(--ws40con-fs, 1)); font-weight: 600; white-space: nowrap; }

.ws40con-full__val {
    margin: 0;
    font-weight: 700;
    font-size: var(--ws40con-value-size, inherit);
    color: var(--ws40con-ink);
    /* Allow a long annotation (e.g. "max 91.4 mm/h at 16:49") to wrap UNDER the
       value instead of forcing the whole row wide and starving the label. */
    white-space: normal;
    text-align: right;
    flex: 0 1 auto;
    min-width: 0;
}

/* Keep the reading itself (number + unit) on one line; only the annotation wraps. */
.ws40con-full__val > [data-ws40con-value] {
    white-space: nowrap;
}

.ws40con-full__time {
    font-weight: 400;
    color: var(--ws40con-muted);
    font-size: calc(11px * var(--ws40con-fs, 1));
    margin-left: 4px;
    white-space: nowrap;
}

/* DT-27: native daily peak on its own full-width line under the value, so the long
   annotation ("max 91.4 mm/h at 16:49") has the whole column width and never
   squeezes the label. flex-basis 100% forces it onto the next flex line. */
.ws40con-full__maxline {
    flex: 0 0 100%;
    text-align: right;
    font-weight: 400;
    font-size: calc(11px * var(--ws40con-fs, 1));
    color: var(--ws40con-muted);
    line-height: 1.3;
    margin-top: -2px;
}

@media (max-width: 600px) {
    .ws40con-full__grid {
        columns: 1;
    }
}

/* ── Gauges ──────────────────────────────────────────────────────────── */

.ws40con-gauges__grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
    gap: 12px;
}

.ws40con-g {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 10px;
    border: 1px solid var(--ws40con-border);
    border-radius: 12px;
    background: var(--ws40con-card-bg);
}

.ws40con-g__label {
    font-size: calc(11px * var(--ws40con-fs, 1));
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--ws40con-muted);
    margin: 0;
    overflow-wrap: anywhere;
    word-break: break-word;
    hyphens: auto;
}

.ws40con-g__current {
    margin: 0;
}

.ws40con-g__value {
    font-size: calc(22px * var(--ws40con-fs, 1));
    font-weight: 700;
    color: var(--ws40con-ink);
}

.ws40con-g__svg {
    width: 100%;
    max-width: 200px;
    display: block;
    margin: 4px auto 0;
}

/* Vertical bar */

.ws40con-g__vert {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 3px;
    margin: 4px auto 0;
    font-size: calc(10px * var(--ws40con-fs, 1));
    color: var(--ws40con-muted);
}

.ws40con-g__vert-track {
    height: 100px;
    background: var(--ws40con-border);
    position: relative;
    overflow: hidden;
    flex-shrink: 0;
}

.ws40con-g__vert-fill {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    transition: height 0.4s ease;
}

/* Secondary row */

.ws40con-g__sub {
    display: flex;
    justify-content: space-between;
    gap: 6px;
    font-size: calc(11px * var(--ws40con-fs, 1));
    color: var(--ws40con-muted);
    margin-top: 4px;
}

.ws40con-g__sub-item strong {
    color: var(--ws40con-ink);
    font-weight: 700;
}

.ws40con-g__trend {
    font-size: calc(16px * var(--ws40con-fs, 1));
    font-weight: 700;
    color: var(--ws40con-ink);
}
/* Directional colour + compact sizing when the gauge trend carries the signed
   3h value ("▲ +1,2 hPa · 3h"). */
.ws40con-g__trend--up   { color: var(--ws40con-trend-up, #2e9e5b); font-size: calc(12px * var(--ws40con-fs, 1)); }
.ws40con-g__trend--down { color: var(--ws40con-trend-down, #e0574f); font-size: calc(12px * var(--ws40con-fs, 1)); }
.ws40con-g__trend--flat { color: var(--ws40con-muted); font-size: calc(12px * var(--ws40con-fs, 1)); }

/* ── Compass (standalone block) ──────────────────────────────────────── */

.ws40con-compass2 {
    display: flex;
    flex-wrap: nowrap;
    align-items: center;
    justify-content: center;
    gap: 16px;
}

/* Su mobile: stesso layout del desktop (bussola + dati affiancati), centrato.
   La bussola si rimpicciolisce per stare accanto al testo su schermi stretti. */
@media (max-width: 640px) {
    .ws40con-compass2 {
        justify-content: center;
        gap: 12px;
    }
    .ws40con-compass2--large  .ws40con-compass2__svg { width: 120px; height: 120px; }
    .ws40con-compass2--medium .ws40con-compass2__svg { width: 100px; height: 100px; }
    .ws40con-compass2--small  .ws40con-compass2__svg { width:  70px; height:  70px; }
    .ws40con-compass2__info  { min-width: 0; }
    .ws40con-compass2__dir   { font-size: calc(22px * var(--ws40con-fs, 1)); }
    .ws40con-compass2__spd   { font-size: calc(13px * var(--ws40con-fs, 1)); white-space: nowrap; }
    .ws40con-compass2__gust  { font-size: calc(11px * var(--ws40con-fs, 1)); white-space: nowrap; }
}

.ws40con-compass2__svg {
    flex-shrink: 0;
    overflow: visible;
}

/* Size variants — controlled via class, not inline style */
.ws40con-compass2--small  .ws40con-compass2__svg { width:  80px; height:  80px; }
.ws40con-compass2--medium .ws40con-compass2__svg { width: 140px; height: 140px; }
.ws40con-compass2--large  .ws40con-compass2__svg { width: 180px; height: 180px; }

.ws40con-compass2__ring-outer {
    fill: var(--ws40con-card-bg);
    stroke: var(--ws40con-border);
    stroke-width: 1.5;
}

.ws40con-compass2__ring-inner {
    fill: none;
    stroke: var(--ws40con-border);
    stroke-width: 0.5;
    stroke-dasharray: 2 3;
}

.ws40con-compass2__tick {
    stroke: var(--ws40con-muted);
    stroke-width: 0.8;
}

.ws40con-compass2__tick--major {
    stroke: var(--ws40con-ink);
    stroke-width: 1.5;
}

/* Cardinal labels inside ring: N E S W */
.ws40con-compass2__card {
    font-size: calc(9px * var(--ws40con-fs, 1));
    font-weight: 700;
    fill: var(--ws40con-ink);
    font-family: inherit;
}

/* Intercardinal labels: NE SE SW NW */
.ws40con-compass2__inter {
    font-size: 7px;
    font-weight: 600;
    fill: var(--ws40con-muted);
    font-family: inherit;
}

/* Secondary labels: NNE ENE… (optional) */
.ws40con-compass2__sec {
    font-size: 5.5px;
    font-weight: 400;
    fill: var(--ws40con-muted);
    font-family: inherit;
    opacity: 0.7;
}

/* Wind names outside the ring */
.ws40con-compass2__windname {
    font-size: 7px;
    font-weight: 700;
    fill: var(--ws40con-blue);
    font-family: inherit;
    letter-spacing: 0;
}

.ws40con-compass2__windname--inter {
    font-size: 6px;
    font-weight: 600;
    opacity: 0.85;
}

.ws40con-compass2__needle-n {
    fill: #e0533d;
}

.ws40con-compass2__needle-s {
    fill: #c3c4c7;
}

.ws40con-compass2__hub {
    fill: var(--ws40con-ink);
}

.ws40con-compass2__info {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 4px;
    min-width: 90px;
}

.ws40con-compass2__dir {
    font-size: calc(28px * var(--ws40con-fs, 1));
    font-weight: 800;
    color: var(--ws40con-ink);
    line-height: 1;
}

.ws40con-compass2__windlabel {
    font-size: calc(11px * var(--ws40con-fs, 1));
    color: var(--ws40con-blue);
    font-weight: 600;
    margin-top: -2px;
}

.ws40con-compass2__spd {
    font-size: calc(15px * var(--ws40con-fs, 1));
    color: var(--ws40con-ink);
    font-weight: 700;
    margin-top: 4px;
}

.ws40con-compass2__gust {
    font-size: calc(12px * var(--ws40con-fs, 1));
    color: var(--ws40con-muted);
}

/* ── Beaufort ────────────────────────────────────────────────────────── */

.ws40con-bft {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 8px;
    padding: 6px 0;
}

.ws40con-bft__icon {
    line-height: 0;
}

.ws40con-bft__main {
    display: flex;
    align-items: baseline;
    gap: 6px;
}

.ws40con-bft__num {
    font-size: calc(44px * var(--ws40con-fs, 1));
    font-weight: 800;
    line-height: 1;
    color: var(--ws40con-ink);
}

.ws40con-bft__unit {
    font-size: calc(16px * var(--ws40con-fs, 1));
    font-weight: 600;
    color: var(--ws40con-muted);
}

.ws40con-bft__label {
    font-size: calc(15px * var(--ws40con-fs, 1));
    font-weight: 600;
    color: var(--ws40con-blue);
}

.ws40con-bft__spd {
    font-size: calc(15px * var(--ws40con-fs, 1));
    font-weight: 700;
    color: var(--ws40con-ink);
    margin-top: 2px;
}

.ws40con-bft__gust {
    font-size: calc(12px * var(--ws40con-fs, 1));
    font-weight: 600;
    color: var(--ws40con-muted);
}

.ws40con-bft__range {
    font-size: calc(12px * var(--ws40con-fs, 1));
    font-weight: 600;
    color: var(--ws40con-muted);
    margin-top: 2px;
}

.ws40con-bft__effect {
    font-size: calc(12px * var(--ws40con-fs, 1));
    font-style: italic;
    color: var(--ws40con-muted);
    text-align: center;
    max-width: 220px;
    line-height: 1.35;
    margin-top: 2px;
}

/* Severity colour of the Beaufort number (opt-in via show_color). */
.ws40con-bft--color[data-bft-force="0"]  .ws40con-bft__num { color: #7FB3E0; }
.ws40con-bft--color[data-bft-force="1"]  .ws40con-bft__num { color: #5BA84F; }
.ws40con-bft--color[data-bft-force="2"]  .ws40con-bft__num { color: #5FB84F; }
.ws40con-bft--color[data-bft-force="3"]  .ws40con-bft__num { color: #8DB52A; }
.ws40con-bft--color[data-bft-force="4"]  .ws40con-bft__num { color: #B6BB22; }
.ws40con-bft--color[data-bft-force="5"]  .ws40con-bft__num { color: #D9BE1F; }
.ws40con-bft--color[data-bft-force="6"]  .ws40con-bft__num { color: #F5B731; }
.ws40con-bft--color[data-bft-force="7"]  .ws40con-bft__num { color: #F59331; }
.ws40con-bft--color[data-bft-force="8"]  .ws40con-bft__num { color: #F06B2A; }
.ws40con-bft--color[data-bft-force="9"]  .ws40con-bft__num { color: #E8492A; }
.ws40con-bft--color[data-bft-force="10"] .ws40con-bft__num { color: #D6322A; }
.ws40con-bft--color[data-bft-force="11"] .ws40con-bft__num { color: #B81E2A; }
.ws40con-bft--color[data-bft-force="12"] .ws40con-bft__num { color: #8B1424; }

.ws40con-bft__bar {
    display: flex;
    gap: 3px;
    width: 100%;
    max-width: 280px;
    margin-top: 4px;
}

.ws40con-bft__seg {
    flex: 1;
    height: 12px;
    border-radius: 3px;
    background: var(--ws40con-border);
    transition: background-color .2s ease;
}

/* Color ramp for active segments: green → yellow → orange → red */
.ws40con-bft__seg--0.is-on  { background: #7FB3E0; }
.ws40con-bft__seg--1.is-on  { background: #6FC36F; }
.ws40con-bft__seg--2.is-on  { background: #5FB84F; }
.ws40con-bft__seg--3.is-on  { background: #9FCB3A; }
.ws40con-bft__seg--4.is-on  { background: #CFD52E; }
.ws40con-bft__seg--5.is-on  { background: #F0D52A; }
.ws40con-bft__seg--6.is-on  { background: #F5B731; }
.ws40con-bft__seg--7.is-on  { background: #F59331; }
.ws40con-bft__seg--8.is-on  { background: #F06B2A; }
.ws40con-bft__seg--9.is-on  { background: #E8492A; }
.ws40con-bft__seg--10.is-on { background: #D6322A; }
.ws40con-bft__seg--11.is-on { background: #B81E2A; }
.ws40con-bft__seg--12.is-on { background: #8B1424; }

.ws40con-bft__scale {
    display: flex;
    justify-content: space-between;
    width: 100%;
    max-width: 280px;
    font-size: calc(10px * var(--ws40con-fs, 1));
    font-family: var(--ws40con-mono, monospace);
    color: var(--ws40con-muted);
    margin-top: 2px;
}



/* ── Sun / Stats ─────────────────────────────────────────────────────── */

.ws40con-sun__list {
    margin: 0;
}

.ws40con-sun__row,
.ws40con-stat__row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 6px;
    padding: 4px 0;
    border-bottom: 1px dashed var(--ws40con-border);
    font-size: calc(13px * var(--ws40con-fs, 1));
    min-width: 0;
}

/* Icon slot — fixed width, keeps alignment consistent */
.ws40con-sun__icon,
.ws40con-stat__icon {
    flex: 0 0 30px;
    width: 30px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.ws40con-sun__icon--empty,
.ws40con-stat__icon--empty {
    display: none;
}

.ws40con-icon {
    display: block;
    flex-shrink: 0;
}

/* Label — grows, left-aligned, wraps if needed */
.ws40con-sun__row dt,
.ws40con-sun__label,
.ws40con-stat__label {
    flex: 1 1 auto;
    color: var(--ws40con-muted);
    font-size: var(--ws40con-label-size, 13px);
    min-width: 0;
    overflow-wrap: anywhere;
    word-break: break-word;
    hyphens: auto;
    line-height: 1.25;
}

/* Value — right-aligned, no wrap */
.ws40con-sun__row dd,
.ws40con-sun__value,
.ws40con-stat__value {
    flex: 0 0 auto;
    margin: 0;
    font-weight: 700;
    color: var(--ws40con-ink);
    text-align: right;
    white-space: nowrap;
    font-size: var(--ws40con-value-size, 13px);
}

/* Time-of-extreme inline */
.ws40con-stat__time {
    color: var(--ws40con-muted);
    font-weight: 400;
    font-size: calc(11px * var(--ws40con-fs, 1));
    margin-left: 4px;
}

/* ── Valori estremi: layout grid / strip / chips / table ─────────────── */

/* GRID — responsive cards */
.ws40con-stat__grid {
    display: grid;
    grid-template-columns: repeat(var(--ws40con-stat-cols, 3), minmax(0, 1fr));
    gap: 8px;
}
.ws40con-stat__card,
.ws40con-stat__cell {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 2px;
}
.ws40con-stat__card {
    padding: 10px 6px;
    background: var(--ws40con-card-bg, rgba(0, 0, 0, 0.03));
    border-radius: var(--ws40con-radius, 8px);
}
.ws40con-stat__card .ws40con-stat__icon,
.ws40con-stat__cell .ws40con-stat__icon {
    flex: 0 0 auto;
    width: auto;
}
.ws40con-stat__card .ws40con-stat__value,
.ws40con-stat__cell .ws40con-stat__value {
    text-align: center;
    white-space: nowrap;
}
.ws40con-stat__card .ws40con-stat__value { font-size: var(--ws40con-value-size, 18px); }
.ws40con-stat__cell .ws40con-stat__value { font-size: var(--ws40con-value-size, 16px); }
.ws40con-stat__card .ws40con-stat__label,
.ws40con-stat__cell .ws40con-stat__label {
    flex: 0 0 auto;
    text-align: center;
}
.ws40con-stat__card .ws40con-stat__time,
.ws40con-stat__cell .ws40con-stat__time { margin: 0; }

/* STRIP — single horizontal band that scrolls, with a custom scrollbar */
.ws40con-stat__striphld {
    position: relative;
    min-width: 0;
    width: 100%;
    max-width: 100%;
}
.ws40con-stat__strip {
    display: flex;
    overflow-x: auto;
    width: 100%;
    max-width: 100%;
    min-width: 0;
    padding-bottom: 8px;
    -webkit-overflow-scrolling: touch;
    scroll-behavior: smooth;
    /* Native browser scrollbar, styled like the Forecast / Dust / Air-quality
       blocks — one consistent bar across the Consolle, and no JS timing to get
       wrong (the old custom thumb mis-measured on early load / resize / stretch). */
    scrollbar-width: thin;
    scrollbar-color: var(--ws40con-blue, #1D9E75) #e0e0e0;
}
.ws40con-stat__strip::-webkit-scrollbar { height: 6px; }
.ws40con-stat__strip::-webkit-scrollbar-track { background: #e0e0e0; border-radius: 3px; }
.ws40con-stat__strip::-webkit-scrollbar-thumb { background: var(--ws40con-blue, #1D9E75); border-radius: 3px; }
.ws40con-stat__strip::-webkit-scrollbar-button { display: none; }
.ws40con-stat__cell {
    flex: 1 1 0;
    min-width: 96px;
    padding: 8px 10px;
}
.ws40con-stat__cell + .ws40con-stat__cell {
    border-left: 1px solid var(--ws40con-border);
}

/* INLINE — chips that wrap */
.ws40con-stat__chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}
.ws40con-stat__chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 10px;
    background: var(--ws40con-card-bg, rgba(0, 0, 0, 0.03));
    border-radius: 999px;
    font-size: calc(13px * var(--ws40con-fs, 1));
}
.ws40con-stat__chip .ws40con-stat__icon { flex: 0 0 auto; width: auto; }
.ws40con-stat__chip .ws40con-stat__label { flex: 0 0 auto; }
.ws40con-stat__chip .ws40con-stat__value { white-space: nowrap; }
.ws40con-stat__chip .ws40con-stat__time { margin-left: 0; }

/* TABLE */
.ws40con-stat__table {
    width: 100%;
    border-collapse: collapse;
    font-size: calc(13px * var(--ws40con-fs, 1));
}
.ws40con-stat__table td {
    padding: 5px 8px;
    border-bottom: 1px dashed var(--ws40con-border);
}
.ws40con-stat__table tr:last-child td { border-bottom: none; }
.ws40con-stat__td-icon { width: 30px; }
.ws40con-stat__td-icon .ws40con-icon { display: block; }
.ws40con-stat__td-label { color: var(--ws40con-muted); font-size: var(--ws40con-label-size, 13px); }
.ws40con-stat__td-value {
    font-weight: 700;
    color: var(--ws40con-ink);
    text-align: right;
    white-space: nowrap;
    font-size: var(--ws40con-value-size, 13px);
}
.ws40con-stat__td-time { color: var(--ws40con-muted); font-size: calc(11px * var(--ws40con-fs, 1)); text-align: right; white-space: nowrap; }

/* ── Webcam ──────────────────────────────────────────────────────────── */

.ws40con-webcam .ws40con-block__body {
    padding: 0;
}

.ws40con-webcam__figure {
    position: relative;
    margin: 0;
}

.ws40con-webcam__img {
    display: block;
    width: 100%;
    height: auto;
    min-height: 120px;
    background: #0c1622;
}

/* LIVE badge nell'intestazione blu */
.ws40con-webcam__live {
    background: #d23b3b;
    color: #fff;
    font-size: calc(10px * var(--ws40con-fs, 1));
    font-weight: 700;
    letter-spacing: 0.06em;
    border-radius: 4px;
    padding: 2px 7px;
    text-transform: uppercase;
}

/* Timestamp nell'intestazione blu */
.ws40con-webcam__time {
    color: rgba(255,255,255,0.85);
    font-size: calc(12px * var(--ws40con-fs, 1));
    font-weight: 500;
    letter-spacing: 0.01em;
    white-space: nowrap;
}

/* ── Map ─────────────────────────────────────────────────────────────── */

.ws40con-map .ws40con-block__body {
    padding: 0;
}

.ws40con-map__frame {
    position: relative;
    padding-top: 62%;
}

.ws40con-map__iframe {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
}

/* ── Responsive: base rules (breakpoints via inline <style> from template settings) ── */

/* Cards: auto-wrap naturally on narrow containers */
.ws40con-cards__grid {
    grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
}

/* Full data: masonry — groups packed into balanced columns (auto count by width) */
.ws40con-full__grid {
    columns: 200px;
    column-gap: 24px;
}

/* Gauge: auto-wrap naturally */
.ws40con-gauges__list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
    gap: var(--ws40con-gap);
}

/* ── Air quality block ───────────────────────────────────────────────── */

.ws40con-aq {
    display: flex;
    flex-direction: column;
    gap: 6px;
    text-align: center;
}

/*
 * Card PM — struttura:
 *
 *  ┌──────────────────────────────┐
 *  │  [icona 48px]   PM1          │  ← riga 1: 2 colonne
 *  │                 2,1 µg/m³    │
 *  ├──────────────────────────────┤
 *  │  Media 5,6 µg/m³  Max 16,2 µg/m³ 00:20  │  ← riga 2: span 2 col
 *  └──────────────────────────────┘
 */
.ws40con-aq__card {
    display: flex;
    flex-direction: column;
    gap: 0;
    padding: 12px 16px;
    border: 1px solid var(--ws40con-border);
    border-radius: 10px;
    background: var(--ws40con-card-bg);
    text-align: center;
}

/* Riga superiore: icona affiancata al testo */
.ws40con-aq__top {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: center;
    gap: 12px;
}

/* Col 1 riga 1 — icona, stessa riga del testo */
.ws40con-aq__icon-wrap {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.ws40con-aq__icon-wrap img,
.ws40con-aq__icon-wrap svg {
    width: 48px !important;
    height: 48px !important;
    display: block;
}

/* Col 2 riga 1 — label + valore, stessa riga dell'icona */
.ws40con-aq__info {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0;
}

.ws40con-aq__label {
    font-size: calc(11px * var(--ws40con-fs, 1));
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--ws40con-muted);
    overflow-wrap: anywhere;
    word-break: break-word;
    hyphens: auto;
}

.ws40con-aq__value {
    font-size: calc(28px * var(--ws40con-fs, 1));
    font-weight: 800;
    color: var(--ws40con-ink);
    line-height: 1.1;
}

.ws40con-aq__unit {
    font-size: calc(12px * var(--ws40con-fs, 1));
    font-weight: 400;
    color: var(--ws40con-muted);
}

/* Riga 2: stats centrate sotto icona+valore */
.ws40con-aq__stats {
    display: flex;
    flex-direction: row;
    justify-content: center;
    gap: 14px;
    padding-top: 8px;
    margin-top: 8px;
    border-top: 1px dashed var(--ws40con-border);
    width: 100%;
}

.ws40con-aq__stat {
    font-size: calc(11px * var(--ws40con-fs, 1));
    color: var(--ws40con-muted);
    white-space: nowrap;
}

.ws40con-aq__stat strong {
    color: var(--ws40con-ink);
    font-weight: 700;
}

/* AQI row: centrata */
.ws40con-aq__aqi-row {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 10px 14px;
    border: 1px solid var(--ws40con-border);
    border-radius: 10px;
    background: var(--ws40con-card-bg);
}

.ws40con-aq__aqi-badge {
    display: inline-block;
    font-size: calc(13px * var(--ws40con-fs, 1));
    font-weight: 700;
    padding: 3px 12px;
    border-radius: 20px;
}

.ws40con-aq__aqi--good           { background: #d4edda; color: #155724; }
.ws40con-aq__aqi--fair           { background: #d1ecf1; color: #0c5460; }
.ws40con-aq__aqi--moderate       { background: #fff3cd; color: #856404; }
.ws40con-aq__aqi--poor           { background: #fde8d8; color: #7d3000; }
.ws40con-aq__aqi--very-poor      { background: #f8d7da; color: #721c24; }
.ws40con-aq__aqi--extremely-poor { background: #6b0000; color: #fff; }



/* ── Alerts block ────────────────────────────────────────────────────── */

/* Remove body padding so the ws40-alerts-widget sits flush */
.ws40con-allarmi .ws40con-block__body {
    padding: 0;
}

/* The widget already has its own internal spacing */
.ws40con-allarmi .ws40-alerts-widget {
    border-radius: 0;
    border: none;
    box-shadow: none;
    font-size: calc(13px * var(--ws40con-fs, 1));
}

/* Tighter header inside Consolle block (title already in block head) */
.ws40con-allarmi .ws40-alerts-header {
    padding: 10px 14px 8px;
    border-bottom: 1px solid var(--ws40con-border);
    background: var(--ws40con-bg);
}

.ws40con-allarmi .ws40-alerts-title {
    font-size: calc(13px * var(--ws40con-fs, 1));
    font-weight: 600;
}

.ws40con-allarmi .ws40-alert-row {
    margin: 0 10px;
    border-radius: var(--ws40con-radius);
    margin-bottom: 8px;
    margin-top: 0;
}

.ws40con-allarmi .ws40-alert-row:first-of-type {
    margin-top: 8px;
}

.ws40con-allarmi .ws40-alerts-footer {
    padding: 8px 14px;
    border-top: 1px solid var(--ws40con-border);
    background: var(--ws40con-bg);
    color: var(--ws40con-muted);
}

/* ── Brand block (firma) ─────────────────────────────────────────────── */

.ws40con__brand {
    margin-top: var(--ws40con-gap);
}

.ws40con__brand--left   { text-align: left; }
.ws40con__brand--center { text-align: center; }
.ws40con__brand--right  { text-align: right; }

.ws40con__brand-card {
    display: inline-flex;
    align-items: center;
    gap: 14px;
    text-align: left;
    padding: 11px 20px 11px 11px;
    border: 1px solid var(--ws40con-border);
    border-radius: 16px;
    background:
        linear-gradient(135deg, rgba(55, 138, 221, 0.07), rgba(99, 153, 34, 0.05)),
        var(--ws40con-card-bg, #fff);
    text-decoration: none;
    box-shadow: 0 1px 2px rgba(16, 42, 67, 0.05);
    transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
}
.ws40con__brand-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 10px 24px rgba(16, 42, 67, 0.13);
    border-color: rgba(55, 138, 221, 0.45);
    text-decoration: none;
}

.ws40con__brand-logo {
    width: 56px;
    height: 56px;
    flex: 0 0 auto;
    display: block;
    border-radius: 50%;
    box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.95), 0 3px 10px rgba(16, 42, 67, 0.22);
}

.ws40con__brand-text {
    display: flex;
    flex-direction: column;
    line-height: 1.08;
}
.ws40con__brand-name {
    font-size: calc(23px * var(--ws40con-fs, 1));
    font-weight: 800;
    letter-spacing: 0.01em;
    background: linear-gradient(180deg, #5aa6ee, #155fa6);
    -webkit-background-clip: text;
    background-clip: text;
    color: #155fa6;
    -webkit-text-fill-color: transparent;
}
.ws40con__brand-sub {
    font-size: calc(10.5px * var(--ws40con-fs, 1));
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.16em;
    color: var(--ws40con-muted);
    margin-top: 3px;
}
.ws40con__brand-url {
    font-size: calc(11px * var(--ws40con-fs, 1));
    font-weight: 700;
    color: var(--ws40con-blue);
    margin-top: 7px;
    opacity: 0.8;
    transition: opacity 0.18s ease;
}
.ws40con__brand-card:hover .ws40con__brand-url { opacity: 1; }
.ws40con__brand-arrow { font-weight: 400; }

/* Size variants */
.ws40con__brand--small  .ws40con__brand-card { padding: 9px 16px 9px 9px; gap: 11px; }
.ws40con__brand--small  .ws40con__brand-logo { width: 44px; height: 44px; }
.ws40con__brand--small  .ws40con__brand-name { font-size: calc(19px * var(--ws40con-fs, 1)); }
.ws40con__brand--large  .ws40con__brand-card { padding: 13px 24px 13px 13px; gap: 18px; }
.ws40con__brand--large  .ws40con__brand-logo { width: 72px; height: 72px; }
.ws40con__brand--large  .ws40con__brand-name { font-size: calc(30px * var(--ws40con-fs, 1)); }

/* Style tag inside .ws40con must not participate in layout */
.ws40con-style {
    display: none;
}

/* ── Status block ────────────────────────────────────────────────────── */

.ws40con-status {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    padding: 8px 4px 4px;
    text-align: center;
}

.ws40con-status__row {
    display: grid;
    grid-template-columns: 56px minmax(0, max-content);
    align-items: center;
    justify-content: center;
    gap: 12px;
}

/* Riga 1: immagine stazione + pill ONLINE/OFFLINE */
.ws40con-status__row--top {
    align-items: center;
}

.ws40con-status__station-img,
.ws40con-status__refresh-img {
    display: flex;
    align-items: center;
    justify-content: center;
}
.ws40con-status__station-img img {
    width: 52px;
    height: 52px;
    object-fit: contain;
    display: block;
}

.ws40con-status__right {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
}

/* Riga 2: icona refresh + timestamp/elapsed */
.ws40con-status__row--update {
    align-items: center;
    gap: 12px;
}

.ws40con-status__refresh-img img {
    width: 44px;
    height: 44px;
    object-fit: contain;
    display: block;
}

.ws40con-status__update-info {
    display: flex;
    flex-direction: column;
    gap: 2px;
    text-align: left;
}

/* Pill */
.ws40con-status__pill {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 4px 14px;
    border-radius: 999px;
    font-size: calc(13px * var(--ws40con-fs, 1));
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    width: fit-content;
}

.ws40con-status__pill--online  { background: #d1fae5; color: #065f46; }
.ws40con-status__pill--offline { background: #fee2e2; color: #991b1b; }
.ws40con-status__pill--unknown { background: #f3f4f6; color: #6b7280; }

.ws40con-status__dot {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    flex-shrink: 0;
}

.ws40con-status__pill--online .ws40con-status__dot {
    background: #10b981;
    box-shadow: 0 0 0 3px rgba(16,185,129,.25);
    animation: ws40-pulse 2s infinite;
}

.ws40con-status__pill--offline .ws40con-status__dot {
    background: #ef4444;
}

@keyframes ws40-pulse {
    0%,100% { box-shadow: 0 0 0 3px rgba(16,185,129,.25); }
    50%      { box-shadow: 0 0 0 6px rgba(16,185,129,.10); }
}

.ws40con-status__ts {
    font-size: calc(13px * var(--ws40con-fs, 1));
    font-weight: 600;
    color: var(--ws40con-ink);
}

.ws40con-status__elapsed {
    font-size: calc(12px * var(--ws40con-fs, 1));
    color: var(--ws40con-muted);
}

.ws40con-status__source {
    font-size: calc(13px * var(--ws40con-fs, 1));
    font-weight: 700;
    color: var(--ws40con-blue);
}

.ws40con-status__outages-wrap {
    width: 100%;
    border: 1px solid var(--ws40con-border);
    border-radius: 8px;
    overflow: hidden;
    margin-top: 2px;
    font-size: calc(12px * var(--ws40con-fs, 1));
}

.ws40con-status__outages-hd {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 7px 10px;
    background: rgba(15, 28, 46, 0.05);
    border: none;
    cursor: pointer;
    text-align: left;
    font-size: calc(12px * var(--ws40con-fs, 1));
    font-family: inherit;
    transition: background 0.12s;
}

.ws40con-status__outages-hd:hover {
    background: rgba(15, 28, 46, 0.09);
}

.ws40con-status__badge {
    padding: 2px 8px;
    border-radius: 999px;
    font-weight: 600;
    font-size: calc(11px * var(--ws40con-fs, 1));
}

.ws40con-status__badge--ok   { background: #d1fae5; color: #065f46; }
.ws40con-status__badge--warn { background: #fef9c3; color: #92400e; }

.ws40con-status__toggle-lbl {
    flex: 1;
    color: var(--ws40con-blue);
    font-size: calc(11px * var(--ws40con-fs, 1));
}

.ws40con-status__toggle-arr {
    font-size: calc(11px * var(--ws40con-fs, 1));
    color: var(--ws40con-muted);
    transition: transform 0.15s;
}

.ws40con-status__outages-wrap.is-open .ws40con-status__toggle-arr {
    transform: rotate(90deg);
}

.ws40con-status__outages-body {
    display: none;
    padding: 6px 10px 8px;
    border-top: 1px solid var(--ws40con-border);
    background: #fff;
}

.ws40con-status__outages-wrap.is-open .ws40con-status__outages-body {
    display: block;
}

.ws40con-status__outage-row {
    display: flex;
    justify-content: space-between;
    padding: 3px 0;
    border-bottom: 1px dashed var(--ws40con-border);
    font-size: calc(11px * var(--ws40con-fs, 1));
}

.ws40con-status__outage-row:last-child { border-bottom: none; }

.ws40con-status__outage-when { color: var(--ws40con-ink); }
.ws40con-status__outage-dur  { color: var(--ws40con-muted); font-weight: 600; }

.ws40con-status__outage-empty {
    font-size: calc(11px * var(--ws40con-fs, 1));
    color: var(--ws40con-muted);
    padding: 2px 0;
}

/* ── Air quality: stats + footer ─────────────────────────────────────── */

.ws40con-aq__stats {
    display: flex;
    flex-direction: column;
    gap: 2px;
    margin-top: 4px;
    padding-top: 4px;
    border-top: 1px dashed var(--ws40con-border);
    width: 100%;
}

.ws40con-aq__stat {
    font-size: calc(11px * var(--ws40con-fs, 1));
    color: var(--ws40con-muted);
    white-space: nowrap;
}

.ws40con-aq__stat strong {
    color: var(--ws40con-ink);
    font-weight: 600;
}

.ws40con-aq__footer {
    text-align: center;
    margin-top: 4px;
    padding-top: 4px;
}

.ws40con-aq__ts {
    font-size: calc(10px * var(--ws40con-fs, 1));
    color: var(--ws40con-muted);
    opacity: 0.75;
}

/* ── Webcam tabs ─────────────────────────────────────────────────── */

.ws40con-webcam__tabs {
    display: flex;
    gap: 0;
    border-bottom: 2px solid #dcdcde;
    margin-bottom: 12px;
}

.ws40con-webcam__tab {
    padding: 10px 16px;
    background: transparent;
    border: none;
    font-size: calc(13px * var(--ws40con-fs, 1));
    font-weight: 500;
    color: #666;
    cursor: pointer;
    border-bottom: 2px solid transparent;
    margin-bottom: -2px;
    transition: all 0.2s ease;
}

.ws40con-webcam__tab:hover {
    color: #333;
    background: #f9f9f9;
}

.ws40con-webcam__tab.active {
    color: #1f6fd6;
    border-bottom-color: #1f6fd6;
}

.ws40con-webcam__panel {
    display: none;
}

.ws40con-webcam__panel.active {
    display: block;
}

/* ── Classic Editor block ────────────────────────────────────────── */

.ws40con-custom-editor {
    font-size: calc(14px * var(--ws40con-fs, 1));
    line-height: 1.6;
    color: var(--ws40con-ink);
}

.ws40con-custom-editor p {
    margin: 0 0 0.8em;
}

.ws40con-custom-editor p:last-child {
    margin-bottom: 0;
}

.ws40con-custom-editor a {
    color: var(--ws40con-blue);
    text-decoration: underline;
}

.ws40con-custom-editor ul,
.ws40con-custom-editor ol {
    margin: 0 0 0.8em 1.5em;
}

.ws40con-custom-editor blockquote {
    border-left: 3px solid var(--ws40con-blue);
    margin: 0 0 0.8em;
    padding: 0.5em 1em;
    color: var(--ws40con-muted);
}

/* ── Live block (Meteobridge push) — matches Full-data styling ──────────── */
.ws40con-live__list {
    columns: 220px;
    column-gap: 24px;
    margin: 0;
    padding: 0;
}
.ws40con-live__row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 6px;
    border-bottom: 1px dashed var(--ws40con-border);
    padding: 4px 0;
    font-size: calc(13px * var(--ws40con-fs, 1));
    break-inside: avoid;
    -webkit-column-break-inside: avoid;
}
.ws40con-live__icon {
    flex: 0 0 30px;
    width: 30px;
    display: flex;
    align-items: center;
    justify-content: center;
}
.ws40con-live__label {
    color: var(--ws40con-muted);
    font-size: var(--ws40con-label-size, inherit);
    flex: 1 1 auto;
    min-width: 0;
    overflow-wrap: anywhere;
    word-break: break-word;
    hyphens: auto;
    line-height: 1.25;
}
.ws40con-live__val {
    font-weight: 700;
    font-size: var(--ws40con-value-size, inherit);
    color: var(--ws40con-ink);
    white-space: nowrap;
    text-align: right;
    flex: 0 0 auto;
}
.ws40con-live__num {
    font-variant-numeric: tabular-nums;
}
.ws40con-live__unit {
    font-weight: 400;
    color: var(--ws40con-muted);
    font-size: .82em;
    margin-left: 3px;
}

/* Single "● LIVE" indicator with a pulsing dot when active */
.ws40con-live__badge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 2px 9px;
    border-radius: 10px;
    font-size: calc(10px * var(--ws40con-fs, 1));
    font-weight: 700;
    letter-spacing: .08em;
    color: var(--ws40con-blue, #1f6fd6);
    background: rgba(255, 255, 255, .55);
}
.ws40con-live__dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: #9aa4b2;
}
.ws40con-live__badge.is-active {
    color: var(--ws40con-blue, #1f6fd6);
    background: rgba(255, 255, 255, .94);
}
.ws40con-live__badge.is-active .ws40con-live__dot {
    background: #2ea043;
    animation: ws40conLivePulse 1.4s ease-in-out infinite;
}
@keyframes ws40conLivePulse {
    0%   { box-shadow: 0 0 0 0 rgba(46,160,67,.55); }
    70%  { box-shadow: 0 0 0 6px rgba(46,160,67,0); }
    100% { box-shadow: 0 0 0 0 rgba(46,160,67,0); }
}
@media (max-width: 600px) {
    .ws40con-live__list { columns: 1; }
}
@media (prefers-reduced-motion: reduce) {
    .ws40con-live__badge.is-active .ws40con-live__dot { animation: none; }
}

/* Live card identity: subtle green accent strip (theme-safe, no bg override) */
.ws40con-block.ws40con-live {
    position: relative;
    box-shadow: inset 3px 0 0 0 #2ea043;
}

/* Fill the vertical void when the live block is stretched to a taller neighbour
   (e.g. Aviation Wind alongside it in a horizontal zone): let the body grow and
   centre the metrics list vertically. When the block is NOT stretched (used
   alone or stacked) there is no extra height, so this is a no-op — no regression.
   Scoped to the live block only; works for any admin row count / icons / text
   scale. The multi-column list keeps its natural height, so the columns stay
   balanced and fill the full width. */
.ws40con-block.ws40con-live .ws40con-block__body {
    display: flex;
    flex-direction: column;
    min-height: 0;
}
.ws40con-block.ws40con-live .ws40con-live__wrap {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    justify-content: center;
}

/* Value flash on change (only inside the live block, via data-ws40-flash) */
@keyframes ws40conLiveFlash {
    0%   { background: rgba(46, 160, 67, .55); color: #1a7f37; transform: scale(1.18); }
    12%  { background: rgba(46, 160, 67, .55); color: #1a7f37; transform: scale(1.18); }
    100% { background: transparent;            color: inherit; transform: scale(1); }
}
.ws40con-live__flash {
    display: inline-block;
    transform-origin: right center;
    animation: ws40conLiveFlash 1.2s ease-out;
    border-radius: 4px;
    padding: 0 4px;
    margin: 0 -4px;
}
@media (prefers-reduced-motion: reduce) {
    .ws40con-live__flash { animation: none; }
}

/* ── Soil & Leaf — per-channel cards (flow grid, no empty space) ─────── */
.ws40con-soilleaf .ws40con-sl-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 10px;
}
.ws40con-soilleaf .ws40con-sl-card {
    border: 1px solid var(--ws40con-border);
    border-radius: 10px;
    padding: 10px 12px;
}
.ws40con-soilleaf .ws40con-sl-card--leaf {
    border-color: #b7e0c8;
    background: rgba(29, 158, 117, 0.06);
}
.ws40con-soilleaf .ws40con-sl-card__title {
    font-size: var(--ws40con-label-size, 12px);
    font-weight: 600;
    color: var(--ws40con-muted);
    margin: 0 0 8px;
}
.ws40con-soilleaf .ws40con-sl-card--leaf .ws40con-sl-card__title { color: #0f6e56; }
.ws40con-soilleaf .ws40con-sl-metric {
    display: flex;
    align-items: center;
    gap: 7px;
    font-variant-numeric: tabular-nums;
}
.ws40con-soilleaf .ws40con-sl-metric + .ws40con-sl-metric { margin-top: 6px; }
.ws40con-soilleaf .ws40con-sl-metric__ic { flex: 0 0 auto; display: inline-flex; }
.ws40con-soilleaf .ws40con-sl-metric__ic .ws40con-icon { width: 20px; height: 20px; display: block; }
.ws40con-soilleaf .ws40con-sl-metric__val {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    flex: 1 1 auto;
    font-weight: 500;
    font-size: var(--ws40con-value-size, 14px);
    /* Use the strong ink colour like the other value blocks (full-data, stats);
       without this the reading inherited a muted grey and looked washed out. The
       unit keeps its own muted style. */
    color: var(--ws40con-ink);
}
.ws40con-soilleaf .ws40con-sl-metric__val .ws40con-sl-pill { margin-left: auto; }

/* Shared value chrome (muted unit + moisture state pills) */
.ws40con-sl-unit { font-weight: 400; color: var(--ws40con-muted); font-size: 0.86em; }
.ws40con-sl-pill { padding: 1px 7px; border-radius: 999px; font-size: calc(11px * var(--ws40con-fs, 1)); font-weight: 600; line-height: 1.5; white-space: nowrap; }
.ws40con-sl-pill--moist   { background: #d1fae5; color: #065f46; }
.ws40con-sl-pill--dry     { background: #fef9c3; color: #92400e; }
.ws40con-sl-pill--verydry { background: #fee2e2; color: #991b1b; }

/* Updated footer */
.ws40con-soilleaf__foot { display: flex; align-items: center; gap: 6px; margin-top: 12px; padding-top: 8px; border-top: 1px solid var(--ws40con-border); font-size: calc(12px * var(--ws40con-fs, 1)); color: var(--ws40con-muted); }
.ws40con-soilleaf__foot-ic { flex: 0 0 auto; }
.ws40con-soilleaf__foot.is-stale { color: #92400e; }

/* ── Aviation wind block (dark cockpit instruments) ─────────────────────── */
.ws40con-av{ width:100%; }
.ws40con-av__svg{ width:100%; height:auto; display:block; }
.ws40con-av__bezel{ fill:#16181c; }
.ws40con-av__ring{ fill:#3b3f47; }
.ws40con-av__face{ fill:#26292e; }
.ws40con-av__card{ fill:#e8e9eb; font:700 12px/1 'DM Mono',ui-monospace,Menlo,Consolas,monospace; }
.ws40con-av__stick{ fill:#c2c7cc; font:400 9px/1 'DM Mono',ui-monospace,Menlo,Consolas,monospace; }
.ws40con-av__lbl{ fill:#8a9096; font:400 8px/1 'DM Mono',ui-monospace,monospace; letter-spacing:.5px; }
.ws40con-av__unit{ fill:#9aa0a6; font:400 10px/1 'DM Mono',ui-monospace,monospace; letter-spacing:1px; }
.ws40con-av__big{ fill:#e8e9eb; font:700 18px/1 'DM Mono',ui-monospace,Menlo,Consolas,monospace; }
.ws40con-av__avg-val{ fill:#7fb0e6; }
.ws40con-av__spd{ fill:#e8e9eb; font:700 26px/1 'DM Mono',ui-monospace,Menlo,Consolas,monospace; }
.ws40con-av__bft{ fill:#9aa0a6; font:700 9px/1 'DM Mono',ui-monospace,monospace; letter-spacing:.5px; }
.ws40con-av__bft[data-bft-force="0"]  { fill:#7FB3E0; }
.ws40con-av__bft[data-bft-force="1"]  { fill:#5BA84F; }
.ws40con-av__bft[data-bft-force="2"]  { fill:#5FB84F; }
.ws40con-av__bft[data-bft-force="3"]  { fill:#8DB52A; }
.ws40con-av__bft[data-bft-force="4"]  { fill:#B6BB22; }
.ws40con-av__bft[data-bft-force="5"]  { fill:#D9BE1F; }
.ws40con-av__bft[data-bft-force="6"]  { fill:#F5B731; }
.ws40con-av__bft[data-bft-force="7"]  { fill:#F59331; }
.ws40con-av__bft[data-bft-force="8"]  { fill:#F06B2A; }
.ws40con-av__bft[data-bft-force="9"]  { fill:#E8492A; }
.ws40con-av__bft[data-bft-force="10"] { fill:#D6322A; }
.ws40con-av__bft[data-bft-force="11"] { fill:#B81E2A; }
.ws40con-av__bft[data-bft-force="12"] { fill:#8B1424; }
.ws40con-av__bft-sep{ fill:#6f757c; }
.ws40con-av__bft-gust{ fill:#e0433d; }
.ws40con-av-legend{ display:flex; gap:18px; justify-content:center; margin:2px 0 0; }
.ws40con-av-legend__item{ display:inline-flex; align-items:center; gap:6px; font-size: calc(11px * var(--ws40con-fs, 1)); color:#8a9099; }
.ws40con-av-legend__swatch{ width:14px; height:3px; border-radius:2px; display:inline-block; }
.ws40con-av-legend__swatch.is-wind{ background:#e8e9eb; }
.ws40con-av-legend__swatch.is-gust{ background:#e0433d; }
.ws40con-av__needle-last{ fill:#e0433d; transition:transform .5s cubic-bezier(.34,1.35,.5,1); }
.ws40con-av__needle-avg{ fill:#2f7fd6; transition:transform .5s cubic-bezier(.34,1.35,.5,1); }
.ws40con-av__needle-spd{ fill:#eceef0; transition:transform .5s cubic-bezier(.34,1.35,.5,1); }
.ws40con-av__gust{ stroke:#e0433d; stroke-width:3; stroke-linecap:round; transition:transform .4s ease; }
.ws40con-av__hub{ fill:#15171a; stroke:#4a4e55; stroke-width:1.5; }
.ws40con-av__hub-dot{ fill:#c9ccd1; }

/* ── Aviation: live/delayed status pill + caption ───────────────────────── */
.ws40con-av-status{ display:inline-flex; align-items:center; gap:6px; font-size: calc(10px * var(--ws40con-fs, 1)); font-weight:700;
  padding:2px 9px; border-radius:10px; font-family:'DM Mono',ui-monospace,Menlo,Consolas,monospace; letter-spacing:.08em; text-transform:uppercase;
  background:rgba(255,255,255,.94); }
.ws40con-av-status__dot{ width:7px; height:7px; border-radius:50%; flex:0 0 auto; }
.ws40con-av-status.is-live{ color:var(--ws40con-blue, #1f6fd6); }
.ws40con-av-status.is-live .ws40con-av-status__dot{ background:#2ea043; animation:ws40con-av-pulse 3s ease-out infinite; }
.ws40con-av-status.is-delayed{ color:#9a6a08; }
.ws40con-av-status.is-delayed .ws40con-av-status__dot{ background:#e0aa2a; }
@keyframes ws40con-av-pulse{ 0%{ box-shadow:0 0 0 0 rgba(47,191,106,.55); } 70%{ box-shadow:0 0 0 6px rgba(47,191,106,0); } 100%{ box-shadow:0 0 0 0 rgba(47,191,106,0); } }
/* ── Aviation wind: light variant ────────────────────────────────────────
   Same drawing, inverted tones, for templates where a black instrument sits
   badly on a pale page. Only the structural colours are redefined; the
   Beaufort scale (.ws40con-av__bft-*) keeps its palette in both variants,
   because those colours encode wind force and must read the same either way.
   The two coloured needles are DARKENED rather than inverted: the blue was
   chosen to glow on black (#2f7fd6 over #26292e) and would wash out on white,
   and the red needed more depth to separate from a pale face. The speed needle
   was near-white and simply flips to near-black. */
.ws40con-av--light .ws40con-av__bezel{ fill:#c9ced6; }
.ws40con-av--light .ws40con-av__ring{ fill:#dde1e7; }
.ws40con-av--light .ws40con-av__face{ fill:#f7f8fa; }
.ws40con-av--light .ws40con-av__card{ fill:#1f2530; }
.ws40con-av--light .ws40con-av__stick{ fill:#3c434c; }
.ws40con-av--light .ws40con-av__lbl{ fill:#6b7280; }
.ws40con-av--light .ws40con-av__unit{ fill:#6b7280; }
.ws40con-av--light .ws40con-av__big{ fill:#1f2530; }
.ws40con-av--light .ws40con-av__spd{ fill:#1f2530; }
.ws40con-av--light .ws40con-av__avg-val{ fill:#1a5aa8; }
.ws40con-av--light .ws40con-av__needle-avg{ fill:#1a5aa8; }
.ws40con-av--light .ws40con-av__needle-last{ fill:#b3271f; }
.ws40con-av--light .ws40con-av__needle-spd{ fill:#2a2f38; }
.ws40con-av--light .ws40con-av__gust{ stroke:#b3271f; }
/* The hub stays dark with a pale centre: inverting it would erase the pivot. */
.ws40con-av--light .ws40con-av__hub{ fill:#2a2f38; stroke:#8c939c; }
.ws40con-av--light .ws40con-av__hub-dot{ fill:#f7f8fa; }
.ws40con-av--light .ws40con-av-legend__swatch.is-wind{ background:#2a2f38; }
.ws40con-av--light .ws40con-av-legend__swatch.is-gust{ background:#b3271f; }

/* Central readout and scale figures over the sweeping needles. The text is
   already painted after the needles, so the layer order is right, but with no
   separation the needle shows through the gaps between digits and appears to
   cut them. paint-order draws a stroke in the FACE colour beneath the glyphs,
   carving a thin halo. The stroke is scaled to the type size: 3px under a 26px
   readout reads as a clean edge, the same 3px under an 8px label would fatten
   it. The stroke colour follows the variant. */
.ws40con-av__big, .ws40con-av__avg-val {
    paint-order: stroke fill;
    stroke: #26292e;
    stroke-width: 3px;
    stroke-linejoin: round;
}
.ws40con-av__lbl, .ws40con-av__stick, .ws40con-av__unit {
    paint-order: stroke fill;
    stroke: #26292e;
    stroke-width: 1.8px;
    stroke-linejoin: round;
}
.ws40con-av--light .ws40con-av__big,
.ws40con-av--light .ws40con-av__avg-val,
.ws40con-av--light .ws40con-av__lbl,
.ws40con-av--light .ws40con-av__stick,
.ws40con-av--light .ws40con-av__unit {
    stroke: #f7f8fa;
}

.ws40con-av-cap{ margin:8px 2px 0; font-size: calc(12px * var(--ws40con-fs, 1)); line-height:1.5; color:#8b93a1; }
.ws40con-cfg-linkrow{ margin:2px 0 8px; }
.ws40con-cfg-link{ font-size: calc(12px * var(--ws40con-fs, 1)); text-decoration:none; }

/* ── Rainfall block (liquid-fill gauges + expandable panel) ──────────────────
   Themed on the Consolle tokens (--ws40con-blue/ink/muted/card-bg/border) so it
   inherits the site's Consolle appearance. Water/ring derive from --ws40con-blue
   via color-mix (with a plain-colour fallback for older engines). Behaviour
   (fill level + wave motion + MORE/HIDE) lives in ws40-consolle.js. */
.ws40con-rain .ws40con-block__body { padding-top: 8px; }
.ws40con-rain__wrap { display: flex; flex-direction: column; align-items: center; }
.ws40con-rain__cloud { color: var(--ws40con-blue); line-height: 0; margin: 2px 0 6px; }

.ws40con-rain__gauges { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; width: 100%; }
.ws40con-rain__gauge { width: 130px; text-align: center; }
.ws40con-rain__svg { width: 118px; height: 118px; display: block; margin: 0 auto; }

.ws40con-rain__ring { fill: none; stroke: #8fc0ee; }
.ws40con-rain__wave--a { fill: #1f6fd6; }
.ws40con-rain__wave--b { fill: #7fb6ee; }
.ws40con-rain__water { transform-box: fill-box; transition: transform 1.15s cubic-bezier(.22, .61, .36, 1); }
.ws40con-rain__wave { transform-box: fill-box; }
@media (prefers-reduced-motion: no-preference) {
    .ws40con-rain__wave--a { animation: ws40con-rain-wa 3.3s linear infinite; }
    .ws40con-rain__wave--b { animation: ws40con-rain-wb 4.7s linear infinite; }
}
@keyframes ws40con-rain-wa { from { transform: translateX(0); }    to { transform: translateX(-46px); } }
@keyframes ws40con-rain-wb { from { transform: translateX(-23px); } to { transform: translateX(23px); } }

.ws40con-rain__pct { fill: #0f1c2e; font-size: calc(19px * var(--ws40con-fs, 1)); font-weight: 600; }
.ws40con-rain__gauge.is-filled .ws40con-rain__pct { fill: #fff; }
/* Themed accent only where var() + color-mix() are reliable (skips older iOS
   Safari without color-mix, which would otherwise fall back to a black fill). */
@supports (fill: color-mix(in srgb, red, blue)) {
    .ws40con-rain__wave--a { fill: var(--ws40con-blue, #1f6fd6); }
    .ws40con-rain__wave--b { fill: color-mix(in srgb, var(--ws40con-blue, #1f6fd6) 60%, #fff); }
    .ws40con-rain__ring    { stroke: color-mix(in srgb, var(--ws40con-blue, #1f6fd6) 40%, #fff); }
    .ws40con-rain__pct     { fill: var(--ws40con-ink, #0f1c2e); }
}

.ws40con-rain__glabel { margin-top: 2px; font-size: calc(12px * var(--ws40con-fs, 1)); color: var(--ws40con-muted); text-transform: uppercase; letter-spacing: .03em; }
.ws40con-rain__gmm { font-size: calc(15px * var(--ws40con-fs, 1)); font-weight: 600; color: var(--ws40con-ink); }
.ws40con-rain__gmoy { font-size: calc(11px * var(--ws40con-fs, 1)); color: var(--ws40con-muted); }
/* Second reading (share of the full month/year mean) — one step stronger than the
   to-date line so the two readings are visually distinct. */
.ws40con-rain__gfull { margin-top: 1px; font-size: calc(11px * var(--ws40con-fs, 1)); color: var(--ws40con-blue, #185fa5); font-weight: 600; }

.ws40con-rain__panel { width: 100%; margin-top: 12px; }
.ws40con-rain__panel[hidden] { display: none; }
.ws40con-rain__lastrain { padding: 2px 2px 8px; }
.ws40con-rain__lr-title { font-weight: 600; color: var(--ws40con-ink); }
.ws40con-rain__lr-sub { color: var(--ws40con-muted); font-size: calc(13px * var(--ws40con-fs, 1)); }

.ws40con-rain__rows { display: flex; flex-direction: column; gap: 3px; }
.ws40con-rain__row { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 9px 12px; border-radius: 10px; background: var(--ws40con-card-bg); border: 1px solid var(--ws40con-border); }
.ws40con-rain__row:nth-child(even) { background: #eef4fb; background: color-mix(in srgb, var(--ws40con-blue) 8%, var(--ws40con-card-bg)); }
.ws40con-rain__rlabel { font-weight: 600; }
.ws40con-rain__rright { text-align: right; }
.ws40con-rain__rval { font-size: calc(17px * var(--ws40con-fs, 1)); font-weight: 600; color: var(--ws40con-ink); }
.ws40con-rain__rdetail { font-size: calc(11px * var(--ws40con-fs, 1)); color: var(--ws40con-muted); margin-top: 1px; }

.ws40con-rain__foot { margin-top: 10px; padding-top: 12px; border-top: 1px solid var(--ws40con-border); text-align: center; }
/* "MORE / HIDE" toggle — an outlined accent pill with a rotating caret, so the
   expandable panel is clearly discoverable (users were missing the old flat grey
   text). Coherent with the Consolle blue; the caret is a CSS ::after (survives
   the JS textContent swap) and flips via aria-expanded. */
.ws40con-rain__toggle {
    display: inline-flex;
    align-items: center;
    gap: .55em;
    background: transparent;
    border: 1.5px solid var(--ws40con-blue);
    border-radius: 999px;
    color: var(--ws40con-blue);
    font-size: calc(12px * var(--ws40con-fs, 1));
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    cursor: pointer;
    padding: 7px 18px;
    transition: background .15s ease, color .15s ease, box-shadow .15s ease;
}
.ws40con-rain__toggle::after {
    content: "";
    width: .48em;
    height: .48em;
    border-right: 2px solid currentColor;
    border-bottom: 2px solid currentColor;
    transform: translateY(-.12em) rotate(45deg);
    transition: transform .2s ease;
}
.ws40con-rain__toggle:hover,
.ws40con-rain__toggle:focus-visible {
    background: var(--ws40con-blue);
    color: #fff;
    box-shadow: 0 2px 8px rgba(31, 111, 214, .28);
}
.ws40con-rain__toggle:focus-visible { outline: 2px solid var(--ws40con-blue); outline-offset: 2px; }
.ws40con-rain__toggle[aria-expanded="true"]::after { transform: translateY(.1em) rotate(225deg); }
.ws40con-rain__note { margin: 12px 4px 2px; font-size: calc(11.5px * var(--ws40con-fs, 1)); line-height: 1.45; color: var(--ws40con-muted); font-style: italic; text-align: center; }
