/* Liberty Flyers field conditions
   Palette taken from the field itself: pre-dawn sky, asphalt, runway markings,
   and the windsock, which is the one thing on a flying field that is already
   orange by international agreement. */

:root {
  --sky-deep:  #0E1621;
  --sky-mid:   #172533;
  --sky-line:  #23394E;
  --asphalt:   #2B3947;
  --sock:      #FF6B1A;
  --marking:   #F2F5F7;
  --cool:      #7EC8DB;
  --muted:     #7D93A8;
  --amber:     #FFB020;
  --alarm:     #FF5A52;

  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, "Roboto Mono", monospace;
  --sans: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

  --gap: 14px;
  --pad: 18px;
  --radius: 10px;
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--sky-deep);
  color: var(--marking);
  font-family: var(--sans);
  font-size: 15px;
  line-height: 1.5;
  padding-bottom: env(safe-area-inset-bottom);
  -webkit-font-smoothing: antialiased;
}

/* ---------- header ---------- */

.bar {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px var(--pad);
  padding-top: calc(12px + env(safe-area-inset-top));
  background: rgba(14, 22, 33, 0.92);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--sky-line);
}

.bar__name {
  margin: 0;
  font-family: var(--mono);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.bar__sub {
  margin: 1px 0 0;
  font-size: 11px;
  color: var(--muted);
  letter-spacing: 0.04em;
}

.age {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 5px 10px 5px 8px;
  border: 1px solid var(--sky-line);
  border-radius: 100px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  white-space: nowrap;
  color: var(--muted);
}

.age__dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: currentColor;
  flex: none;
}

.age[data-state="live"]  { color: var(--sock); border-color: rgba(255,107,26,0.4); }
.age[data-state="stale"] { color: var(--amber); border-color: rgba(255,176,32,0.4); }
.age[data-state="dead"]  { color: var(--alarm); border-color: rgba(255,90,82,0.45); }

.age[data-state="live"] .age__dot { animation: pulse 2.6s ease-in-out infinite; }

@keyframes pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.25; }
}

/* ---------- layout ---------- */

.stack {
  display: flex;
  flex-direction: column;
  gap: var(--gap);
  padding: var(--gap) var(--pad) 32px;
  max-width: 1120px;
  margin: 0 auto;
}

.eyebrow {
  margin: 0 0 10px;
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--muted);
}

.eyebrow__thin {
  letter-spacing: 0.1em;
  opacity: 0.65;
  text-transform: none;
}

/* shared panel look */
.wind, .rwy, .chart, .cell, .env {
  background: var(--sky-mid);
  border: 1px solid var(--sky-line);
  border-radius: var(--radius);
  padding: var(--pad);
}

/* ---------- hero ---------- */

.hero { margin: 0; }

.hero__frame {
  position: relative;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border-radius: var(--radius);
  border: 1px solid var(--sky-line);
  background: var(--asphalt);
}

