/* Retro pixel-art theme: palette, typography, sprite colours, and the
   dithered surfaces that hold the whole page together.

   Palette is a 16-colour retro set. Every surface/ink pair below was chosen to
   clear WCAG AA at the size it is used, because VS-006 says decoration must
   never win over legibility. */

@font-face {
  font-family: 'Press Start 2P';
  src: url('../assets/fonts/press-start-2p.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  /* swap: the monospace fallback is already the right shape, so showing text
     immediately beats a blank flash. */
  font-display: swap;
}

:root {
  /* Surfaces */
  --bg: #1a1c2c;
  --bg-panel: #29366f;
  --bg-panel-lit: #3b5dc9;
  --edge-light: #41a6f6;
  --edge-dark: #100f1c;

  /* Ink */
  --ink: #f4f4f4;
  --ink-dim: #94b0c2;
  --ink-accent: #ffcd75;

  /* Sprite palette */
  --sun: #ffcd75;
  --cloud: #f4f4f4;
  --cloud-dark: #94b0c2;
  --rain: #41a6f6;
  --snow: #ffffff;
  --bolt: #ffcd75;
  --fog: #94b0c2;

  /* Semantic */
  --today: #38b764;
  --warn: #ef7d57;

  --pixel: 'Press Start 2P', ui-monospace, monospace;
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

/* --- Page ---------------------------------------------------------------- */

body {
  background-color: var(--bg);
  /* Dithered starfield-ish texture, built from repeating gradients rather than
     an image asset. Two offset grids read as a 2x2 Bayer dither. */
  background-image:
    repeating-linear-gradient(
      45deg,
      rgba(65, 166, 246, 0.05) 0 2px,
      transparent 2px 4px
    ),
    repeating-linear-gradient(
      -45deg,
      rgba(255, 205, 117, 0.04) 0 2px,
      transparent 2px 4px
    );
  color: var(--ink);
  font-family: var(--mono);
  line-height: 1.5;
  min-height: 100vh;
}

/* --- Sprites ------------------------------------------------------------- */

.sprite-defs {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

.sprite {
  width: 3rem;
  height: 3rem;
  /* Belt and braces: the rects are vector geometry so they scale crisply, but
     if anything does rasterise, keep the edges hard (VS-002). */
  image-rendering: pixelated;
  shape-rendering: crispEdges;
}

.s-sun {
  fill: var(--sun);
}
.s-cloud {
  fill: var(--cloud);
}
.s-cloud-dark {
  fill: var(--cloud-dark);
}
.s-rain {
  fill: var(--rain);
}
.s-snow {
  fill: var(--snow);
}
.s-bolt {
  fill: var(--bolt);
}
.s-fog {
  fill: var(--fog);
}
.s-muted {
  fill: var(--ink-dim);
}

/* --- Typography ---------------------------------------------------------- */

.masthead__title {
  font-family: var(--pixel);
  color: var(--ink-accent);
  /* The pixel font has very wide metrics; loosen tracking rather than let it
     crowd at small sizes. */
  letter-spacing: 0.02em;
  text-shadow: 2px 2px 0 var(--edge-dark);
}

.masthead__location {
  font-family: var(--pixel);
  font-size: 0.6rem;
  color: var(--ink);
}

.masthead__subtitle,
.day__date,
.day__condition,
.freshness,
.colophon {
  color: var(--ink-dim);
}

.day__weekday {
  font-family: var(--pixel);
  color: var(--ink);
}

.day__temp--max {
  color: var(--ink-accent);
  font-weight: 700;
}

.day__temp--min {
  color: var(--ink-dim);
}

/* --- Day cards ----------------------------------------------------------- */

.day {
  background: var(--bg-panel);
  /* Hard 2px edges, no radius, no blur — the pixel-art idiom has no curves. */
  border: 2px solid var(--edge-dark);
  box-shadow: inset -2px -2px 0 rgba(16, 15, 28, 0.5), inset 2px 2px 0 rgba(65, 166, 246, 0.25);
}

.day--today {
  background: var(--bg-panel-lit);
  border-color: var(--today);
}

.day--today .day__weekday {
  /* Not --today green: at 2.26:1 against the lit panel it fails WCAG AA.
     The green earns its keep on the border instead, where it scores 6.52:1
     against the page background. The card is already labelled "Today", so the
     marker never depends on colour alone. */
  color: var(--snow);
}

.day--empty {
  background: transparent;
  border-style: dashed;
  border-color: var(--ink-dim);
  opacity: 0.75;
}

/* --- Loading, error, and notice panels ----------------------------------- */
/* Styled in the same idiom so no state falls back to browser defaults (VS-005) */

.panel {
  background: var(--bg-panel);
  border: 2px solid var(--edge-dark);
  box-shadow: inset -2px -2px 0 rgba(16, 15, 28, 0.5), inset 2px 2px 0 rgba(65, 166, 246, 0.25);
}

.panel__art {
  font-family: var(--pixel);
  color: var(--ink-accent);
}

.panel--loading .panel__art {
  animation: pixel-blink 1s steps(2, end) infinite;
}

.panel--error .panel__art {
  color: var(--warn);
  animation: none;
}

.panel__message {
  font-family: var(--pixel);
  line-height: 1.9;
}

.panel__hint {
  color: var(--ink-dim);
}

.notice {
  background: var(--bg-panel);
  border: 2px dashed var(--warn);
  color: var(--ink);
}

@keyframes pixel-blink {
  0%,
  50% {
    opacity: 1;
  }
  51%,
  100% {
    opacity: 0.25;
  }
}

@media (prefers-reduced-motion: reduce) {
  .panel--loading .panel__art {
    animation: none;
  }
}

/* --- Links --------------------------------------------------------------- */

.colophon a {
  color: var(--edge-light);
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
}

.colophon a:hover,
.colophon a:focus-visible {
  color: var(--ink-accent);
}

:focus-visible {
  outline: 2px solid var(--ink-accent);
  outline-offset: 2px;
}

/* --- Selected-day detail -------------------------------------------------- */
/* Same idiom as the day cards: hard edges, no radius, no gradient (VS-002). */

.detail {
  background: var(--bg-panel);
  border: 2px solid var(--edge-dark);
  box-shadow: inset -2px -2px 0 rgba(16, 15, 28, 0.5), inset 2px 2px 0 rgba(65, 166, 246, 0.25);
}

.detail__heading {
  font-family: var(--pixel);
  color: var(--ink-accent);
}

.detail__label {
  color: var(--ink-dim);
}

.detail__value {
  color: var(--ink);
  font-weight: 700;
}

/* A hard 2px rule between rows rather than a hairline — a 1px border would
   render as a grey blur on a scaled display and break the pixel idiom. */
.detail__row + .detail__row {
  border-top: 2px solid var(--edge-dark);
}

/* At exactly three columns (pinned in layout.css at 48rem), items 1, 4 and 7
   are the top of each column and must not carry a rule above them. */
@media (min-width: 48rem) {
  .detail__row:nth-child(3n + 1) {
    border-top: 0;
  }
}

.detail__empty {
  color: var(--ink-dim);
}

/* --- Day controls and selection ------------------------------------------ */

.day {
  /* The card is a button now; strip the UA chrome the pixel styling replaces. */
  width: 100%;
  font: inherit;
  color: inherit;
  text-align: inherit;
  cursor: pointer;
  appearance: none;
}

/* The selected day is marked three ways so it never depends on colour alone
   (VS-003): a lit panel, a thicker bright edge, and a caret in the gutter. */
.day--selected {
  background: var(--bg-panel-lit);
  border-color: var(--edge-light);
  box-shadow:
    inset -2px -2px 0 rgba(16, 15, 28, 0.5),
    inset 2px 2px 0 rgba(244, 244, 244, 0.35),
    0 0 0 2px var(--edge-light);
}

.day--selected .day__weekday {
  color: var(--snow);
}

/* A chunky pixel caret, drawn with a character rather than a border so it
   reads as a marker and not as decoration (VS-001). */
.day--selected .day__header::before {
  content: '\25B8';
  color: var(--ink-accent);
  margin-right: 0.35rem;
}

/* An unavailable day stays selectable, so it still shows a selected state —
   it just keeps its dashed edge to signal it has nothing to show. */
.day--empty.day--selected {
  background: var(--bg-panel);
  border-style: dashed;
  border-color: var(--edge-light);
  opacity: 1;
}

/* A day control's focus ring must survive the lit selected background, so it
   is drawn as a hard offset outline rather than a colour change (FR-013). The
   global :focus-visible rule above gives the accent outline; this thickens it
   on the cards, where a 2px ring is lost against the 2px card border. */
.day:focus-visible {
  outline: 3px solid var(--ink-accent);
  outline-offset: 3px;
  /* Keep the ring readable when the card behind it is already lit. */
  box-shadow: inset -2px -2px 0 rgba(16, 15, 28, 0.5), inset 2px 2px 0 rgba(244, 244, 244, 0.35);
}
