/* =========================================================
   SKY THEMES — dynamic background reactive to weather + time of day
   Layered atop the base shinkai.css. Two themes (cinematic and
   minimal) selectable from the city sheet, persisted in localStorage,
   also forced via ?theme= URL param for preview. (sky101 — painterly
   removed; users who picked it fall back to cinematic.)

   How the cascade composes:
     body[data-theme]  — overall aesthetic vocabulary (palette, density)
     body[data-time-scene]  — dawn / day / golden-hour / night base sky
     body[data-weather-scene]  — clear / cloudy / fog / rain / snow / storm overlay

   Particles render on a fixed full-viewport canvas behind hero/cards,
   never above key info. Cards have their own opaque dark background
   so particles aren't visible through them.
========================================================= */

/* ---------- Canvas + moon DOM positioning ---------- */

#weather-canvas {
  position: fixed;
  inset: 0;
  width: 100vw;
  height: 100vh;
  height: 100dvh;
  z-index: 6;
  pointer-events: none;
  /* Was inside hero (clipped to that rectangle). Ann wanted petals
     across the whole image (Tenki no Ko aesthetic — petals/rain cross
     every frame). Now full-viewport. z:6 sits above main (z:4) so
     particles render OVER cards too, but below alert-banner (z:90) and
     city-sheet (z:100) so neither modal surface is obscured by petals.
     pointer-events:none keeps the canvas tap-transparent. */
}

/* moon shares the .sun's positioning slot — both absolute inside .hero */
.moon {
  position: absolute;
  top: 30%;
  right: 16%;
  /* Larger than before (was 78px) so the real lunar phase's terminator reads
     as a graceful crescent/gibbous instead of a thin sliver that looked like a
     notch at small sizes. The phase itself is drawn by applyMoonPhase() in
     sky-themes.js via the .moon-shadow ellipse — kept ON (real phase). */
  width: 96px;
  height: 96px;
  z-index: 1;
  filter: drop-shadow(0 0 24px rgba(220, 230, 255, 0.45))
          drop-shadow(0 0 60px rgba(180, 200, 250, 0.22));
  /* Visibility: hidden by default, scene-CSS shows at night */
  display: none;
  transition: transform 12s linear;
}
.moon svg { width: 100%; height: 100%; display: block; }

body[data-time-scene="night"] .moon { display: block; }
body[data-time-scene="night"] .sun,
body[data-time-scene="night"] .flare { display: none; }

/* Dawn / golden-hour: sun smaller and warmer. Golden-hour flare goes
   FULL on (opacity in gradient block below) — the warm halo around the
   sun is what makes a Tenki-no-Ko sunset shot land. */
body[data-time-scene="dawn"] .sun { top: 50%; right: 22%; width: 64px; height: 64px; }

/* ============ scene → sky gradient overrides ============
   Variables set per scene so theme files only need to change palette,
   not the structural gradient. */

body[data-time-scene] .sky { background: var(--scene-sky, linear-gradient(
  180deg, var(--sky-1) 0%, var(--sky-2) 36%, var(--sky-3) 74%, var(--sky-4) 100%
)); }

body[data-time-scene="dawn"] {
  --scene-sky: linear-gradient(
    180deg,
    #1a2c5a 0%,
    #5e6db0 30%,
    #e8a47e 65%,
    #ffd9b0 95%
  );
}
body[data-time-scene="day"] {
  --scene-sky: linear-gradient(
    180deg,
    #4a8fc7 0%,
    #87b8de 45%,
    #c8dff0 90%,
    #f0e8d4 100%
  );
}
body[data-time-scene="golden-hour"] {
  /* TRUE golden hour — the whole sky bathes in warm honey/amber light,
     not just a band at the horizon. Plum reduced to a thin sliver at the
     very top; warm earth + amber + gold dominate. (sky102) */
  --scene-sky: linear-gradient(
    180deg,
    #5a3a52 0%,
    #8c4838 15%,
    #c47042 35%,
    #ee9540 58%,
    #ffb858 78%,
    #ffe49a 100%
  );
}
/* Warm radial wash emanating from the sun position — like real golden-hour
   light filling the air, not just a gradient. screen-blend so it brightens
   without flattening the gradient. */
body[data-time-scene="golden-hour"] .hero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: radial-gradient(
    circle at 80% 22%,
    rgba(255, 210, 120, 0.35) 0%,
    rgba(255, 180, 90, 0.18) 33%,
    transparent 72%
  );
  mix-blend-mode: screen;
}
/* Sun gets a more saturated amber-gold center for golden-hour specifically. */
body[data-time-scene="golden-hour"] .sun {
  background: radial-gradient(circle, #fff5d0 0%, #ffc548 42%, rgba(255, 150, 60, 0) 82%);
}
/* Flare goes full ON. */
body[data-time-scene="golden-hour"] .flare {
  opacity: 0.9;
}
body[data-time-scene="night"] {
  --scene-sky: linear-gradient(
    180deg,
    #050717 0%,
    #0a1230 40%,
    #1a1840 75%,
    #2a1d52 100%
  );
}

/* ---------- Weather mood overlays (apply on top of time gradient) ---------- */

body[data-weather-scene="partly-cloudy"] .sky::after,
body[data-weather-scene="cloudy"] .sky::after,
body[data-weather-scene="fog"] .sky::after,
body[data-weather-scene="drizzle"] .sky::after,
body[data-weather-scene="rain-heavy"] .sky::after,
body[data-weather-scene="snow"] .sky::after,
body[data-weather-scene="heavy-snow"] .sky::after,
body[data-weather-scene="storm"] .sky::after,
body[data-weather-scene="thunderstorm"] .sky::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 1;
}

body[data-weather-scene="partly-cloudy"] .sky::after {
  background: linear-gradient(180deg, rgba(60, 60, 80, 0.08), rgba(80, 80, 100, 0.15));
}
body[data-weather-scene="cloudy"] .sky::after {
  background: linear-gradient(180deg, rgba(60, 60, 80, 0.22), rgba(80, 80, 100, 0.38));
}
body[data-weather-scene="drizzle"] .sky::after {
  background: linear-gradient(180deg, rgba(40, 50, 70, 0.32), rgba(30, 40, 60, 0.42));
}
body[data-weather-scene="rain-heavy"] .sky::after {
  background: linear-gradient(180deg, rgba(20, 28, 50, 0.72), rgba(8, 14, 32, 0.82));
}
body[data-weather-scene="snow"] .sky::after {
  background: linear-gradient(180deg, rgba(180, 200, 230, 0.22), rgba(160, 180, 220, 0.32));
}
body[data-weather-scene="storm"] .sky::after {
  background: linear-gradient(180deg, rgba(28, 32, 56, 0.65), rgba(20, 22, 44, 0.78));
}
body[data-weather-scene="thunderstorm"] .sky::after {
  background: linear-gradient(180deg, rgba(14, 16, 36, 0.78), rgba(8, 10, 28, 0.88));
  animation: storm-flicker 14s ease-in-out infinite;
}
body[data-weather-scene="heavy-snow"] .sky::after {
  /* Heavy snow = dimmer sky than light snow; reduced visibility feeling */
  background: linear-gradient(180deg, rgba(160, 168, 180, 0.42), rgba(140, 150, 168, 0.50));
}
body[data-weather-scene="fog"] .sky::after {
  background: linear-gradient(180deg, rgba(220, 220, 220, 0.32), rgba(200, 200, 210, 0.48));
}

/* ============ Sky-character visibility (sky97) ============
   .sky-character lives inside .hero, full-bleed. Only one .sc-* child
   is visible at a time, picked by body[data-weather-scene]. Clear weather
   shows neither (the existing .sun / .moon are the clear character). */