.hero__media {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.hero__media--hidden { opacity: 0; pointer-events: none; }

.hero__scrim {
  position: absolute;
  inset: auto 0 0 0;
  height: 45%;
  background: linear-gradient(to top, rgba(8,13,20,0.85), transparent);
  pointer-events: none;
}

.hero__bar {
  position: absolute;
  inset: auto 0 0 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 12px;
}

.hero__stamp {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  color: var(--marking);
  text-shadow: 0 1px 3px rgba(0,0,0,0.8);
}

.tl {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 13px 7px 11px;
  border: 1px solid rgba(242,245,247,0.35);
  border-radius: 100px;
  background: rgba(8,13,20,0.6);
  backdrop-filter: blur(8px);
  color: var(--marking);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  cursor: pointer;
}

.tl:hover { border-color: var(--sock); }

.tl__glyph {
  width: 0;
  height: 0;
  border-left: 8px solid var(--sock);
  border-top: 5px solid transparent;
  border-bottom: 5px solid transparent;
}

.tl[aria-pressed="true"] .tl__glyph {
  border: 0;
  width: 8px;
  height: 9px;
  background: var(--sock);
  box-shadow: inset 2.5px 0 0 var(--sky-deep), inset -2.5px 0 0 var(--sky-deep);
}

.hero__note {
  margin: 8px 0 0;
  font-size: 12px;
  color: var(--amber);
}

/* ---------- wind ---------- */

.wind__row {
  display: flex;
  align-items: baseline;
  gap: 14px;
  flex-wrap: wrap;
}

.wind__val {
  font-family: var(--mono);
  font-size: clamp(56px, 17vw, 84px);
  font-weight: 500;
  line-height: 0.85;
  letter-spacing: -0.04em;
  font-variant-numeric: tabular-nums;
  color: var(--sock);
}

.wind__meta {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.wind__unit {
  font-family: var(--mono);
  font-size: 15px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}

.wind__from {
  font-family: var(--mono);
  font-size: 17px;
  letter-spacing: 0.03em;
  font-variant-numeric: tabular-nums;
}

.wind__gust {
  margin: 14px 0 0;
  font-family: var(--mono);
  font-size: 13px;
  letter-spacing: 0.06em;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

/* ---------- runway ---------- */

.rwy__svg {
  display: block;
  width: 100%;
  height: auto;
  margin: 2px 0 4px;
  overflow: visible;
}

.rwy__rose circle {
  fill: none;
  stroke: var(--sky-line);
  stroke-width: 1;
  stroke-dasharray: 2 6;
}

.rwy__rose text {
  fill: var(--muted);
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.12em;
}

.rwy__pave   { fill: var(--asphalt); }
.rwy__centre { stroke: var(--marking); stroke-width: 2; stroke-dasharray: 16 12; opacity: 0.5; }
.rwy__thresh rect { fill: var(--marking); opacity: 0.7; }

.rwy__num {
  fill: var(--marking);
  font-family: var(--mono);
  font-size: 17px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-anchor: middle;
  dominant-baseline: central;
  opacity: 0.85;
}

.rwy__hub { fill: var(--marking); }

.leg { fill: none; stroke-width: 2.25; }
/* Backing line, so a leg stays readable where it runs over the centreline. */
.leg--halo  { stroke: var(--sky-deep); stroke-width: 5.5; opacity: 0.9; }
/* Dash rhythms differ from the centreline's, so the legs never read as paint. */
.leg--head  { stroke: var(--cool); stroke-dasharray: 5 3; }
.leg--cross { stroke: var(--sock); stroke-dasharray: 5 3; }

.vec line    { stroke: var(--sock); stroke-width: 4; stroke-linecap: round; }
.vec polygon { fill: var(--sock); }

.vec, .leg {
  transition: all 700ms cubic-bezier(0.22, 1, 0.36, 1);
}

.comp {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  margin: 14px 0 0;
  background: var(--sky-line);
  border: 1px solid var(--sky-line);
  border-radius: 8px;
  overflow: hidden;
}

.comp__cell {
  background: var(--sky-mid);
  padding: 11px 10px;
  min-width: 0;
}

.comp dt {
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}

.comp dd {
  margin: 4px 0 0;
  font-family: var(--mono);
  font-size: 21px;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}

.comp__cell--hot dd { color: var(--sock); }
.comp__cell--hot .comp__sub { color: var(--muted); }

.comp .comp__sub {
  font-size: 10px;
  letter-spacing: 0.06em;
  color: var(--muted);
  margin-top: 2px;
}

.rwy__ref {
  margin: 12px 0 0;
  font-size: 11.5px;
  line-height: 1.45;
  color: var(--muted);
}

/* ---------- conditions grid ---------- */

.grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--gap);
}

.cell__val {
  margin: 0;
  font-family: var(--mono);
  font-size: 27px;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
}

/* ---------- chart ---------- */

.chart__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
}

.key {
  margin: 0 0 10px;
  display: flex;
  gap: 12px;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}

.key__item { display: inline-flex; align-items: center; gap: 5px; }

.key__item::before {
  content: "";
  width: 12px;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
}

