/* ═══════════════════════════════════════════════════════════════════════
   AvioWeather — web replica of the iOS Home AirportCard
   Source of truth: ios/AVMet/DesignSystem/Components/Components.swift
   (struct AirportCard + FlightCategoryBadge + MetricTile + infobar leaves)
   and ios/AVMet/DesignSystem/{Colors,EditorialKit}.swift — LIGHT palette
   (the site is light-only). Every dimension below maps 1:1 pt→px to the
   SwiftUI values (sole exception: the shadow blur, where the SwiftUI
   radius is a Gaussian sigma ≈ half the CSS blur, so 10 → 20px);
   comments reference the Swift token it mirrors.
   Loaded by: index.html (root + en/de/es/fr) and login.html.
   Rendered/updated by /assets/live-metar.js (self-mounts on
   [data-avx-metar]; static snapshot markup ships in the HTML for SEO/no-JS).
   ═══════════════════════════════════════════════════════════════════════ */

.avx-card {
  /* Category accent — set per flight category, mirrors AVMetColors.forCategory
     + categoryBorder (30% opacity perimeter hairline). */
  --avx-cat: #2d8559;
  --avx-cat-border: rgba(45, 133, 89, 0.3);
  /* iOS system text colors: Color(.label) / Color(.secondaryLabel) in light. */
  --avx-label: #000000;
  --avx-label2: rgba(60, 60, 67, 0.6);
  /* Editorial.hairlineStrong = #0A0A0A @ 18% */
  --avx-hairline: rgba(10, 10, 10, 0.18);
  /* AVMetColors.accentBlue light */
  --avx-accent: #1d3a8a;
  /* SF Pro on Apple hardware (identical to the iPhone card), graceful
     system-sans elsewhere; Geist is the site fallback of last resort. */
  --avx-sans: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Helvetica Neue', 'Segoe UI', Roboto, 'Geist', sans-serif;
  /* SF Mono on Apple hardware (design: .monospaced), Geist Mono fallback. */
  --avx-mono: ui-monospace, 'SF Mono', SFMono-Regular, Menlo, 'Geist Mono', monospace;
  /* design: .rounded (hazard chip) */
  --avx-rounded: ui-rounded, 'SF Pro Rounded', -apple-system, BlinkMacSystemFont, 'Geist', sans-serif;

  /* Card shell — Editorial.bgCard #FFFFFF, AVMetRadius.card 16,
     padding .horizontal AVMetSpacing.l=24 / .vertical cardPadding=18,
     shadow light: black 5%, radius 10 (≈20px CSS blur), y 4. */
  position: relative;
  width: 100%;
  background: #ffffff;
  border: 1px solid var(--avx-cat-border);
  border-radius: 16px;
  padding: 18px 24px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.05);
  /* Outer VStack(spacing: AVMetSpacing.sectionGap = 24) */
  display: flex;
  flex-direction: column;
  gap: 24px;
  font-family: var(--avx-sans);
  color: var(--avx-label);
  text-align: left;
  -webkit-font-smoothing: antialiased;
}
.avx-card, .avx-card * { box-sizing: border-box; min-width: 0; }