.sky-character {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  overflow: hidden;
}
.sky-character .sc {
  position: absolute;
  /* Start the weather character BELOW the topbar, not at the hero's top edge
     (Ann, 2026-07-25: "在 hero 图片的最上方用同样的背景色延伸出来一块 ...
     最上面的那部分没有任何其他装饰的内容").

     The hero deliberately slides up behind the topbar so the sky fills the
     notch region, which means its top band is exactly where the city pill and
     the gear sit -- so a character drawn from `top: 0` lands under them by
     construction. Measured across every weather scene at 430pt: 8 of 9 collided
     with the pill and 7 of those also with the gear. Only `clear` was safe, and
     only because it draws nothing. This was never a one-cloud or one-city
     problem; Changsha simply made it obvious, being a dark cloud on a night sky.

     No extra element is needed for the clean strip Ann described: .sky is a
     full-hero gradient, so the band above the character IS already the same sky.
     Pushing the character down uncovers it.

     The offset is DERIVED, not chosen: `calc(56px + var(--sat))` is the hero's
     own padding-top, i.e. exactly how much of the hero the topbar covers, so it
     tracks the safe-area inset per device instead of needing a value per phone.
     Measured clearance below the gear: 11px at --sat 59. */
  top: calc(56px + var(--sat));
  left: 0;
  width: 100%;
  /* Height stays 65% of the hero rather than shrinking to fit the new top.
     Shrinking was tried and is visibly worse: the character SVGs stretch to
     their box, so compressing the box exposed a hard rectangular seam down the
     right-hand side. Translating keeps the artwork's proportions. */
  height: 65%;
  display: none;
}
.sky-character .sc > svg {
  width: 100%;
  height: 100%;
  display: block;
}

/* Scene → which .sc is visible. Order: most specific selector wins. */
body[data-weather-scene="partly-cloudy"] .sky-character .sc-partly-cloudy { display: block; }
body[data-weather-scene="cloudy"]        .sky-character .sc-cloudy        { display: block; }
body[data-weather-scene="fog"]           .sky-character .sc-fog           { display: block; }
body[data-weather-scene="drizzle"]       .sky-character .sc-drizzle       { display: block; }
body[data-weather-scene="rain-heavy"]    .sky-character .sc-rain-heavy    { display: block; }
body[data-weather-scene="snow"]          .sky-character .sc-snow          { display: block; }
body[data-weather-scene="heavy-snow"]    .sky-character .sc-heavy-snow    { display: block; }
body[data-weather-scene="storm"]         .sky-character .sc-storm         { display: block; }
body[data-weather-scene="thunderstorm"]  .sky-character .sc-thunderstorm  { display: block; }

/* Hide .sun + .flare for scenes where the sun shouldn't be visible.
   partly-cloudy KEEPS the sun (it peeks through the scattered clouds).
   clear KEEPS the sun (default — no rule needed). */
body[data-weather-scene="cloudy"] .sun,
body[data-weather-scene="cloudy"] .flare,
body[data-weather-scene="fog"] .sun,
body[data-weather-scene="fog"] .flare,
body[data-weather-scene="drizzle"] .sun,
body[data-weather-scene="drizzle"] .flare,
body[data-weather-scene="rain-heavy"] .sun,
body[data-weather-scene="rain-heavy"] .flare,
body[data-weather-scene="snow"] .sun,
body[data-weather-scene="snow"] .flare,
body[data-weather-scene="heavy-snow"] .sun,
body[data-weather-scene="heavy-snow"] .flare,
body[data-weather-scene="storm"] .sun,
body[data-weather-scene="storm"] .flare,
body[data-weather-scene="thunderstorm"] .sun,
body[data-weather-scene="thunderstorm"] .flare {
  display: none;
}
/* partly-cloudy: sun stays visible but dimmed slightly so the foreground
   clouds read as "in front of" the sun rather than "next to" it. */
body[data-weather-scene="partly-cloudy"] .sun { opacity: 0.85; }

/* Fog: drape a translucent misty veil across the ENTIRE hero — including
   over the temperature numerals. Real fog obscures vision; we go light
   enough that the temp is still legible but visibly washed out. (sky102) */
body[data-weather-scene="fog"] .hero::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 5;             /* above .hero-inner (z:4) so temp is veiled */
  pointer-events: none;
  background:
    radial-gradient(ellipse 90% 60% at 30% 35%, rgba(248, 248, 248, 0.45), transparent 70%),
    radial-gradient(ellipse 100% 70% at 70% 65%, rgba(245, 240, 235, 0.40), transparent 70%),
    linear-gradient(180deg,
      rgba(235, 235, 238, 0.38) 0%,
      rgba(225, 225, 230, 0.30) 50%,
      rgba(238, 238, 242, 0.42) 100%);
}
/* Night fog: dim indigo-gray haze, NOT bright white. Daytime fog veil
   above would wash the night sky to milky-bright; this override keeps
   the dark gradient readable while still obscuring the temp. (sky103) */
body[data-time-scene="night"][data-weather-scene="fog"] .hero::after {
  background:
    radial-gradient(ellipse 90% 60% at 30% 35%, rgba(90, 95, 115, 0.50), transparent 70%),
    radial-gradient(ellipse 100% 70% at 70% 65%, rgba(75, 80, 105, 0.45), transparent 70%),
    linear-gradient(180deg,
      rgba(60, 65, 90, 0.48) 0%,
      rgba(50, 55, 80, 0.42) 50%,
      rgba(50, 55, 80, 0.52) 100%);
}

/* Night-clear emphasis: when clear + night, intensify the existing star
   field (already drawn by .sky::before). Pure CSS, no DOM nodes added. */
body[data-weather-scene="clear"][data-time-scene="night"] .sky::before {
  filter: brightness(1.35);
}

/* ============ Night × weather composition (sky103) ============
   The base night gradient + cloud SVGs compose for any weather scene,
   but the daytime cloud colors look fluorescent against a navy night sky.
   These rules darken the cloud artwork at night so it reads as silhouettes
   against starlight, and hide moon/stars when the sky is overcast (real
   moon can't shine through full cloud cover). */

/* Darken cloud SVGs at night — but NOT for thunderstorm. Thunderstorm
   clouds are already drawn with dark fills (#2a2840, #1a1a2e) in the SVG;
   adding a parent brightness(0.45) filter would also dim the lightning
   bolt (the parent filter creates a stacking context that pre-darkens
   everything inside, including children with counter-filters). So:
   thunderstorm cloud darkness lives in SVG fill colors, all other
   weather scenes get the parent filter. (sky105) */
body[data-time-scene="night"]:not([data-weather-scene="thunderstorm"]) .sky-character {
  filter: brightness(0.45) saturate(0.55);
}
/* Night thunderstorm: cloud SVGs go EVEN darker via their own fill
   override (no parent filter to do it) so the lightning has high
   contrast against the cloud bank. */
body[data-time-scene="night"][data-weather-scene="thunderstorm"] .sky-character .sc-thunderstorm path:not(.sc-lightning-bolt) {
  fill: #0a0a16;
}
/* Night thunderstorm bolt: extra glow halo so it reads as the brightest
   thing in the night sky. */
body[data-time-scene="night"][data-weather-scene="thunderstorm"] .sc-lightning-bolt {
  filter: drop-shadow(0 0 12px rgba(255, 230, 130, 0.95))
          drop-shadow(0 0 32px rgba(255, 200, 80, 0.65));
}

/* Moon visibility: hide it when overcast or precipitating (cloud cover
   blocks the moon). Night-partly-cloudy KEEPS the moon (peeks through). */
body[data-time-scene="night"][data-weather-scene="cloudy"] .moon,
body[data-time-scene="night"][data-weather-scene="fog"] .moon,
body[data-time-scene="night"][data-weather-scene="drizzle"] .moon,
body[data-time-scene="night"][data-weather-scene="rain-heavy"] .moon,
body[data-time-scene="night"][data-weather-scene="storm"] .moon,
body[data-time-scene="night"][data-weather-scene="thunderstorm"] .moon,
body[data-time-scene="night"][data-weather-scene="snow"] .moon,
body[data-time-scene="night"][data-weather-scene="heavy-snow"] .moon {
  display: none;
}