.key__item--wind { color: var(--sock); }
.key__item--gust { color: var(--sock); opacity: 0.55; }
.key__item--temp { color: var(--cool); }

#chart { display: block; width: 100%; height: 200px; }

.chart__empty {
  margin: 0;
  padding: 40px 0;
  text-align: center;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}

/* ---------- footer ---------- */

.foot {
  margin-top: 4px;
  padding: var(--pad);
  border: 1px solid var(--sky-line);
  border-left: 3px solid var(--amber);
  border-radius: var(--radius);
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--muted);
}

.foot p { margin: 0 0 9px; }
.foot p:last-child { margin-bottom: 0; }

.foot__warn {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--amber);
}

.foot__meta { font-size: 11.5px; opacity: 0.8; }

/* ---------- wider screens ---------- */

@media (min-width: 900px) {
  .stack {
    display: grid;
    grid-template-columns: 1.35fr 1fr;
    align-items: start;
  }
  /* aqi-layout-v2: `align-items: start` above keeps the hero from being
     stretched past its aspect ratio, so the cards that SHOULD absorb the
     leftover height in column 1 have to ask for it individually. */
  .hero  { grid-column: 1; grid-row: 1; align-self: start; }
  .env   { grid-column: 1; grid-row: 2; align-self: stretch; }
  .wind  { grid-column: 2; grid-row: 1; align-self: stretch; }  /* wind-stretch-v3 */
  .rwy   { grid-column: 2; grid-row: 2 / span 2; }
  .grid  { grid-column: 1; grid-row: 3; grid-template-columns: repeat(4, 1fr);
           align-self: stretch; }
  .chart { grid-column: 1 / -1; }
  .foot  { grid-column: 1 / -1; }
  #chart { height: 240px; }
}

/* ---------- accessibility floor ---------- */

:focus-visible {
  outline: 2px solid var(--sock);
  outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}


/* ---------- air quality (aqi-card-v1) ---------- */

/* Panel chrome comes from the shared .wind/.rwy/.chart/.cell rule above; this
   block only adds what is specific to the reading itself. */
.env__half--aqi {
  /* EPA category colour, overwritten by app.js via the data-cat attribute */
  --aqi: var(--muted);
}

.aqi__row {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  margin-top: 0.15rem;
}

.aqi__val {
  font-size: clamp(2.6rem, 9vw, 4rem);
  line-height: 0.95;
  font-variant-numeric: tabular-nums;
  color: var(--aqi);
}

.aqi__meta {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
}

.aqi__unit {
  font-size: 0.78rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  opacity: 0.62;
}

.aqi__cat {
  font-size: 0.98rem;
  color: var(--aqi);
}

.aqi__conc,
.aqi__src {
  margin: 0.35rem 0 0;
  font-size: 0.78rem;
  opacity: 0.58;
}

.aqi__src { opacity: 0.42; }

/* A reading we no longer trust: drain the colour rather than hide the number,
   so a stale panel reads as obviously stale instead of quietly wrong. */
.env__half--aqi[data-stale="1"] { --aqi: var(--amber); }
.env__half--aqi[data-stale="1"] .aqi__val { opacity: 0.55; }