/* Category variants (AVMetColors: vfr/mvfr/ifr/lifr/noData) */
.avx-card.cat-vfr     { --avx-cat: #2d8559; --avx-cat-border: rgba(45, 133, 89, 0.3); }
.avx-card.cat-mvfr    { --avx-cat: #1d3a8a; --avx-cat-border: rgba(29, 58, 138, 0.3); }
.avx-card.cat-ifr     { --avx-cat: #b91c1c; --avx-cat-border: rgba(185, 28, 28, 0.3); }
.avx-card.cat-lifr    { --avx-cat: #6d28d9; --avx-cat-border: rgba(109, 40, 217, 0.3); }
.avx-card.cat-unknown { --avx-cat: #9aa0a8; --avx-cat-border: rgba(154, 160, 168, 0.3); }

/* ── Header + infobar group: VStack(spacing: groupRelated = 8) ── */
.avx-head-group { display: flex; flex-direction: column; gap: 8px; }

/* Header: HStack(alignment: .top, spacing: 10) */
.avx-header { display: flex; align-items: flex-start; gap: 10px; }

/* Left column: VStack(alignment: .leading, spacing: 6) */
.avx-id { flex: 1 1 auto; display: flex; flex-direction: column; gap: 6px; }

/* ICAO row: HStack(alignment: .firstTextBaseline, spacing: 10) */
.avx-icao-row { display: flex; align-items: baseline; gap: 10px; }

/* ICAO: .system(size: 32, weight: .semibold), tracking -0.8 */
.avx-icao {
  font-size: 32px; font-weight: 600; letter-spacing: -0.8px;
  line-height: 1.06; color: var(--avx-label); white-space: nowrap;
}

/* IATA chip: 11 bold mono, tracking .6, pad 7/3, fill label 8%,
   border 0.6px label 15%, radius AVMetRadius.chip-adjacent 4 */
.avx-iata {
  font-family: var(--avx-mono); font-size: 11px; font-weight: 700;
  letter-spacing: 0.6px; line-height: 1; color: var(--avx-label);
  padding: 3px 7px; background: rgba(0, 0, 0, 0.08);
  border: 0.6px solid rgba(0, 0, 0, 0.15); border-radius: 4px;
  white-space: nowrap;
}
.avx-iata:empty { display: none; }

/* "City · Name": 13 medium, secondaryLabel, lineLimit(1) */
.avx-name {
  font-size: 13px; font-weight: 500; color: var(--avx-label2);
  line-height: 1.3; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* Right column: VStack(alignment: .trailing, spacing: 8) */
.avx-side { flex: 0 0 auto; display: flex; flex-direction: column; align-items: flex-end; gap: 8px; margin-left: 6px; }

/* Hazard chip + category badge: HStack(spacing: 6) */
.avx-badges { display: flex; align-items: center; gap: 6px; }

/* ConvectiveHazardChip: capsule, pad 7/2, glyph 9 bold + label 10 bold rounded, white */
.avx-hazard {
  display: inline-flex; align-items: center; gap: 4px;
  font-family: var(--avx-rounded); font-size: 10px; font-weight: 700;
  line-height: 1.4; color: #ffffff; background: #b91c1c; /* .cb → AVMetColors.ifr */
  padding: 2px 7px; border-radius: 999px; white-space: nowrap;
}
.avx-hazard.is-tcu { background: #c2410c; } /* .tcu → cautionAmber light */
.avx-hazard svg { width: 9px; height: 9px; flex: 0 0 auto; }
.avx-hazard[hidden] { display: none; }

/* FlightCategoryBadge (.solid): 11 semibold mono, tracking .8, white on
   category fill, pad 10/4, radius AVMetRadius.chip = 4 */
.avx-cat {
  font-family: var(--avx-mono); font-size: 11px; font-weight: 600;
  letter-spacing: 0.8px; line-height: 1.4; color: #ffffff;
  background: var(--avx-cat); padding: 4px 10px; border-radius: 4px;
  white-space: nowrap;
}

/* Temp: 24 semibold tracking -.6 tabular + "°C" 12 semibold secondary,
   firstTextBaseline spacing 2 */
.avx-temp { display: flex; align-items: baseline; gap: 2px; }
.avx-temp[hidden] { display: none; }
.avx-temp-v {
  font-size: 24px; font-weight: 600; letter-spacing: -0.6px;
  line-height: 1.1; color: var(--avx-label); font-variant-numeric: tabular-nums;
}
.avx-temp-u { font-size: 12px; font-weight: 600; color: var(--avx-label2); }

/* ── Info bar: HStack(spacing: 6) — local time + METAR age + QNH pill ── */
.avx-infobar { display: flex; align-items: center; gap: 6px; }

/* AirportLocalTimeLabel / METARAgeLabel chips: icon 10 + 11 semibold mono,
   label @78%, pad 7/3, fill label 6%, radius 4 */
.avx-chip {
  display: inline-flex; align-items: center; gap: 4px;
  font-family: var(--avx-mono); font-size: 11px; font-weight: 600;
  line-height: 1.4; color: rgba(0, 0, 0, 0.78);
  padding: 3px 7px; background: rgba(0, 0, 0, 0.06); border-radius: 4px;
  white-space: nowrap;
}
.avx-chip svg { width: 10px; height: 10px; flex: 0 0 auto; }
.avx-chip[hidden] { display: none; }

/* QNH pill: gauge icon @78% + value 13 bold mono + "hPa" 10 semibold mono @70%,
   fill accentBlue 8%, pad 7/3, radius AVMetRadius.chip = 4 */
.avx-qnh {
  /* iOS: HStack(spacing:4){ gauge; HStack(spacing:2){ value; "hPa" } } —
     flat DOM: 2px flex gap everywhere + 2px extra on the icon = 4px icon↔value. */
  margin-left: auto; display: inline-flex; align-items: baseline; gap: 2px;
  padding: 3px 7px; background: rgba(29, 58, 138, 0.08); border-radius: 4px;
  white-space: nowrap;
}
.avx-qnh[hidden] { display: none; }
.avx-qnh svg { width: 10px; height: 10px; flex: 0 0 auto; align-self: center; margin-right: 2px; color: rgba(0, 0, 0, 0.78); }
.avx-qnh-v {
  font-family: var(--avx-mono); font-size: 13px; font-weight: 700;
  line-height: 1.3; color: var(--avx-label); font-variant-numeric: tabular-nums;
}
.avx-qnh-u { font-family: var(--avx-mono); font-size: 10px; font-weight: 600; color: rgba(0, 0, 0, 0.7); }

/* ── Metrics row: 4 MetricTiles + 1px×44 dividers, hairlineStrong top/bottom,
      row padding .vertical 14 / .horizontal 4 ── */
.avx-metrics {
  display: flex; align-items: center; padding: 14px 4px;
  border-top: 1px solid var(--avx-hairline);
  border-bottom: 1px solid var(--avx-hairline);
}
.avx-div { flex: 0 0 auto; width: 1px; height: 44px; background: var(--avx-hairline); }

/* MetricTile: VStack(spacing: 6) — icon 14 semibold accent in 16pt frame,
   value 16 semibold tracking -.2 tabular + unit 10 semibold mono secondary,
   label 10 semibold mono tracking 1.2 secondary */
.avx-tile { flex: 1 1 0; display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 0 2px; }
.avx-tile-ico { height: 16px; display: flex; align-items: center; color: var(--avx-cat); }
.avx-tile-ico svg { width: 14px; height: 14px; }
.avx-tile-val { display: flex; align-items: baseline; gap: 2px; max-width: 100%; }
.avx-tile-val .v {
  font-size: 16px; font-weight: 600; letter-spacing: -0.2px; line-height: 1.2;
  color: var(--avx-label); font-variant-numeric: tabular-nums; white-space: nowrap;
}
.avx-tile-val .u {
  font-family: var(--avx-mono); font-size: 10px; font-weight: 600;
  color: var(--avx-label2); white-space: nowrap;
}
.avx-tile-val .u:empty { display: none; }
.avx-tile-lbl {
  font-family: var(--avx-mono); font-size: 10px; font-weight: 600;
  letter-spacing: 1.2px; color: var(--avx-label2); white-space: nowrap;
}

/* ── RAW METAR expandable section (RawMetarSection) ──
   IDENTICO all'app iPhone (richiesta owner 2026-07-21): il RAW si apre
   DENTRO la card — la card cresce col suo unico bordo categoria, angoli 16px
   invariati, blocco raw dentro il padding della card — su TUTTI i viewport
   (stesso meccanismo grid-rows del mobile, da sempre senza glitch: un solo
   elemento con una sola cornice → niente crossfade di bordi, niente
   giunture → interruzioni del perimetro impossibili).
   Vincolo desktop "la pagina non slitta": il mount [data-avx-metar] ha
   l'altezza BLOCCATA sull'altezza della card CHIUSA (--avx-closed-h,
   misurata da live-metar.js): la card aperta sborda dal mount e si dipinge
   sopra il contenuto seguente (il mount è già stacking context via
   container-type), il layout della pagina non cambia di un pixel.
   Storia: ogni variante "pannello overlay che estende la card" (fino a
   16a8c785) crossfadava due cornici → segmenti di perimetro semitrasparenti
   per un istante; il cassetto-da-dietro (11c51c8e) era glitch-free ma NON
   identico all'app — bocciato dall'owner. */
.avx-card { position: relative; z-index: 1; }
.avx-rawsec { display: flex; flex-direction: column; position: relative; }
.avx-rawbtn {
  display: flex; align-items: center; gap: 6px; width: 100%;
  background: none; border: 0; padding: 0; margin: 0; cursor: pointer;
  font-family: var(--avx-mono); font-size: 10px; font-weight: 700;
  letter-spacing: 1.2px; color: rgba(0, 0, 0, 0.7); text-align: left;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
  -webkit-user-select: none; user-select: none;
  -webkit-touch-callout: none;
}
.avx-rawbtn svg { width: 10px; height: 10px; flex: 0 0 auto; }
/* Chevron rotates 180° on the same reveal clock (AVMetMotion.reveal:
   critically-damped spring response .38 damping .9 ≈ .4s ease-out quint) */
.avx-chev { margin-left: auto; transition: transform 0.4s cubic-bezier(0.33, 1, 0.36, 1); }
.avx-rawbtn[aria-expanded="true"] .avx-chev { transform: rotate(180deg); }

/* RevealLayout (iOS): singola altezza animata 0↔naturale (grid-rows
   0fr↔1fr) dentro la card, su tutti i viewport. */
.avx-reveal {
  display: grid; grid-template-rows: 0fr;
  transition: grid-template-rows 0.4s cubic-bezier(0.33, 1, 0.36, 1);
}
.avx-reveal.open { grid-template-rows: 1fr; }
.avx-reveal > .avx-rawwrap { overflow: hidden; min-height: 0; }

/* rawBlock: 12 medium mono label@85%, pad 12/10, bg Color(white:.96)=#F5F5F5,
   radius AVMetRadius.tile=10, border hairlineStrong; .padding(.top, 8) inside
   the measured child. */
.avx-raw {
  margin: 8px 0 0; font-family: var(--avx-mono); font-size: 12px; font-weight: 500;
  line-height: 1.5; color: rgba(0, 0, 0, 0.85);
  background: #f5f5f5; border: 1px solid var(--avx-hairline); border-radius: 10px;
  padding: 10px 12px; white-space: pre-wrap; word-break: break-word;
}

/* ── Identical footprint on EVERY page ──
   One component, one size: each mount is capped at the width the home hero
   column yields on a full desktop (1140px container − padding − grid gap →
   ≈469px) and centered, so the login side panel renders the SAME card
   instead of a wider (big screens) or narrower (laptop) variant. On phones
   the login panel's 28px side padding is pulled back by 8px per side to the
   hero's effective 20px, so the two pages render pixel-identical widths. */
/* width:100% is LOAD-BEARING, not decorative: on the home page this element
   is a grid item, and `margin-inline:auto` cancels stretch alignment — the
   item falls back to fit-content sizing, whose intrinsic width under
   `container-type:inline-size` containment is ZERO (the card collapsed to
   width 0 in production). An explicit 100% resolves against the grid area /
   containing block instead of the (contained) intrinsic size. */
[data-avx-metar] { container-type: inline-size; width: 100%; max-width: 470px; margin-inline: auto; }
/* NOTE: no negative-margin tricks to equalize the last ~16px on phones — a
   `width: calc(100% + 16px)` wrapper inside the auth grid inflated the 1fr
   track (percentage cycle) and overflowed the whole login page by 16px. The
   card is identical in shape/typography on both pages; on phones the login
   panel's extra 8px/side padding is accepted. */

/* ── minimumScaleFactor(0.55) equivalent: tile values shrink only when the
      CARD itself is genuinely narrow (tiers sit BELOW the 470px cap, or the
      16px base would never apply). Container queries where supported;
      viewport fallback for browsers without them. ── */
@container (max-width: 430px) {
  .avx-tile-val .v { font-size: 14px; }
}
@container (max-width: 370px) {
  .avx-tile-val .v { font-size: 13px; }
  .avx-icao { font-size: 28px; }
}
@media (max-width: 400px) {
  .avx-tile-val .v { font-size: 13px; }
}
/* Valori lunghi (es. vento con raffica "280°/18 G29"): scala ridotta come il
   minimumScaleFactor(0.55) di iOS — mai fuori dalla tile. */
.avx-tile-val .v.long { font-size: 13px; letter-spacing: -0.3px; }
@container (max-width: 470px) {
  .avx-tile-val .v.long { font-size: 12px; }
}
@container (max-width: 370px) {
  .avx-tile-val .v.long { font-size: 9.5px; letter-spacing: -0.4px; }
  .avx-tile-val .v.long + .u { font-size: 9px; }
  .avx-tile-val:has(.v.long) { gap: 1px; }
}
@media (max-width: 400px) {
  .avx-tile-val .v.long { font-size: 9.5px; letter-spacing: -0.4px; }
  .avx-tile-val .v.long + .u { font-size: 9px; }
  .avx-tile-val:has(.v.long) { gap: 1px; }
}

/* ── Desktop: la card cresce in-flow (identica all'iPhone) dentro un mount
      ad ALTEZZA BLOCCATA sull'altezza della card chiusa — i contenuti sotto
      non si muovono di un pixel; la card aperta sborda dal mount e copre
      (senza spostare) ciò che segue, nello spazio già previsto oggi.
      Senza JS (--avx-closed-h assente) l'altezza resta auto: lo snapshot
      statico è chiuso e identico a prima. Il raw è cappato a 72px; per
      METAR estremi scorre internamente (ingombro aperto ≤ ~80px, dentro la
      riserva del login e l'involucro della hero). ── */
@media (min-width: 861px) {
  [data-avx-metar] { height: var(--avx-closed-h, auto); }
  .avx-reveal .avx-raw { max-height: 72px; overflow-y: auto; }
  .side-readout[data-avx-metar] { margin-bottom: 128px; }
}

/* ── Mobile (<861px): mount ad altezza auto — la card spinge il contenuto,
      comportamento naturale su phone (come iOS nella lista). ── */

@media (prefers-reduced-motion: reduce) {
  /* NB: se mai si reintroducono regole con selettori più specifici di una
     classe singola sul reveal, vanno co-elencati qui — altrimenti a
     specificità più alta ammazzano transition:none (login.html non ha il
     blanket-override di pagina che maschera il difetto sulle index). */
  .avx-reveal, .avx-reveal.open, .avx-card, .avx-chev { transition: none; }
}