/* Stars: hide when overcast/precipitating (same reasoning as moon). The
   .sky::before star field is shared across all themes. */
body[data-time-scene="night"][data-weather-scene="cloudy"] .sky::before,
body[data-time-scene="night"][data-weather-scene="fog"] .sky::before,
body[data-time-scene="night"][data-weather-scene="drizzle"] .sky::before,
body[data-time-scene="night"][data-weather-scene="rain-heavy"] .sky::before,
body[data-time-scene="night"][data-weather-scene="storm"] .sky::before,
body[data-time-scene="night"][data-weather-scene="thunderstorm"] .sky::before,
body[data-time-scene="night"][data-weather-scene="snow"] .sky::before,
body[data-time-scene="night"][data-weather-scene="heavy-snow"] .sky::before {
  display: none;
}

/* Partly-cloudy at night: moon stays (peeks through scattered clouds),
   stars partially visible. The cloud-darken filter above already dims
   the scattered cumulus shapes so the moon reads through them. */

/* Moon + stars ambient motion (Ann: 月亮也要像太阳那样有动作, 星星一点点闪动).
   Compositor-friendly (transform / opacity only). Very slow + subtle so the
   night reads as "alive but calm", not busy. */
@keyframes moon-float {
  0%, 100% { transform: translate(0, 0); }
  50%      { transform: translate(-7px, 5px); }
}
@keyframes star-twinkle {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.72; }
}
body[data-time-scene="night"] .moon {
  animation: moon-float 90s ease-in-out infinite;
}
body[data-time-scene="night"] .sky::before {
  animation: star-twinkle 5.5s ease-in-out infinite;
}

/* ============ Sky-character ambient motion (sky97) ============
   Compositor-friendly (transform/opacity only) per the web/coding-style
   rule. Slow drift = "alive but calm" feel. */

@keyframes sc-drift-slow {
  0%, 100% { transform: translateX(0); }
  50%      { transform: translateX(-40px); }
}
@keyframes sc-drift-mid {
  0%, 100% { transform: translateX(0); }
  50%      { transform: translateX(-30px); }
}
@keyframes sc-drift-fast {
  0%, 100% { transform: translateX(0); }
  50%      { transform: translateX(-24px); }
}
@keyframes sc-drift-a-cumulus {
  0%   { transform: translateX(0); }
  100% { transform: translateX(60px); }
}
@keyframes sc-drift-b-cumulus {
  /* Shifted 20px left of the old 0/-50px range: cloud B's rest position
     (0%, which is also what every fresh page load starts on) sat close
     enough to .sun's bounding box to graze it, since .sky-character and
     .sun share z-index 1 with .sky-character painting later in the DOM
     (no stacking guarantee keeps the sun on top). Same 50px drift range,
     just starting with clearance instead of already touching. */
  0%   { transform: translateX(-20px); }
  100% { transform: translateX(-70px); }
}
@keyframes sc-fog-band-1 { 0%, 100% { transform: translateX(0); } 50% { transform: translateX(-22px); } }
@keyframes sc-fog-band-2 { 0%, 100% { transform: translateX(0); } 50% { transform: translateX( 26px); } }
@keyframes sc-fog-band-3 { 0%, 100% { transform: translateX(0); } 50% { transform: translateX(-18px); } }
@keyframes sc-cloud-breath {
  0%, 100% { transform: scaleY(1); }
  50%      { transform: scaleY(1.025); }
}

/* Cloud + fog drift ~10% faster (Ann: 云移动稍微明显一点). These selectors are
   global (any scene's clouds/fog), so the speed-up applies across every hero
   form at once. Durations cut ~10%. */
.sky-character .sc-drift-slow { animation: sc-drift-slow 90s ease-in-out infinite; transform-origin: center; }
.sky-character .sc-drift-mid  { animation: sc-drift-mid 63s ease-in-out infinite; transform-origin: center; }
.sky-character .sc-drift-fast { animation: sc-drift-fast 36s ease-in-out infinite; transform-origin: center; }
.sky-character .sc-drift-a    { animation: sc-drift-a-cumulus 72s linear infinite; transform-origin: center; }
.sky-character .sc-drift-b    { animation: sc-drift-b-cumulus 99s linear infinite; transform-origin: center; }
.sky-character .sc-fog-band-1 { animation: sc-fog-band-1 63s ease-in-out infinite; transform-origin: center; }
.sky-character .sc-fog-band-2 { animation: sc-fog-band-2 81s ease-in-out infinite; transform-origin: center; }
.sky-character .sc-fog-band-3 { animation: sc-fog-band-3 54s ease-in-out infinite; transform-origin: center; }
/* Cloudy gets an additional slow breath on top of horizontal drift —
   stacks via combining transforms on parent + child (the inner SVG <g>
   already handles translateX). Apply breath to the outer .sc box. */
.sky-character .sc-cloudy { animation: sc-cloud-breath 11s ease-in-out infinite; }

/* Thunderstorm lightning — the bolt is drawn at opacity 0.92 by HTML
   markup (always visible as scene identifier). The CSS keyframe briefly
   pulses opacity to 1 every ~7s + the sky-character flash overlay does
   the "crack" feel. Keyframe touches opacity only (not filter) so the
   default glow + night-override glow persist. */
@keyframes sc-lightning-bolt-pulse {
  0%, 87%, 100% { opacity: 0.92; }
  88%, 91% { opacity: 1; }
}
@keyframes sc-lightning-flash {
  0%, 87%, 100% { background: transparent; }
  88%, 91% { background: rgba(255, 250, 220, 0.45); }
  89% { background: rgba(255, 250, 220, 0.18); }
}
.sky-character .sc-thunderstorm .sc-lightning-bolt {
  /* Default (day + golden-hour): warm yellow glow around the bolt. */
  filter: drop-shadow(0 0 8px rgba(255, 220, 100, 0.65))
          drop-shadow(0 0 18px rgba(255, 200, 80, 0.40));
  animation: sc-lightning-bolt-pulse 7s ease-in-out infinite;
}
body[data-weather-scene="thunderstorm"] .sky-character {
  animation: sc-lightning-flash 7s ease-in-out infinite;
}

@media (prefers-reduced-motion: reduce) {
  .sky-character .sc-drift-slow,
  .sky-character .sc-drift-mid,
  .sky-character .sc-drift-fast,
  .sky-character .sc-drift-a,
  .sky-character .sc-drift-b,
  .sky-character .sc-fog-band-1,
  .sky-character .sc-fog-band-2,
  .sky-character .sc-fog-band-3,
  .sky-character .sc-cloudy,
  .sky-character .sc-thunderstorm .sc-lightning-bolt,
  body[data-weather-scene="thunderstorm"] .sky-character {
    animation: none;
  }
}

/* ============ Sky-glyph (minimal theme only) (sky97) ============
   Flat geometric icons that replace the .sky-character SVGs when
   data-theme="minimal" is active. Positioned center-upper, large
   enough to read as the focal element. */

.sky-glyph {
  position: absolute;
  top: 18%;
  right: 8%;
  width: 110px;
  height: 80px;
  z-index: 1;
  pointer-events: none;
  display: none;             /* shown by minimal-theme rules below */
}
.sky-glyph .sg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: none;
}

/* ============ HERO TEXT CONTRAST per time scene ============
   The original hero text (cream + gold accents) was tuned against the dusk
   sky which is dark at the top. Day + dawn scenes have a bright sky band
   that washes out cream text — switch to dark ink + text-shadow for those.
   Night + dusk keep the original cream/gold. */