.env__half--aqi[data-cat="good"]      { --aqi: #6FCF7C; }
.env__half--aqi[data-cat="moderate"]  { --aqi: #E8D44D; }
.env__half--aqi[data-cat="usg"]       { --aqi: #F2994A; }
.env__half--aqi[data-cat="unhealthy"] { --aqi: #FF5A52; }
.env__half--aqi[data-cat="very"]      { --aqi: #C77DFF; }
.env__half--aqi[data-cat="hazard"]    { --aqi: #D4707A; }


/* ---------- layout balance (aqi-layout-v2) ---------- */

@media (min-width: 900px) {
  /* Once the card is taller than its contents, centre them rather than
     leaving the number stranded at the top of a tall empty panel. */
  .env__half {
    justify-content: center;
  }

  /* The stat tiles stretch with their row, so centre each value too. */
  .grid .cell {
    display: flex;
    flex-direction: column;
    justify-content: center;
  }
}


/* ---------- wind card fills row 1 (wind-stretch-v3) ---------- */

@media (min-width: 900px) {
  /* The hero sets the height of row 1. Rather than leave the wind reading
     stranded at the top of a tall panel, centre it the way .aqi is centred. */
  .wind {
    display: flex;
    flex-direction: column;
    justify-content: center;
  }

  /* The eyebrow is a label for the card, not part of the centred group, so
     pin it to the top and let the reading centre in what is left. */
  .wind > .eyebrow {
    position: absolute;
    top: var(--pad);
    left: var(--pad);
  }
  .wind { position: relative; }
}


/* ---------- unit toggle in the header (units-v1) ---------- */

.bar__right {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

/* units.js injects its own baseline styles into <head>, which lands after
   this stylesheet. Two classes beat its one, so these win without !important
   and units.js stays a drop-in file with no edits. */
.bar .unit-toggle {
  border: 1px solid var(--sky-line);
  border-radius: 100px;
  background: transparent;
  flex: none;
}

.bar .unit-toggle button {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: lowercase;
  padding: 5px 9px;
  color: var(--muted);
  opacity: 1;
}

.bar .unit-toggle button:hover { color: var(--marking); }

.bar .unit-toggle button[aria-pressed="true"] {
  background: var(--sky-line);
  color: var(--sock);
}

@media (max-width: 380px) {
  .bar { gap: 8px; }
  .bar__right { gap: 6px; }
  .bar .unit-toggle button { padding: 5px 7px; }
  .bar__sub { display: none; }
}


/* ---------- air quality + daylight, one box (env-box-v1) ---------- */

/* Panel chrome comes from the shared .wind/.rwy/.chart/.cell rule above.
   The halves sit side by side with a hairline between them, and either can
   be hidden on its own, in which case the survivor takes the full width. */
.env {
  display: flex;
  flex-direction: row;
  gap: var(--pad);
  align-items: stretch;
}

.env__half {
  display: flex;
  flex-direction: column;
  flex: 1 1 0;
  min-width: 0;
}

.env[data-halves="2"] .env__half--sun {
  padding-left: var(--pad);
  border-left: 1px solid var(--sky-line);
}

/* Stack the halves on a phone; the divider becomes a rule between them. */
@media (max-width: 560px) {
  .env { flex-direction: column; gap: 0; }
  .env[data-halves="2"] .env__half--sun {
    padding-left: 0;
    border-left: 0;
    margin-top: var(--pad);
    padding-top: var(--pad);
    border-top: 1px solid var(--sky-line);
  }
}


/* ---------- daylight half ---------- */

.sun {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 7px;
}

.sun__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}

.sun__row dt {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}

.sun__row dd {
  margin: 0;
  font-family: var(--mono);
  font-size: 21px;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
  color: var(--marking);
}

/* Last light is context for sunset, not a peer of it. */
.sun__row--sub dd {
  font-size: 15px;
  color: var(--muted);
}

.sun__note {
  margin: 12px 0 0;
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.04em;
  color: var(--sock);
}

/* Once the sun is down there is nothing urgent to say, so drop the accent. */
.sun__note[data-phase="night"] { color: var(--muted); }
.sun__note[data-phase="dusk"]  { color: var(--amber); }


/* ---------- hidden must actually hide (env-hide-fix) ---------- */

/* The hidden attribute works through a UA rule of display: none, and ANY
   author rule beats the UA sheet regardless of specificity. So the
   display: flex above quietly defeated it, and a half with no data rendered
   as an empty column of dashes. Attribute plus class outranks the bare
   class, so these win without !important.

   The same trap was already in the layout media query on the old .aqi card,
   where display: flex meant a PurpleAir outage left an empty panel on
   desktop rather than hiding it. */
.env[hidden],
.env__half[hidden] { display: none; }

/* hidden must beat display:flex (env-hide-fix) */
.env[hidden],
.env__half[hidden] { display: none; }