/* DAY: bright sky → dark navy ink with white-glow shadow */
body[data-time-scene="day"] .temp-num,
body[data-time-scene="day"] .temp-unit,
body[data-time-scene="day"] .meta-condition,
body[data-time-scene="day"] .meta-mono {
  color: #15203d;
  text-shadow: 0 1px 14px rgba(255, 255, 255, 0.55), 0 0 24px rgba(255, 255, 255, 0.35);
}
body[data-time-scene="day"] .temp-meta-label,
body[data-time-scene="day"] .temp-meta {
  /* Cream text + ink shadow + small dark pill background so the
     humidity stat reads sharply against any strip of the hero (bright
     sky, dark plum mountains, coral horizon). The pill is barely
     there but anchors the text in a guaranteed contrast region. */
  color: #fff8e8;
  text-shadow: 0 1px 4px rgba(15, 12, 28, 0.85), 0 0 8px rgba(15, 12, 28, 0.55);
}
/* The numeric value gets a small dark pill so it pops harder than the
   surrounding label text. */
body[data-time-scene="day"] .temp-meta .meta-mono {
  background: rgba(15, 12, 28, 0.45);
  padding: 2px 8px;
  border-radius: 100px;
  color: #fff8e8;
}
body[data-time-scene="day"] .temp-meta .feels-val {
  color: #8a5a0e;  /* darker gold so it pops without losing the warm accent */
  text-shadow: 0 1px 8px rgba(255, 255, 255, 0.45);
}
/* Day/dawn used to use dark text because the bright cream sky was
   the direct background. Now there's a near-solid black scrim behind
   .headline (base CSS), so light cream text is correct for every
   scene. Keeping the rules as no-op overrides to make the intent
   visible; deleting them entirely would silently inherit base. */
body[data-time-scene="day"] .headline {
  color: #fff8e8;
  text-shadow: none;
}
body[data-time-scene="day"] .headline-marks {
  color: rgba(255, 248, 232, 0.55);
}

/* DAWN: similar palette story (bright peach band on the lower half) */
/* .temp-unit was missing from this selector list, so the degree mark alone fell
   through to the base on-sky colour and sat at 1.6:1 on the peach band while the
   number beside it was fine. Theme x scene is an 8-cell grid; it was filled in
   by hand and two cells were never written. */
body[data-time-scene="dawn"] .temp-num,
body[data-time-scene="dawn"] .temp-unit,
body[data-time-scene="dawn"] .meta-condition,
body[data-time-scene="dawn"] .meta-mono {
  color: #2a1d40;
  text-shadow: 0 2px 18px rgba(255, 235, 210, 0.55);
}
body[data-time-scene="dawn"] .temp-meta-label,
body[data-time-scene="dawn"] .temp-meta {
  color: rgba(42, 29, 64, 0.75);
}
body[data-time-scene="dawn"] .headline {
  color: #fff8e8;
  text-shadow: none;
}

/* DAY scene also wants the sun nudged out of the right-side meta text
   column on narrow phones so "clear sky" italic doesn't overlap the sun
   disc directly. Smaller + higher + further right. */
body[data-time-scene="day"] .sun {
  top: 18%;
  /* 8% -> 20% (2026-07-25): at 8% the disc overlapped the settings gear by
     10x29px on a 430pt phone and 11x16 on a 414, and the 120px glow reached
     further still, so the gear sat on the sun.

     DAY is the only scene that collided -- measured across all five: dawn
     (right 94.6), golden-hour and dusk (68.8), night's moon (68.8) all clear
     the gear already. So this moves one rule, not the whole family.

     The comment above says day was pushed to 8% to keep the disc off the
     right-side meta text column, so moving it back LEFT is exactly the thing
     that rule was guarding against. Re-measured before trusting it: sun-vs-
     temp-meta and sun-vs-temp-block are "none" at 13/16/20/24% on both 430 and
     414 widths, so the guard does not bite here. 13% would already clear the
     gear; 20% is the value Ann approved from the mockup. */
  right: 20%;
  width: 64px;
  height: 64px;
}
/* The flare is a SEPARATE element that has to be moved with the disc it belongs
   to. Moving the sun above without this left the glow behind at right:8% --
   which is exactly where the gear is, so the fix for "the gear covers the sun"
   quietly parked the sun's halo under the gear instead. Caught by diffing the
   rendered pixels under the gear with the flare shown vs hidden: 10.6 mean
   channels of brightening in this scene, against 0.8 to 1.4 in the scenes where
   the flare is genuinely elsewhere, and 28 in a positive control taken on the
   sun itself. A bounding-box check alone would have called all of them equal. */
body[data-time-scene="day"] .flare {
  top: 18%;
  /* 8% -> 20%, kept in step with the .sun rule above. This value exists twice
     in this file by design of the original author (disc and halo are separate
     elements), which is precisely why moving one silently stranded the other. */
  right: 20%;
  width: 198px;
  height: 198px;
  opacity: 0.50;
}

@keyframes storm-flicker {
  0%, 91%, 95%, 100% { opacity: 1; }
  92% { opacity: 0.55; }
  93% { opacity: 1; }
  94% { opacity: 0.7; }
}

@media (prefers-reduced-motion: reduce) {
  body[data-weather-scene="storm"] .sky::after { animation: none; }
}

/* ---------- Star field at night (pure CSS, no DOM nodes) ---------- */

body[data-time-scene="night"] .sky::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background-image:
    radial-gradient(1px 1px at 12% 18%, rgba(255,255,255,0.7), transparent),
    radial-gradient(1px 1px at 28% 8%,  rgba(255,255,255,0.55), transparent),
    radial-gradient(1px 1px at 47% 22%, rgba(255,255,255,0.65), transparent),
    radial-gradient(1px 1px at 63% 5%,  rgba(255,255,255,0.5), transparent),
    radial-gradient(1px 1px at 78% 14%, rgba(255,255,255,0.7), transparent),
    radial-gradient(1px 1px at 88% 9%,  rgba(255,255,255,0.55), transparent),
    radial-gradient(1.4px 1.4px at 18% 32%, rgba(255,240,210,0.75), transparent),
    radial-gradient(1px 1px at 36% 38%, rgba(255,255,255,0.4), transparent),
    radial-gradient(1.2px 1.2px at 55% 30%, rgba(220,230,255,0.6), transparent),
    radial-gradient(1px 1px at 70% 35%, rgba(255,255,255,0.5), transparent),
    radial-gradient(1px 1px at 92% 25%, rgba(255,255,255,0.55), transparent);
  background-size: 100% 100%;
}

/* ============ THEME: Cinematic (default) ============
   Most direct Tenki no Ko quote. Keep the existing dramatic cloud
   layers + flare. No additional overrides — the base shinkai.css IS
   the cinematic theme, scene gradients above just adapt it. */

body[data-theme="cinematic"] .cloud-layer.far { opacity: 0.6; }
body[data-theme="cinematic"] .cloud-layer.near { opacity: 1; }

/* ============ THEME: Painterly (watercolor / Ghibli-quiet) ============
   Softer palette, gentler cloud layers, no harsh flare. Subtle paper-grain
   noise via SVG-data-url overlay. Particles get more transparent in JS via
   the natural `opacity` param. */

/* Reposition painterly sun further off-meta on dusk/night specifically.
   Default position (top:30%/right:16%) collides with temp-meta column
   on 390px-wide phones; shift up + further right + smaller halo. */
/* Day + dawn keep the base scene rule (already pushed sun to top:18%/right:8%
   and top:50%/right:22% respectively — those don't collide with meta). */

/* Painterly recolors sky-character clouds — warmer/pinker palette, plus a
   feTurbulence+feDisplacementMap SVG filter (#painterly-bleed) that warps
   cloud edges into hand-painted shapes. Pure watercolor — no extra SVG
   assets, same source paths as cinematic, different render layer. (sky98) */
/* Apply watercolor-bleed filter to every cloud SVG. saturate(1.18) +
   contrast(0.94) shifts toward "painted" rather than "rendered". The url()
   reference points at the inline <defs> in templates/shinkai.html. */
/* Bump paper grain so the texture reads at hero scale on iPhone (sky99). */

/* ============ Painterly global atmosphere (sky99) ============
   The bleed filter only touched cloud SVGs, so scenes without clouds
   (night-clear, fog) and dark scenes (storm) read identical to cinematic.
   Painterly now overrides the SKY GRADIENT stops to warmer
   watercolor palettes — covers 60% of hero area and reads as a different
   theme even with zero clouds. */

/* Warm hill silhouettes — painterly hills lean toward terracotta/plum
   instead of cinematic's cool plum. Touches every time-of-day at once. */

/* Tint the moon a slight peach (warm-ivory rather than cool-white). The
   filter shifts the moon's existing radial gradient toward warmer tones
   without rewriting the SVG itself. */

/* Painterly star field — warmer, more cream-tinted than cinematic's
   cool white/blue stars. Re-defines the existing :before pattern. */

/* Subtle paper grain — inline SVG noise */

/* ============ THEME: Minimal (flat color bands, woodblock-print) ============
   No gradients on the sky — solid color bands instead. No clouds, no
   flare. Sun is a single solid disc. Reads like a Hokusai-era print. */

body[data-theme="minimal"] .sky { background: var(--scene-sky-flat, #2e4a7f); }
body[data-theme="minimal"][data-time-scene="dawn"] { --scene-sky-flat: #c77b4c; }
body[data-theme="minimal"][data-time-scene="day"]  { --scene-sky-flat: #87b8de; }
body[data-theme="minimal"][data-time-scene="golden-hour"] { --scene-sky-flat: #c77b4c; }
body[data-theme="minimal"][data-time-scene="night"] { --scene-sky-flat: #14122a; }

body[data-theme="minimal"] .flare,
body[data-theme="minimal"] .cloud-layer { display: none; }

/* Minimal theme: replace cinematic/painterly cloud SVGs with flat glyph icons.
   .sky-character hides entirely; .sky-glyph shows one .sg-* child per
   weather scene. The existing .sun (already a flat yellow circle under
   minimal) keeps showing for clear + partly-cloudy. */
body[data-theme="minimal"] .sky-character { display: none; }

body[data-theme="minimal"] .sky-glyph { display: block; }
body[data-theme="minimal"][data-weather-scene="partly-cloudy"] .sky-glyph .sg-partly-cloudy { display: block; }
body[data-theme="minimal"][data-weather-scene="cloudy"]        .sky-glyph .sg-cloudy        { display: block; }
body[data-theme="minimal"][data-weather-scene="fog"]           .sky-glyph .sg-fog           { display: block; }
body[data-theme="minimal"][data-weather-scene="drizzle"]       .sky-glyph .sg-drizzle       { display: block; }
body[data-theme="minimal"][data-weather-scene="rain-heavy"]    .sky-glyph .sg-rain-heavy    { display: block; }
body[data-theme="minimal"][data-weather-scene="snow"]          .sky-glyph .sg-snow          { display: block; }
body[data-theme="minimal"][data-weather-scene="heavy-snow"]    .sky-glyph .sg-heavy-snow    { display: block; }
body[data-theme="minimal"][data-weather-scene="storm"]         .sky-glyph .sg-storm         { display: block; }
body[data-theme="minimal"][data-weather-scene="thunderstorm"]  .sky-glyph .sg-thunderstorm  { display: block; }

/* For minimal + partly-cloudy specifically: nudge the small cloud glyph
   so it sits LEFT of the sun (partial occlusion read), and shrink it. */
body[data-theme="minimal"][data-weather-scene="partly-cloudy"] .sky-glyph {
  top: 28%;
  right: 22%;
  width: 80px;
  height: 50px;
}
/* For weather states that REPLACE the sun (no .sun visible), grow the glyph
   so it carries the visual weight that .sun normally would. */
body[data-theme="minimal"][data-weather-scene="cloudy"] .sky-glyph,
body[data-theme="minimal"][data-weather-scene="drizzle"] .sky-glyph,
body[data-theme="minimal"][data-weather-scene="rain-heavy"] .sky-glyph,
body[data-theme="minimal"][data-weather-scene="snow"] .sky-glyph,
body[data-theme="minimal"][data-weather-scene="heavy-snow"] .sky-glyph,
body[data-theme="minimal"][data-weather-scene="storm"] .sky-glyph,
body[data-theme="minimal"][data-weather-scene="thunderstorm"] .sky-glyph {
  top: 16%;
  right: 8%;
  width: 130px;
  height: 96px;
}
/* Fog: low bars across the upper sky — full-width slot, not a corner glyph. */
body[data-theme="minimal"][data-weather-scene="fog"] .sky-glyph {
  top: 28%;
  right: 0;
  left: 0;
  width: 100%;
  height: 70px;
}

body[data-theme="minimal"] .sun {
  background: #ffd07a;
  box-shadow: none;
  animation: none;
  width: 96px; height: 96px;
}
body[data-theme="minimal"] .moon {
  filter: none;
}

body[data-theme="minimal"] .skyline path {
  fill: rgba(15, 12, 31, 1);
}

/* Minimal + dusk specifically: flat coral sky + original cream text is
   ~3.4:1 contrast (WCAG AA needs 4.5:1 for body text). Other themes' dusk
   works because the gradient has a dark band at top; minimal's flat sky
   doesn't. Apply the dark-ink override that day + dawn scenes already use. */
/* GOLDEN HOUR (cinematic): the missing cell. The band behind the number is a
   bright warm orange, so the display type takes dark ink with a warm glow, the
   same story as day and dawn -- pale-on-pale was measuring 2.4:1. */
body[data-time-scene="golden-hour"] .temp-num,
body[data-time-scene="golden-hour"] .temp-unit,
body[data-time-scene="golden-hour"] .meta-condition,
body[data-time-scene="golden-hour"] .meta-mono {
  color: #3a2016;
  text-shadow: 0 2px 18px rgba(255, 238, 214, 0.60), 0 0 26px rgba(255, 238, 214, 0.35);
}

body[data-theme="minimal"][data-time-scene="golden-hour"] .temp-num,
body[data-theme="minimal"][data-time-scene="golden-hour"] .temp-unit,
body[data-theme="minimal"][data-time-scene="golden-hour"] .meta-condition,
body[data-theme="minimal"][data-time-scene="golden-hour"] .meta-mono {
  color: #2a1d40;
  text-shadow: 0 1px 10px rgba(255, 235, 210, 0.5);
}
body[data-theme="minimal"][data-time-scene="golden-hour"] .temp-meta-label,
body[data-theme="minimal"][data-time-scene="golden-hour"] .temp-meta {
  color: rgba(42, 29, 64, 0.78);
}
body[data-theme="minimal"][data-time-scene="golden-hour"] .temp-meta .feels-val {
  color: #6b3a08;
}
body[data-theme="minimal"][data-time-scene="golden-hour"] .headline {
  color: #2a1d40;
}

body[data-theme="minimal"][data-time-scene="night"] .sky::before {
  /* Fewer, sharper stars on the flat night */
  background-image:
    radial-gradient(1px 1px at 20% 15%, #fff, transparent),
    radial-gradient(1px 1px at 50% 8%,  #fff, transparent),
    radial-gradient(1px 1px at 75% 18%, #fff, transparent),
    radial-gradient(1.2px 1.2px at 35% 30%, rgba(255,240,210,0.85), transparent);
}

/* ============ Theme picker UI (top of city sheet for discoverability) ============ */

.theme-picker {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 18px;
  padding-bottom: 18px;
  border-bottom: 1px solid var(--card-line);
}
/* Was originally placed AFTER the city list with a top divider — moved to top
   of sheet in v=sky96 so it's the first thing visible when the sheet opens. */
.theme-picker.theme-picker-top {
  margin-top: 0;
  padding-top: 0;
  border-top: none;
}
.theme-picker-label {
  flex-basis: 100%;
  font-size: 9.5px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--cream-subtle);
  font-weight: 600;
  margin-bottom: 4px;
}
.theme-picker-row {
  display: flex;
  gap: 8px;
  flex-basis: 100%;
}
.theme-picker button {
  appearance: none;
  flex: 1;
  border: 1px solid var(--card-line-strong);
  background: rgba(244, 236, 216, 0.04);
  color: var(--cream-muted);
  border-radius: 14px;
  padding: 12px 8px;
  font-family: var(--sans);
  font-size: 12.5px;
  font-weight: 500;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background .15s, border-color .15s, transform .07s, color .15s;
  min-height: 44px;
  line-height: 1.2;
}
.theme-picker button:active { transform: scale(0.97); }
.theme-picker button.active {
  /* The tint was a hardcoded copy of the OLD gold, and the label used
     --gold-soft, which is the LIFTED variant meant for dark surfaces. On a pale
     tint that is amber-on-yellow and reads washed out. Both now come from the
     brand token, and the label takes the dark variant because this card is
     light. Measured: 5.0:1. */
  background: linear-gradient(135deg, rgba(200, 121, 10, 0.055), rgba(200, 121, 10, 0.02));
  border-color: var(--accent-edge);
  color: var(--gold-deep);
  font-weight: 600;
}
.theme-picker .theme-name {
  display: block;
  font-family: var(--serif);
  font-style: italic;
  font-size: 14px;
  margin-bottom: 2px;
}
.theme-picker .theme-desc {
  display: block;
  font-size: 10px;
  letter-spacing: 0.04em;
  opacity: 0.75;
}

/* =========================================================
   HEADLINE CONTRAST FIX (all themes, all scenes)
   The headline sits over the dark silhouette band at the bottom of
   the hero. Cream/gold ink + a soft text-shadow leaves it readable
   against the navy/plum silhouette in EVERY scene. The scene-specific
   overrides earlier in this file still cover dawn/day; this baseline
   covers dusk + night + anything not otherwise specified.
========================================================= */
.headline {
  /* Old multi-layer text-shadow was needed when the headline sat
     directly over the silhouette band. Now the near-solid black
     scrim (base CSS) provides the contrast, and the shadow just
     blurs the text edges. Removed. */
  text-shadow: none;
}
/* Day + dawn already use dark ink — flip the shadow to a pale halo
   so the dark ink stays legible against the cream/peach band. */
body[data-time-scene="day"] .headline,
body[data-time-scene="dawn"] .headline {
  text-shadow:
    0 1px 2px rgba(255, 255, 255, 0.85),
    0 0 14px rgba(255, 255, 255, 0.55);
}

/* =========================================================
   WHOLE-APP THEME OVERRIDES
   =========================================================
   Each theme below restructures the cards, chart, day strip, take
   cells, chat bubbles, scenario chips, and headline treatment so the
   theme picker visibly changes the ENTIRE page, not just the hero.

   Cascade ordering: these blocks come AFTER all base shinkai.css rules
   (loaded first via <link>), so a single body[data-theme=...] selector
   beats the default specificity. Where the base uses 2-class selectors
   (e.g. .day.today), the override matches the same specificity by also
   chaining via body[data-theme=...] .day.today.
========================================================= */

/* ─────────────────────────────────────────────────────────
   THEME: Cinematic (default — Tenki no Ko)
   Identity: warm cream cards, brilliant gold + coral accents,
   smooth flowing curves with a film-grade glow. The default the
   app shipped with — extended here so the theme picker explicitly
   reasserts cinematic-ness when the user toggles back from another
   theme (without these, switching painterly→cinematic would leave
   stale painterly inheritance on the cards).
─────────────────────────────────────────────────────────── */

body[data-theme="cinematic"] {
  --theme-accent: #ff8c5f;          /* Tenki coral as the second accent */
  --theme-accent-soft: #ffd766;     /* warm gold */
  --theme-curve: #f6b94a;           /* chart temp curve */
  --theme-curve-glow: rgba(246, 185, 74, 0.55);
}
/* Cards: keep the warm-cream gradient. */
body[data-theme="cinematic"] .card {
  background: linear-gradient(180deg, var(--card) 0%, var(--card-2) 100%);
  border: 1px solid var(--card-line);
  border-radius: 22px;
}
/* Today tile: amber radial glow — pure Tenki sunset. */
body[data-theme="cinematic"] .day.today {
  background: linear-gradient(180deg, rgba(255, 140, 95, 0.18) 0%, rgba(255, 182, 40, 0.10) 100%);
  border-color: rgba(255, 140, 95, 0.42);
  box-shadow: 0 0 0 1px rgba(255, 140, 95, .18), 0 8px 28px -16px rgba(255, 140, 95, .5);
}

/* ─────────────────────────────────────────────────────────
   THEME: Painterly (Watercolor / Ghibli)
   Identity: warmer amber cards with paper-grain texture, softer
   borders, less saturated chart curve (terracotta), rounded
   everything, generous italic serif. Reads like a hand-painted
   weather page in a Ghibli sketchbook.
─────────────────────────────────────────────────────────── */

/* Cards: warmer amber + paper-grain noise overlay + soft hand-drawn border.
   The ::before injects an SVG-noise layer that gives every card a subtle
   watercolor texture. */
/* Make sure card content stays above the noise. */

/* Chart temp curve: terracotta with softer glow. SVG presentation
   attributes (stroke="...") are beaten by CSS `stroke:` declarations. */
/* Now-indicator dot: match the curve tone. */
/* Wind curve in painterly: warmer dusty-blue (less neon). */

/* Take cells: warmer tint + softer rounded border, no hard edges. */
/* Cell-icon: warmer chip tone */
/* Cell val accent (em) — terracotta instead of gold. */

/* Day strip — softer rounded tiles, terracotta today highlight. */

/* Chat: rounder bubbles, terracotta user pill */

/* Scenario chips: warmer wash */

/* Headline + take-headline italic serif feels right for painterly already.
   Bump the italic emphasis a touch with a soft amber accent on em. */

/* Today's high/low accent in chart head: terracotta. */

/* Unit toggle + city trigger active state: terracotta */

/* Theme-picker active pill: terracotta */

/* Outfit pills: rounded with warmer tone */

/* Painterly contrast fixes — the base cream-subtle (45% opacity ink) is
   too faint against the warmer amber card. Bump cell-lab + kicker +
   d-label to a deeper warm-brown that holds AA on the amber. */

/* Dusk hero meta: the sun disc + bright peach band on the lower 2/3
   of the sky wash out cream text. Switch ALL themes' dusk hero meta
   to dark ink with a cream halo (same trick the base CSS uses for
   day + dawn). The temp-num itself is large enough that cream still
   reads, but the smaller mono values need this. */
body[data-time-scene="golden-hour"] .temp-meta,
body[data-time-scene="golden-hour"] .meta-mono {
  color: #2a1d40;
  text-shadow: 0 1px 8px rgba(255, 235, 210, 0.7), 0 0 16px rgba(255, 235, 210, 0.5);
}
body[data-time-scene="golden-hour"] .temp-meta-label {
  color: rgba(42, 29, 64, 0.78);
  text-shadow: 0 1px 6px rgba(255, 235, 210, 0.7);
}
body[data-time-scene="golden-hour"] .temp-meta .feels-val {
  color: #6b3a08;
  text-shadow: 0 1px 6px rgba(255, 235, 210, 0.7);
}

/* (Painterly-specific overrides for night still apply below.) */
/* Night: dark sky → bright cream values with strong ink shadow. */

/* Painterly chat-log empty hint */

/* Minimal contrast: cell-detail needs more contrast on flat off-white */
body[data-theme="minimal"] .cell-detail {
  color: rgba(15, 12, 31, 0.70);
}
body[data-theme="minimal"] .feels-cell .cell-detail {
  color: rgba(247, 244, 237, 0.85);
}
body[data-theme="minimal"] .head-right {
  color: rgba(15, 12, 31, 0.72);
}
body[data-theme="minimal"] .day .d-lo,
body[data-theme="minimal"] .day .d-cond {
  color: rgba(15, 12, 31, 0.62);
}

/* ─────────────────────────────────────────────────────────
   THEME: Minimal (Hokusai woodblock)
   Identity: FLAT solid blocks, sharp edges, single accent (deep
   indigo), no gradients anywhere, bold typography with letter-
   spacing. The chart curve is a SHARP angular indigo line with NO
   glow. Everything reads as a graphic print, not a render.
─────────────────────────────────────────────────────────── */

body[data-theme="minimal"] {
  --theme-accent: #1a3566;          /* deep indigo */
  --theme-accent-soft: #4a6fa8;     /* mid indigo */
  --theme-curve: #1a3566;
  --theme-ink: #0f0c1f;             /* near-black ink */

  /* Cooler / cleaner cards — stark warm-off-white rather than cream */
  --card-minimal: #f7f4ed;
  --card-minimal-line: rgba(15, 12, 31, 0.16);
}

/* Cards: FLAT — no gradient, smaller radius, hairline ink border. */
body[data-theme="minimal"] .card {
  background: var(--card-minimal);
  border: 1.5px solid var(--card-minimal-line);
  border-radius: 8px;
}

/* Card head: bolder kicker with wider tracking. */
body[data-theme="minimal"] .kicker {
  color: var(--theme-ink);
  font-weight: 700;
  letter-spacing: 0.28em;
}

/* Chart temp curve: deep indigo, NO glow, slightly thicker.
   Targets the path the JS draws with stroke="#f6b94a". */
body[data-theme="minimal"] .chart-svg path[fill="none"][stroke="#f6b94a"] {
  stroke: var(--theme-curve);
  stroke-width: 3;
  filter: none;
}
body[data-theme="minimal"] .chart-svg circle[fill="#f6b94a"] {
  fill: var(--theme-curve);
  stroke: var(--card-minimal);
  filter: none;
}
/* Temp gradient area: flat indigo tint (override the orange linear-gradient
   defs the JS creates). The <stop>s have stop-color attributes; CSS can
   override them via the stop-color CSS property. */
body[data-theme="minimal"] .chart-svg #g-temp stop:nth-child(1) { stop-color: rgba(26, 53, 102, 0.35); }
body[data-theme="minimal"] .chart-svg #g-temp stop:nth-child(2) { stop-color: rgba(26, 53, 102, 0.10); }
body[data-theme="minimal"] .chart-svg #g-temp stop:nth-child(3) { stop-color: rgba(26, 53, 102, 0); }

/* Wind curves: cool grey — the chart is mono-accent in minimal. */
body[data-theme="minimal"] .chart-svg path[fill="none"][stroke="rgba(110,166,216,0.72)"] {
  stroke: rgba(15, 12, 31, 0.55);
}
body[data-theme="minimal"] .chart-svg path[fill="none"][stroke="rgba(155,196,234,0.85)"] {
  stroke: rgba(15, 12, 31, 0.4);
}
body[data-theme="minimal"] .chart-svg #g-wind stop:nth-child(1) { stop-color: rgba(15, 12, 31, 0.14); }
body[data-theme="minimal"] .chart-svg #g-wind stop:nth-child(2) { stop-color: rgba(15, 12, 31, 0.02); }

/* NOW dashed line: indigo ink instead of cream */
body[data-theme="minimal"] .chart-svg line[stroke="#fff8e8"] {
  stroke: var(--theme-ink);
  opacity: 0.6;
}

/* Sunrise marker color (the line is stroke="#f6b94a" too — but it has
   stroke-dasharray="3 4", so we differentiate by that attribute). The
   marker circle is fill, separate ruleset. We've already targeted
   stroke="#f6b94a" above which catches both the curve AND the sun marker
   line. That's fine — both go indigo. */

/* Hi/lo header accents: indigo + grey instead of gold + blue */
body[data-theme="minimal"] .head-right .hi-val { color: var(--theme-accent); font-weight: 700; }
body[data-theme="minimal"] .head-right .lo-val { color: rgba(15, 12, 31, 0.55); font-weight: 700; }
body[data-theme="minimal"] .head-right .dot {
  background: var(--theme-accent);
  box-shadow: none;
}

/* Chart legend swatches: indigo + grey */
body[data-theme="minimal"] .legend-swatch { background: var(--theme-accent); }
body[data-theme="minimal"] .legend-swatch.wind { background: rgba(15, 12, 31, 0.55); }
body[data-theme="minimal"] .legend-swatch.gust {
  background: repeating-linear-gradient(90deg, rgba(15, 12, 31, 0.55) 0 4px, transparent 4px 7px);
}
body[data-theme="minimal"] .legend-swatch.rain {
  background: linear-gradient(180deg, rgba(74, 111, 168, 0.6), rgba(74, 111, 168, 0.08));
}
body[data-theme="minimal"] .legend-marker {
  background: var(--theme-accent);
  box-shadow: none;
}
body[data-theme="minimal"] .legend-marker.set {
  background: rgba(15, 12, 31, 0.55);
  box-shadow: none;
}

/* Day strip: flat tiles, sharp small radius, no gradient bar. */
body[data-theme="minimal"] .day {
  background: rgba(15, 12, 31, 0.03);
  border: 1.5px solid var(--card-minimal-line);
  border-radius: 6px;
}
body[data-theme="minimal"] .day.today {
  background: var(--theme-accent);
  border-color: var(--theme-accent);
  box-shadow: none;
}
body[data-theme="minimal"] .day.today .d-label,
body[data-theme="minimal"] .day.today .d-hi,
body[data-theme="minimal"] .day.today .d-lo,
body[data-theme="minimal"] .day.today .d-cond { color: #f7f4ed; }
body[data-theme="minimal"] .day .d-label {
  color: rgba(15, 12, 31, 0.55);
  font-weight: 700;
}
body[data-theme="minimal"] .day .d-hi { color: var(--theme-ink); font-family: var(--sans); font-weight: 600; }
body[data-theme="minimal"] .day .d-bar {
  background: rgba(15, 12, 31, 0.12);
  border-radius: 0;
  height: 3px;
}
body[data-theme="minimal"] .day .d-bar::after {
  background: var(--theme-accent);
  box-shadow: none;
  border-radius: 0;
  width: 6px;
  height: 6px;
}
body[data-theme="minimal"] .day.today .d-bar { background: rgba(247, 244, 237, 0.32); }
body[data-theme="minimal"] .day.today .d-bar::after { background: #f7f4ed; }

/* Take cells: flat, sharp, no fancy gradient. */
body[data-theme="minimal"] .take-cell {
  background: rgba(15, 12, 31, 0.025);
  border: 1.5px solid var(--card-minimal-line);
  border-radius: 6px;
}
body[data-theme="minimal"] .feels-cell {
  background: var(--theme-accent);
  border-color: var(--theme-accent);
}
body[data-theme="minimal"] .feels-cell .cell-lab,
body[data-theme="minimal"] .feels-cell .cell-detail {
  color: rgba(247, 244, 237, 0.78);
}
body[data-theme="minimal"] .feels-cell .cell-val,
body[data-theme="minimal"] .feels-cell .cell-val em { color: #f7f4ed; }
body[data-theme="minimal"] .feels-cell .cell-ico {
  background: rgba(247, 244, 237, 0.18);
  color: #f7f4ed;
}

/* Other cell icons: flat indigo on light, no soft tones */
body[data-theme="minimal"] .cell-ico {
  background: rgba(15, 12, 31, 0.08);
  color: var(--theme-accent);
  border-radius: 4px;
}
body[data-theme="minimal"] .cell-ico-gold,
body[data-theme="minimal"] .cell-ico-coral,
body[data-theme="minimal"] .cell-ico-plum {
  background: rgba(15, 12, 31, 0.08);
  color: var(--theme-accent);
}
body[data-theme="minimal"] .cell-lab {
  color: var(--theme-ink);
  font-weight: 700;
  letter-spacing: 0.24em;
}
body[data-theme="minimal"] .cell-val,
body[data-theme="minimal"] .cell-val em {
  color: var(--theme-ink);
  font-family: var(--sans);
  font-weight: 600;
  font-style: normal;
}

/* Take headline: BOLD sans, not italic serif — woodblock graphic. */
body[data-theme="minimal"] .take-headline {
  font-family: var(--sans);
  font-style: normal;
  font-weight: 700;
  color: var(--theme-ink);
  letter-spacing: -0.005em;
  line-height: 1.18;
}
body[data-theme="minimal"] .take-headline em {
  font-style: normal;
  color: var(--theme-accent);
  font-weight: 800;
}
body[data-theme="minimal"] .take-sub { color: rgba(15, 12, 31, 0.7); }
body[data-theme="minimal"] .take-sub strong { color: var(--theme-accent); font-weight: 700; }

/* Chat: square-ish bubbles, indigo user pill */
body[data-theme="minimal"] .msg {
  border-radius: 4px;
  font-family: var(--sans);
}
body[data-theme="minimal"] .msg.user {
  background: var(--theme-accent);
  color: #f7f4ed;
  font-weight: 500;
}
body[data-theme="minimal"] .msg.assistant {
  background: rgba(15, 12, 31, 0.04);
  border: 1px solid var(--card-minimal-line);
  color: var(--theme-ink);
}
body[data-theme="minimal"] .chat-form input {
  border-radius: 6px;
  border-color: var(--card-minimal-line);
  background: rgba(15, 12, 31, 0.03);
}
body[data-theme="minimal"] .chat-form input:focus {
  border-color: var(--theme-accent);
  box-shadow: 0 0 0 3px rgba(26, 53, 102, 0.18);
}
body[data-theme="minimal"] .chat-form button {
  background: var(--theme-accent);
  color: #f7f4ed;
  border-radius: 6px;
}
body[data-theme="minimal"] .chat-log:empty::after {
  font-family: var(--sans);
  font-style: normal;
  color: rgba(15, 12, 31, 0.55);
}

/* Scenario chips: flat indigo, sharper corners */
body[data-theme="minimal"] .scenario {
  background: rgba(26, 53, 102, 0.08);
  border-color: rgba(26, 53, 102, 0.22);
  border-radius: 4px;
}
body[data-theme="minimal"] .scenario .ico {
  background: var(--theme-accent);
  color: #f7f4ed;
  border-radius: 4px;
}
body[data-theme="minimal"] .scenario .lab {
  color: var(--theme-ink);
  font-weight: 600;
}
body[data-theme="minimal"] .scenario .sub {
  color: rgba(15, 12, 31, 0.55);
  font-weight: 700;
}
body[data-theme="minimal"] .scenario.tone-warm,
body[data-theme="minimal"] .scenario.tone-positive,
body[data-theme="minimal"] .scenario.tone-coral,
body[data-theme="minimal"] .scenario.tone-warn,
body[data-theme="minimal"] .scenario.tone-plum {
  background: rgba(26, 53, 102, 0.08);
  border-color: rgba(26, 53, 102, 0.22);
}
body[data-theme="minimal"] .scenario.tone-warm .ico,
body[data-theme="minimal"] .scenario.tone-positive .ico,
body[data-theme="minimal"] .scenario.tone-coral .ico,
body[data-theme="minimal"] .scenario.tone-warn .ico,
body[data-theme="minimal"] .scenario.tone-plum .ico {
  background: var(--theme-accent);
  color: #f7f4ed;
}

/* Kit chips (Task 8, was "outfit pills"): square corners + ink border */
body[data-theme="minimal"] .kit-chip {
  background: rgba(15, 12, 31, 0.04);
  border: 1px solid var(--card-minimal-line);
  border-radius: 4px;
  color: var(--theme-ink);
}
body[data-theme="minimal"] .kit-chip svg { color: var(--theme-accent); }

/* Headline: bold sans (graphic print), not italic serif */
body[data-theme="minimal"] .headline {
  font-family: var(--sans);
  font-style: normal;
  font-weight: 700;
  letter-spacing: 0.005em;
  color: #fff5e8;
  text-shadow: 0 2px 6px rgba(0, 0, 0, 0.85), 0 1px 1px rgba(0, 0, 0, 0.95);
}
body[data-theme="minimal"][data-time-scene="day"] .headline,
body[data-theme="minimal"][data-time-scene="dawn"] .headline,
body[data-theme="minimal"][data-time-scene="golden-hour"] .headline {
  color: #0f0c1f;
  text-shadow: 0 1px 2px rgba(255, 255, 255, 0.7);
}
body[data-theme="minimal"] .headline-marks { color: rgba(255, 245, 232, 0.45); }
body[data-theme="minimal"][data-time-scene="day"] .headline-marks,
body[data-theme="minimal"][data-time-scene="dawn"] .headline-marks,
body[data-theme="minimal"][data-time-scene="golden-hour"] .headline-marks {
  color: rgba(15, 12, 31, 0.4);
}

/* Hero meta: keep mono numbers crisp, no italic gold */
body[data-theme="minimal"] .meta-condition {
  font-family: var(--sans);
  font-style: normal;
  font-weight: 500;
}
body[data-theme="minimal"] .temp-meta .feels-val {
  font-family: var(--sans);
  font-style: normal;
  font-weight: 600;
}
body[data-theme="minimal"] .temp-unit {
  font-family: var(--sans);
  font-style: normal;
  font-weight: 600;
}

/* Unit toggle + city trigger active: indigo, no glow */
body[data-theme="minimal"] .unit-toggle button.active {
  background: var(--theme-accent);
  color: #f7f4ed;
  box-shadow: none;
  border-radius: 6px;
}
body[data-theme="minimal"] .unit-toggle {
  border-radius: 8px;
}
body[data-theme="minimal"] .city-trigger { border-radius: 6px; }

/* Theme-picker active pill in the city sheet: indigo flat */
body[data-theme="minimal"] .theme-picker button {
  border-radius: 4px;
}
body[data-theme="minimal"] .theme-picker button.active {
  background: var(--theme-accent);
  border-color: var(--theme-accent);
  color: #f7f4ed;
}

/* Footer: ink instead of cream subtle */
body[data-theme="minimal"] .footer-row,
body[data-theme="minimal"] .footer-privacy { color: rgba(15, 12, 31, 0.62); }
body[data-theme="minimal"] .footer-row a { color: var(--theme-ink); }
body[data-theme="minimal"] .footer-row a:hover { color: var(--theme-accent); }

/* Hover tip (chart): indigo background instead of dark cream-tinted */
body[data-theme="minimal"] .hover-tip {
  background: var(--theme-ink);
  border-color: rgba(247, 244, 237, 0.18);
  border-radius: 4px;
  color: #f7f4ed;
}
body[data-theme="minimal"] .hover-tip .time { color: #f7f4ed; font-family: var(--sans); font-style: normal; }
body[data-theme="minimal"] .hover-tip .val.gold { color: #f7f4ed; }

/* Painterly hover tip: warm terracotta tint */

/* ─────────────────────────────────────────────────────────
   CARD INNER BG VARIANT for cards-row layout
   The base CSS sets .card-inner cells on take-cell + day to a single
   shade. Each theme above already overrides; this is just a safety
   note that all theme cells inherit their parent .card's background
   layering — keep card padding ≥ inner radius so painterly's noise
   layer doesn't get clipped at the corners. (None of this needs CSS
   here; comment-only.) */
