/* ==========================================================================
   vaBase default customer template - theme stylesheet
   --------------------------------------------------------------------------
   Everything is plain CSS with custom properties (design tokens). To rebrand:

     1. Change the token values in :root below (or just --accent - the
        primary colour saved in your vaBase Admin Portal overrides it too).
     2. Or restyle any component class.
     3. Or delete this file and write your own - the pages are plain HTML.

   Dark is the default theme. The light theme's token values are the
   [data-theme="light"] block just below :root: same tokens, different
   values. Light-theme overrides for individual components sit beside the
   components they adjust, with the maps' light chrome gathered in one
   block further down.
   ========================================================================== */

:root {
  color-scheme: dark;

  /* Surfaces: background darkest, surfaces step LIGHTER with elevation. */
  --bg: #0c0d0f;
  --surface-1: #141519;
  --surface-2: #17181c;
  --surface-3: #1d1e23;
  --border: #292a30;
  --border-strong: #3c3e46;

  /* Text */
  --text-primary: #eceded;
  --text-secondary: #b4b6bc;
  --text-muted: #979aa1;
  /* Ink on the accent. White for the default accent; vabase.js sets it from the airline's accent
     (white or near-black, whichever contrasts more - site-boot.js accentInk). */
  --text-on-accent: #ffffff;
  /* The primary button's and the header call to action's hover fill. Lighter by default; vabase.js
     darkens it instead where lighter would drop the ink below WCAG AA (site-boot.js accentHoverTarget). */
  --accent-hover: color-mix(in srgb, var(--accent) 82%, #ffffff);

  /* Accent + semantic. --accent is replaced at runtime by your airline's
     primary colour from the vaBase branding settings. */
  --accent: #5e00ea;
  --accent-soft: color-mix(in srgb, var(--accent) 16%, transparent);
  /* The space between the nav and a page's title - one value for every titled page. A page with
     its own hero or banner, or a detail page led by its back link, is not a titled page. */
  --page-top: 56px;
  /* A page's title, one size on every titled page. */
  --page-title-size: clamp(1.8rem, 4vw, 2.5rem);
  --accent-glow: color-mix(in srgb, var(--accent) 55%, transparent);
  --accent-bright: color-mix(in srgb, var(--accent) 55%, #ffffff);
  --success: #3ec27d;
  --warning: #d9a13c;
  --danger: #e35d6a;
  --info: #58a6ff;

  /* Weather: the four flight categories, the same in both themes and the same hexes as the maps'
     station dots (assets/js/weather-category.js; acars logic/weather-category.test.js reads this block). */
  --wx-vfr: #3ec27d;
  --wx-mvfr: #58a6ff;
  --wx-ifr: #e35d6a;
  --wx-lifr: #c05bd6;

  /* Shape, depth, type */
  --radius-sm: 8px;
  --radius-md: 12px;
  --radius-lg: 18px;
  --shadow-1: 0 4px 14px rgba(0, 0, 0, 0.3);
  --shadow-2: 0 12px 34px rgba(0, 0, 0, 0.45);
  --font-body: "Segoe UI Variable Text", "Segoe UI", system-ui, -apple-system, sans-serif;
  --font-mono: "Cascadia Mono", Consolas, "SF Mono", monospace;
  --content-width: 1160px;
}

[data-theme="light"] {
  color-scheme: light;
  --bg: #f4f4f6;
  --surface-1: #ffffff;
  --surface-2: #fafafb;
  --surface-3: #f0f1f3;
  --border: #dcdee3;
  --border-strong: #c0c3cb;
  --text-primary: #191b21;
  --text-secondary: #474b55;
  --text-muted: #6b6f7a;
  --shadow-1: 0 4px 14px rgba(15, 18, 28, 0.1);
  --shadow-2: 0 12px 34px rgba(15, 18, 28, 0.16);
}

/* ---- base ---- */

* {
  box-sizing: border-box;
}

/* The scrollbar's space is kept on every page, so titles do not jump sideways between pages - a
   page too short to scroll otherwise gains the scrollbar's width and re-centres everything under
   it. */
html {
  scrollbar-gutter: stable;
}

body {
  margin: 0;
  background: var(--bg);
  /* The airline accent's soft glow at the top of every page. It sits on the page background, so a
     page with its own hero image (Home, Join) covers it, and the translucent nav takes the same
     tint the page does. */
  background-image: radial-gradient(900px 380px at 10% 0%, var(--accent-soft), transparent 70%);
  background-repeat: no-repeat;
  color: var(--text-primary);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

a {
  color: var(--accent-bright);
  text-decoration: none;
}

a:hover {
  text-decoration: underline;
}

/* A row or card that is itself a link never underlines on hover.
   The rule above is for a link in running text, where the underline is the affordance and the link
   carries the accent colour. These links wrap a whole row, card or panel and inherit the page's own
   text colour, so the same rule would draw a white underline across every word in the row - under
   a flight number, a city, a date. Each of them already says it is a link another way: the row
   lifts, its border brightens, or its title turns accent on hover. Keep this list in step when a
   new whole-row link is added; an inline text link ("View report", "Open airport ›") is not one of
   these. */
a.card:hover, a.award-card:hover, a.dashboard-activity:hover,
a.activity-row:hover, a.recent-flight-row:hover, a.fd-card-link:hover, a.fdd-mini:hover, a.fdd-apcard:hover,
a.nm-flt:hover, a.profile-live-pill:hover, a.section-nav-link:hover, a.ribbon:hover,
a.ap-frow:hover, a.ap-rank:hover, a.ap-rank-flight:hover, a.ap-act:hover, a.ap-act-main:hover,
a.ap-glance:hover, a.ap-search-hit:hover, a.airport-link:hover {
  text-decoration: none;
}

img {
  max-width: 100%;
}

/* Focused form controls, everywhere. A browser's default focus ring is designed to be visible on
   an unknown background, so on a dark page it draws a light, near-white outline. The template's
   own idiom is a 2px accent outline, stated once on the elements themselves so a new form is
   styled correctly before anyone thinks about it. The per-form rules elsewhere (.va-form,
   .filter-bar, the dispatch selects) are all higher specificity, so they still win where they
   deliberately differ - this only fills the gaps.

   :focus, not :focus-visible. These controls are dark-on-dark, so "which box am I typing in" is
   not only a keyboard-navigation question here, and :focus-visible would leave a clicked field
   with no indication at all. */
input:focus,
textarea:focus,
select:focus {
  outline: 2px solid var(--accent);
  outline-offset: -1px;
}

code,
.mono {
  font-family: var(--font-mono);
}

.container {
  max-width: var(--content-width);
  margin: 0 auto;
  padding: 0 24px;
}

/* ---- navigation ---- */

.site-nav {
  position: sticky;
  top: 0;
  z-index: 50;
  backdrop-filter: blur(14px);
  background: color-mix(in srgb, var(--bg) 78%, transparent);
  border-bottom: 1px solid var(--border);
}

.site-nav .container {
  display: flex;
  align-items: center;
  gap: 28px;
  min-height: 64px;
}

.nav-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  font-weight: 700;
  font-size: 1.05rem;
  color: var(--text-primary);
  letter-spacing: 0.01em;
}

.nav-brand:hover {
  text-decoration: none;
}

.nav-brand img {
  height: 30px;
  width: auto;
  max-width: 220px;
  object-fit: contain;
}
/* A loaded logo stands alone: the name stays for screen readers only (.visually-hidden's rule). */
.nav-brand img:not([hidden]) ~ .nav-brand-name {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.nav-links {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-left: auto;
}

.nav-links a {
  color: var(--text-secondary);
  padding: 8px 13px;
  border-radius: var(--radius-sm);
  font-size: 0.95rem;
}

.nav-links a:hover {
  color: var(--text-primary);
  background: var(--surface-2);
  text-decoration: none;
}

.nav-links a.active {
  color: var(--text-primary);
  background: var(--accent-soft);
}

.nav-links .nav-cta {
  margin-left: 10px;
  background: var(--accent);
  color: var(--text-on-accent);
  font-weight: 600;
}

.nav-links .nav-cta:hover {
  background: var(--accent-hover);
  color: var(--text-on-accent);
}

/* The visitor's light / dark switch - an icon in the bar, a labelled row in the mobile menu.
   The sun offers light while the page is dark; the moon offers dark while it is light. */
.nav-theme {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  background: none;
  border: none;
  border-radius: var(--radius-sm);
  color: var(--text-secondary);
  padding: 8px 10px;
  font: inherit;
  font-size: 0.95rem;
  cursor: pointer;
}
.nav-theme[hidden] { display: none; }
.nav-theme:hover { color: var(--text-primary); background: var(--surface-2); }
.nav-theme:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 2px; }
.nav-theme-moon { display: none; }
[data-theme="light"] .nav-theme-sun { display: none; }
[data-theme="light"] .nav-theme-moon { display: inline; }
.nav-theme-label {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.nav-toggle {
  display: none;
  margin-left: auto;
  background: none;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  font-size: 1.3rem;
  padding: 4px 12px;
  cursor: pointer;
}

@media (max-width: 800px) {
  .nav-toggle {
    display: block;
  }

  .nav-links {
    display: none;
    position: absolute;
    top: 64px;
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: stretch;
    background: var(--surface-1);
    border-bottom: 1px solid var(--border);
    padding: 12px 24px 18px;
    gap: 6px;
  }

  .nav-links.open {
    display: flex;
  }

  .nav-links .nav-cta {
    margin-left: 0;
    text-align: center;
  }

  .nav-theme { padding: 8px 13px; }
  .nav-theme-label { position: static; width: auto; height: auto; overflow: visible; clip: auto; }
}

/* ---- hero ---- */

.hero {
  position: relative;
  display: flex;
  align-items: center;
  background-color: var(--surface-1);
  background-size: cover;
  background-position: center;
  overflow: hidden;
}

/* Dark gradient overlay so text stays readable over any hero image. Deliberately neutral: an
   accent-coloured glow here reads as a coloured wash across a real photo rather than a
   highlight. */
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(180deg,
      color-mix(in srgb, #070808 62%, transparent) 0%,
      color-mix(in srgb, #070808 40%, transparent) 45%,
      color-mix(in srgb, #0c0d0f 92%, transparent) 100%);
}

.hero .container {
  position: relative;
  width: 100%;
}

.hero-kicker {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent-bright);
  background: color-mix(in srgb, #070808 45%, transparent);
  border: 1px solid var(--accent-glow);
  border-radius: 999px;
  padding: 6px 14px;
  margin-bottom: 22px;
}

.hero h1 {
  margin: 0 0 14px;
  font-size: clamp(2.4rem, 6vw, 4.2rem);
  line-height: 1.05;
  letter-spacing: -0.02em;
  color: #ffffff;
  text-wrap: balance;
}

.hero .tagline {
  max-width: 640px;
  margin: 0 0 30px;
  font-size: clamp(1.05rem, 2.2vw, 1.3rem);
  color: rgba(236, 237, 237, 0.88);
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

/* ---- stat cards ---- */

.stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 14px;
}

.stat-tile {
  background: color-mix(in srgb, var(--surface-2) 88%, transparent);
  backdrop-filter: blur(10px);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 18px 20px;
  box-shadow: var(--shadow-1);
}

.stat-tile .stat-value {
  font-size: 1.9rem;
  font-weight: 700;
  font-family: var(--font-mono);
  color: var(--text-primary);
  line-height: 1.2;
}

.stat-tile .stat-label {
  margin-top: 2px;
  font-size: 0.82rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.stat-tile.accent {
  border-color: var(--accent-glow);
  background: linear-gradient(160deg, var(--accent-soft), color-mix(in srgb, var(--surface-2) 88%, transparent) 55%);
}

/* ---- sections ---- */

.section {
  padding: 64px 0 26px;
}

.section-head {
  display: flex;
  align-items: baseline;
  gap: 16px;
  margin-bottom: 22px;
}

.section-head h2 {
  margin: 0;
  font-size: 1.6rem;
  letter-spacing: -0.01em;
}

.section-head .section-sub {
  color: var(--text-muted);
  font-size: 0.95rem;
}

.section-head .section-link {
  margin-left: auto;
  font-size: 0.92rem;
  white-space: nowrap;
}

/* ---- buttons ---- */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  padding: 11px 22px;
  font-size: 0.98rem;
  font-weight: 600;
  font-family: inherit;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
}

.btn:hover {
  text-decoration: none;
}

/* A gentle press affordance for every button variant. */
.btn:active {
  transform: translateY(1px);
}

/* A disabled button must look disabled - otherwise a click that does nothing reads as "the app is
   broken". Site-wide, so every server-gated action explains itself the same way. */
.btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
  box-shadow: none;
}
.btn:disabled:active {
  transform: none;
}

/* No glow shadow: the accent fill is the emphasis. A coloured drop shadow reads as a smudge on
   dark surfaces rather than depth. */
.btn-primary {
  background: var(--accent);
  color: var(--text-on-accent);
}

.btn-primary:hover {
  background: var(--accent-hover);
}

.btn-ghost {
  background: color-mix(in srgb, #070808 30%, transparent);
  border-color: rgba(236, 237, 237, 0.35);
  color: #ffffff;
}

.btn-ghost:hover {
  border-color: #ffffff;
}

.section .btn-ghost,
.state .btn-ghost,
/* The Join page sheet and its terms dialog are surfaces too. */
.join-page .btn-ghost,
.join-terms-dialog .btn-ghost,
/* The Statistics page sits on the page surface, never over an image. */
.stx-page .btn-ghost {
  background: var(--surface-2);
  border-color: var(--border-strong);
  color: var(--text-primary);
}

/* The in-section ghost variant above out-specifies the base .btn-ghost:hover, which left
   buttons like From SimBrief and the lifecycle actions with NO visible hover at all. A subtle
   accent tint + brightened border says "clickable" without shouting. */
.section .btn-ghost:hover,
.state .btn-ghost:hover,
.join-page .btn-ghost:hover,
.join-terms-dialog .btn-ghost:hover,
.stx-page .btn-ghost:hover {
  background: color-mix(in srgb, var(--accent) 9%, var(--surface-2));
  border-color: color-mix(in srgb, var(--accent) 45%, var(--border-strong));
}

/* ---- badges ---- */

.badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  border-radius: 999px;
  padding: 2px 11px;
  font-size: 0.76rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  white-space: nowrap;
}

.badge-accent { background: var(--accent-soft); color: var(--accent-bright); }
.badge-success { background: color-mix(in srgb, var(--success) 16%, transparent); color: var(--success); }
.badge-warning { background: color-mix(in srgb, var(--warning) 16%, transparent); color: var(--warning); }
.badge-danger { background: color-mix(in srgb, var(--danger) 16%, transparent); color: var(--danger); }
.badge-info { background: color-mix(in srgb, var(--info) 16%, transparent); color: var(--info); }
.badge-muted { background: var(--surface-3); color: var(--text-muted); }
/* The flight-kind pill (Scheduled / Free flight) - an outline tag, deliberately distinct from the
   filled status badges so the two pills never read as the same kind of thing. */
.badge-kind { background: transparent; color: var(--text-secondary); border: 1px solid var(--border-strong); }

/* ---- cards ---- */

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 16px;
}

.card {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 20px 22px;
  transition: border-color 0.15s ease, transform 0.15s ease;
}

.card:hover {
  border-color: var(--border-strong);
  transform: translateY(-2px);
}

.card h3 {
  margin: 0 0 4px;
  font-size: 1.12rem;
}

.card .card-sub {
  color: var(--text-muted);
  font-size: 0.9rem;
}

.card-top {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  margin-bottom: 10px;
}

.card-top .spacer {
  margin-left: auto;
}

/* My-flights card header groups - flight number + kind pill on the left, status + aircraft chip
   on the right - each a wrapping flex row so the pills always keep their gap. */
.card-top .flight-id,
.card-top .badge-row {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

/* The inline cancel confirmation revealed under a My-flights card's actions. */
.cancel-confirm { margin-top: 12px; }
.cancel-confirm .card-sub { margin-bottom: 10px; }

.card-facts {
  display: flex;
  flex-wrap: wrap;
  /* More breathing room between facts on the summary row. */
  gap: 12px 34px;
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
}

.card-facts .fact {
  font-size: 0.85rem;
  color: var(--text-secondary);
}

.card-facts .fact strong {
  display: block;
  font-family: var(--font-mono);
  font-size: 1rem;
  color: var(--text-primary);
}

/* Big monospace airport code, used on hub cards and route displays. */
.airport-code {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 1.7rem;
  letter-spacing: 0.04em;
  color: var(--text-primary);
  line-height: 1.1;
}

/* ---- route display (schedules, recent flights) ---- */

.route {
  display: flex;
  align-items: center;
  gap: 14px;
}

.route .route-end {
  min-width: 74px;
}

.route .route-end .airport-code {
  font-size: 1.35rem;
}

.route .route-end .route-city {
  font-size: 0.78rem;
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 120px;
}

.route .route-line {
  flex: 1;
  min-width: 40px;
  position: relative;
  height: 18px;
}

.route .route-line::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  border-top: 2px dashed var(--border-strong);
}

/* The aircraft over the dashed line is a real silhouette SVG, built by vaBase.routeLine() (a text
   \2708 glyph renders differently on every OS). The span backgrounds punch a gap in the dashes
   around it. */
.route .route-plane {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  color: var(--accent-bright);
  background: var(--surface-2);
  padding: 0 6px;
  line-height: 0;
}

.route .route-plane svg {
  transform: rotate(90deg);
}

/* The discreet planned-departure editor on the dispatch brief. */
.brief-departure { margin-top: 12px; }
.brief-departure .dep-row {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex-wrap: wrap;
  padding: 11px 14px;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
}
.brief-departure .dep-label {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-muted);
}
.brief-departure .dep-value {
  font-family: var(--font-mono);
  color: var(--text-primary);
}
.brief-departure .dep-edit {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  font-size: 0.85rem;
  color: var(--accent-bright);
  text-decoration: underline;
  cursor: pointer;
}
.brief-departure .dep-edit:hover { color: var(--text-primary); }
.brief-departure .dep-note {
  margin-top: 6px;
  font-size: 0.82rem;
  color: var(--accent-bright);
}
.brief-departure .dep-edit-form {
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-width: 340px;
  margin-top: 6px;
  padding: 14px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}
.brief-departure .dep-field-label {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-muted);
}
/* The native datetime-local control, dressed to match the template's text inputs (it renders as a
   light UA default otherwise). color-scheme keeps its calendar popup and picker icon dark-on-dark. */
.brief-departure .dep-input {
  width: 100%;
  padding: 10px 12px;
  font: inherit;
  color: var(--text-primary);
  background: var(--surface-1);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  color-scheme: dark;
}
.brief-departure .dep-input:focus { outline: none; border-color: var(--accent); }
/* Follow the active theme for the native picker (dark by default; light when the site is). */
[data-theme="light"] .brief-departure .dep-input { color-scheme: light; }
.brief-departure .dep-actions { display: flex; gap: 8px; }
.brief-departure .dep-hint {
  font-size: 0.78rem;
  color: var(--text-muted);
  margin: 0;
}

/* ---- filter bar ---- */

.filter-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-bottom: 22px;
}

.filter-bar input[type="search"],
.debrief-timeline-search {
  flex: 1;
  min-width: 220px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  font-family: inherit;
  font-size: 0.95rem;
  padding: 10px 14px;
}

.filter-bar input[type="search"]:focus,
.debrief-timeline-search:focus {
  outline: 2px solid var(--accent);
  outline-offset: -1px;
}

.chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.chip {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--text-secondary);
  font-family: inherit;
  font-size: 0.86rem;
  font-weight: 600;
  padding: 7px 16px;
  cursor: pointer;
}

.chip:hover {
  border-color: var(--border-strong);
  color: var(--text-primary);
}

.chip.active {
  background: var(--accent-soft);
  border-color: var(--accent-glow);
  color: var(--accent-bright);
}

.result-count {
  margin-left: auto;
  font-size: 0.85rem;
  color: var(--text-muted);
}

/* ---- data tables ---- */

.table-wrap {
  overflow-x: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface-2);
}

table.data {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.92rem;
}

table.data th {
  position: sticky;
  top: 0;
  text-align: left;
  font-size: 0.76rem;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--text-muted);
  background: var(--surface-3);
  padding: 11px 16px;
  white-space: nowrap;
}

table.data td {
  padding: 11px 16px;
  border-top: 1px solid var(--border);
  color: var(--text-secondary);
  white-space: nowrap;
}

table.data td:first-child {
  color: var(--text-primary);
}

table.data tr:hover td {
  background: color-mix(in srgb, var(--surface-3) 55%, transparent);
}

/* ---- icons ----
   Shared primitive, not scoring's own: vaBase.icon() draws stroke-only SVG that inherits
   currentColor, so an icon takes the colour of whatever it sits beside. Sized here once so a
   caller never has to.

   An SVG's class is set through setAttribute (className is read-only on SVG elements), which
   the stylesheet-classes scanner cannot see - so a typo in an icon class name is not caught by
   that guard. Verify icons by measuring them in the browser. */
.icon {
  width: 15px;
  height: 15px;
  flex: 0 0 auto;
  vertical-align: -2px;
}

/* ---- how scoring works ----
   The rule's shape drives its presentation. One outcome is a statement, a band rule is a ramp of
   tiers, met/not-met is a pair - rendered as one table, every rule would read as a spreadsheet,
   with the points (the reason a pilot opens the page) no louder than the label beside them. The
   shape comes from the server (ScoringRuleShape), because two bands are two tiers and not a pass
   and a fail. */

/* ---- the headline ----
   The number a pilot came for. Across every group: no flight anywhere at this airline can beat
   it. */
.scoring-headline {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px 18px;
  margin-bottom: 14px;
  padding: 14px 18px;
  border-radius: var(--radius-lg);
  border: 1px solid color-mix(in srgb, var(--accent) 40%, var(--border));
  background: var(--accent-soft);
}
.scoring-headline-figure {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex-wrap: wrap;
}
.scoring-headline-value {
  font-size: 1.7rem;
  font-weight: 650;
  line-height: 1;
  color: var(--accent-bright);
  font-variant-numeric: tabular-nums;
}
.scoring-headline-label { color: var(--text-secondary); font-size: 0.9rem; }
.scoring-headline-rank {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 0.8rem;
  color: var(--text-muted);
}

.scoring-group + .scoring-group { margin-top: 14px; }

/* Name, covered aircraft and (with more than one group) its ceiling on ONE line. A group is
   "this name, these aircraft" - stacking them would make a three-line header out of a single
   fact. */
.scoring-group-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}
.scoring-group-head h3 { margin: 0 8px 0 0; }
.scoring-group-ceiling {
  margin-left: auto;
  font-size: 0.78rem;
  color: var(--text-muted);
  white-space: nowrap;
}
.scoring-group-ceiling strong {
  color: var(--accent-bright);
  font-size: 1rem;
  font-variant-numeric: tabular-nums;
}
.scoring-group-note { margin: 8px 0 0; font-size: 0.85rem; }

.scoring-chip {
  font-size: 0.74rem;
  padding: 3px 10px;
  border-radius: 999px;
  background: var(--surface-3);
  border: 1px solid var(--border);
  color: var(--text-muted);
}
/* An aircraft code is a code everywhere else in vaBase, so it reads as one here too. */
.scoring-chip-code {
  font-family: var(--font-mono);
  color: var(--text-secondary);
  letter-spacing: 0.02em;
}

.scoring-rule {
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
}

.scoring-rule-head { margin-bottom: 10px; }
/* A single-outcome rule is ONE row - name and summary left, figure right. Rendered as three
   stacked rows it left a band of empty space across the card for a rule that says one thing. */
.scoring-rule-single {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 0;
}
.scoring-rule-heading { min-width: 0; }

.scoring-rule-title {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 10px;
}

/* Demoted deliberately. As a badge this competed with the rule's own name; it is a footnote
   about when the rule can run, so it reads as one. */
.scoring-requirement {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 0.74rem;
  color: var(--text-muted);
}
.scoring-requirement .icon { width: 13px; height: 13px; }

.scoring-rule-summary {
  margin: 3px 0 0;
  font-size: 0.85rem;
  color: var(--text-secondary);
}
.scoring-rule-head:not(.scoring-rule-single) .scoring-rule-summary { margin-bottom: 10px; }

/* Sign, and only sign. Never the tier's rank - a rule whose bands are all positive must not
   paint its lowest band as a penalty the airline never configured. */
.scoring-pos { color: var(--success); }
.scoring-neg { color: var(--danger); }
.scoring-zero { color: var(--text-secondary); }

/* One fact, one number - sitting on the rule's own row rather than a table with a single
   line in it. */
.scoring-single-points {
  font-size: 1.45rem;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  flex: 0 0 auto;
}

/* The ramp. auto-fit wraps to fewer columns on a narrow screen rather than scrolling the page
   sideways. */
.scoring-tiers {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(124px, 1fr));
  gap: 8px;
}

.scoring-tier {
  padding: 10px 12px;
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
  background: var(--surface-3);
}
.scoring-tier.scoring-pos {
  border-color: color-mix(in srgb, var(--success) 40%, var(--border));
  background: color-mix(in srgb, var(--success) 10%, transparent);
}
.scoring-tier.scoring-neg {
  border-color: color-mix(in srgb, var(--danger) 40%, var(--border));
  background: color-mix(in srgb, var(--danger) 10%, transparent);
}

/* Three lines, in the order they are read: what it pays, what it is called, where it starts
   and ends. The range is a separate field from the server, not a suffix glued to the name -
   as one string it wrapped into a paragraph and the tile read as a table row again. */
.scoring-tier-points {
  display: block;
  font-size: 1.25rem;
  font-weight: 650;
  line-height: 1.2;
  font-variant-numeric: tabular-nums;
}
.scoring-tier-label {
  display: block;
  margin-top: 2px;
  font-size: 0.82rem;
  color: var(--text-secondary);
}
.scoring-tier-range {
  display: block;
  margin-top: 2px;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: var(--text-muted);
}

/* Which direction is which. Without it a pilot reads four ranges to work out that right is
   better. */
.scoring-axis {
  display: flex;
  justify-content: space-between;
  margin-top: 5px;
  font-size: 0.72rem;
  color: var(--text-muted);
}

.scoring-pair {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 8px;
}

.scoring-outcome {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
  background: var(--surface-3);
}
.scoring-outcome.scoring-pos {
  border-color: color-mix(in srgb, var(--success) 40%, var(--border));
  background: color-mix(in srgb, var(--success) 10%, transparent);
}
.scoring-outcome.scoring-neg {
  border-color: color-mix(in srgb, var(--danger) 40%, var(--border));
  background: color-mix(in srgb, var(--danger) 10%, transparent);
}

.scoring-mark { width: 15px; height: 15px; flex: 0 0 auto; }
.scoring-outcome-label {
  font-size: 0.82rem;
  color: var(--text-secondary);
  flex: 1 1 auto;
  min-width: 0;
}
.scoring-outcome-points {
  font-size: 1.1rem;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.scoring-not-shown { margin-top: 16px; }

/* ---- the score on the pilot's own report ----
   The same signs, colours and tone helpers as the page above, because a pilot reads a rule
   there and its result here: two vocabularies would read as two systems. */

/* The section wrapper, spaced like the flight-data section it sits beside - .card carries no
   margin of its own, so a section that is one card has to supply it. */
/* The Points section: no card - the headline with its arithmetic beside it, then Earned /
   Penalties / Other evaluated rules as captioned groups of hairline rows, and the zero-point
   lines behind a disclosure.
   Full width, not a reading column. The reading measure belongs to prose - `.debrief-lede` keeps
   its 760 px because it is running text - and this is a ledger: name on the left, figure on the
   right, a hairline under every row carrying the eye across. */
.scoring-report { margin-bottom: 18px; }
.points-body { padding-top: 2px; }
.points-summary { font-size: 0.86rem; color: var(--text-secondary); font-variant-numeric: tabular-nums; }
.points-group { margin-top: 18px; }
.points-group-caption { margin: 0 0 2px; font-size: 0.76rem; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-muted); }
.points-compact-names { display: flex; flex-wrap: wrap; gap: 0 6px; }
.points-compact-figures { display: inline-flex; gap: 10px; font-size: 0.9rem; font-weight: 500; }
.points-other { margin-top: 18px; font-size: 0.86rem; }
.points-other summary { cursor: pointer; color: var(--text-secondary); }
.points-other summary strong { color: var(--text-primary); font-weight: 600; }
.points-other .scoring-report-line { padding: 8px 0; }
@media (max-width: 700px) { .points-compact-figures { gap: 6px; } }

.scoring-report-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 16px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--border);
}
.scoring-report-total {
  font-size: 2rem;
  font-weight: 650;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.scoring-report-state {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  font-size: 0.8rem;
}
.scoring-report-adjusted { margin: 12px 0 0; font-size: 0.82rem; }

.scoring-report-line {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  padding: 10px 0;
  border-bottom: 1px solid var(--border);
}
/* The rule's name, with a skipped rule's reason under it: a missing line would read as the
   airline quietly dropping it, and a silent zero as a rule that awarded nothing. */
.scoring-report-label { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.scoring-report-label .muted { font-size: 0.78rem; }
.scoring-report-points {
  font-size: 1.05rem;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.scoring-report-help { display: inline-block; margin-top: 14px; font-size: 0.82rem; }

/* ---- flight data on the pilot's own report ---- */

/* Compact stat tiles: this section sits under the report hero, so its numbers read as data,
   not a dashboard headline - the admin review page's scale (smaller body-font values, tighter
   grid), keeping the dashboard's big mono tiles untouched. */
.flight-data .stat-grid {
  grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  gap: 10px;
}

.flight-data .stat-tile {
  padding: 12px 14px;
}

.flight-data .stat-tile .stat-value {
  font-size: 1.3rem;
  font-family: var(--font-body);
  font-weight: 650;
  letter-spacing: -0.01em;
}

.flight-data .stat-tile .stat-label {
  font-size: 0.76rem;
}

/* A table inside a card flattens, and the rule is keyed on the card. .table-wrap draws the same
   border, radius and surface a .card does, so one inside the other is the same box twice. Keyed
   on .card, any table put inside a card is covered - the report's flight data, the debrief, the
   hub standings.

   The fleet list is the case this must not reach, and it does not: it renders its table into a
   bare div, where the wrap is the container and rightly keeps its chrome.

   Only table.data sheds its outer cell padding, and the standings table deliberately keeps its
   own: its cells are already inset by the same 12px the wrap's border used to add, and its
   highlighted row is a tr background spanning the whole row, which stays a full-width band
   either way. */
.card .table-wrap {
  border: 0;
  border-radius: 0;
  background: transparent;
}

.card table.data th {
  background: transparent;
}

.card table.data th:first-child,
.card table.data td:first-child {
  padding-left: 0;
}

.card table.data th:last-child,
.card table.data td:last-child {
  padding-right: 0;
}

/* ---- activity list (recent flights) ---- */

/* The live map, a radar-style ops display: one full-bleed canvas with the hover card, sidebar
   and empty/error states all overlaid on it (no strips or lists - the planes are the interface).
   The shell needs an explicit height - MapLibre fills whatever box it gets, and an auto-height
   div collapses to a silently blank map. Concrete dark colours on everything that sits on the
   map, never theme variables: the overlays belong to the map, not the page, and the light
   theme's map chrome is its own block further down. */
.live-section { padding-top: 26px; }
.live-shell {
  position: relative;
  height: 68vh;
  min-height: 480px;
  border: 1px solid var(--border);
  border-radius: 14px;
  overflow: hidden;
  background: #0d0d13;
}
.live-canvas { position: absolute; inset: 0; }

/* Aircraft: our own north-pointing silhouette (fill: currentColor), rotated to the heading. */
.live-plane { color: var(--accent, #8b6be0); cursor: pointer; line-height: 0; }
.live-plane svg { filter: drop-shadow(0 0 3px rgba(0, 0, 0, 0.8)); }
.live-plane-stale { color: var(--warning, #d9a13c); opacity: 0.8; }
.live-plane-selected { color: #c4b5fd; }

/* Empty / error state, centred on the glass. */
.live-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 2;
  pointer-events: none;
}

/* One line when a link named a flight that is no longer in the air. It sits over the map rather
   than replacing it (that is what .live-overlay does) - the map stays usable, which is the whole
   difference between a note and an error. */
.live-note {
  position: absolute;
  top: 12px;
  left: 50%;
  transform: translateX(-50%);
  margin: 0;
  padding: 6px 12px;
  border-radius: 8px;
  background: rgba(17, 17, 24, 0.78);
  border: 1px solid var(--border);
  font-size: 0.85rem;
  z-index: 3;
  pointer-events: none;
}
/* The empty state sits on glass, never as bare text over map labels. */
.live-overlay-box {
  text-align: center;
  pointer-events: auto;
  max-width: 300px;
  background: rgba(17, 17, 24, 0.92);
  border: 1px solid #2a2a38;
  border-radius: 12px;
  padding: 16px 20px;
}
.live-overlay-text { color: #a3a3b2; font-size: 13.5px; line-height: 1.55; margin: 0; }
.live-overlay-box .btn { margin-top: 12px; }

/* Degraded mode: the accessible flight list shown ONLY when the basemap cannot load at all
   (vendor script missing / style unreachable) - the flights must never be a blank page. */
.live-fallback { max-width: 420px; width: min(420px, 90%); text-align: left; }
.live-fallback-list {
  margin-top: 12px;
  max-height: 55vh;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.live-fallback-row {
  display: flex;
  flex-direction: column;
  gap: 2px;
  text-align: left;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid #2a2a38;
  border-radius: 8px;
  padding: 8px 12px;
  cursor: pointer;
  color: inherit;
  font: inherit;
}
.live-fallback-row:hover { background: rgba(255, 255, 255, 0.08); }
.live-fallback-title { font-size: 13px; font-weight: 600; color: #f0ecff; }
.live-fallback-meta { font-size: 12px; color: #a3a3b2; }

/* ---- tours and events ---- */

/* A card that is itself a link. Without this it inherits the global `a` rule - the whole card
   takes the accent colour and its text underlines on hover, which is right for a run of text and
   wrong for a panel. The card already signals its own affordance through the hover lift and
   border, so the anchor only has to stop painting itself as text. */
a.card,
a.card:hover {
  color: inherit;
  text-decoration: none;
}
/* The heading keeps the accent so the card still reads as somewhere to go, and it is the one
   part that behaves like a link. */
a.card h3 { color: var(--accent-bright); }

/* The tour route map. Fixed height, like the live map: MapLibre needs a laid-out box before it
   can size its canvas, and a zero-height container renders blank until something resizes it. */
.route-map {
  height: 320px;
  border-radius: var(--radius-md);
  overflow: hidden;
  border: 1px solid var(--border);
  margin-top: 12px;
}

/* An event or tour's poster. Capped so a large remote image cannot dominate the page, and it
   is a link the airline hosts, so it may simply fail to load. */
.promo-image {
  display: block;
  width: 100%;
  max-height: 260px;
  object-fit: cover;
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
  margin-bottom: 18px;
}

/* The pilot's activity card while a clock is running against them. Amber - a deadline is
   approaching and nothing has happened yet. */
.activity-warn {
  border-color: color-mix(in srgb, var(--warning) 45%, var(--border));
  background: color-mix(in srgb, var(--warning) 8%, var(--surface-2));
}

/* And red once it has. The two are deliberately different colours: until the consequence
   applied, amber said "act soon"; once the airline is refusing to let them fly, the card has to
   look like the thing it is, or a pilot meets the refusal at the Book button with a mild-looking
   note above it - blocked with nothing on screen explaining why. */
.activity-error {
  border-color: color-mix(in srgb, var(--danger) 45%, var(--border));
  background: color-mix(in srgb, var(--danger) 8%, var(--surface-2));
}


/* Rendered rich text - a briefing, server-sanitised. Without these the browser's own defaults
   apply: an h3 twice the size of the card's heading, and lists with a 40px indent. */
.rich-text > :first-child { margin-top: 0; }
.rich-text > :last-child { margin-bottom: 0; }
.rich-text p { margin: 0 0 10px; }
.rich-text h1,
.rich-text h2,
.rich-text h3 { font-size: 15px; font-weight: 600; margin: 16px 0 8px; }
.rich-text ul,
.rich-text ol { margin: 0 0 10px; padding-left: 20px; }
.rich-text li { margin: 3px 0; }
.rich-text blockquote {
  margin: 0 0 10px;
  padding-left: 12px;
  border-left: 2px solid var(--border-strong);
  color: var(--text-secondary);
}

/* Airport endpoint chips (DOM markers - no glyph dependency on the tile style). */
.live-map-airport {
  font-family: var(--mono, ui-monospace, monospace);
  font-size: 10px;
  letter-spacing: 0.04em;
  color: #a3a3b2;
  background: rgba(20, 20, 26, 0.85);
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 6px;
  padding: 1px 5px;
  pointer-events: none;
}

/* The hover mini card (a restyled MapLibre popup - see the chrome overrides below). */
.live-hover { min-width: 170px; }
.live-hover-head { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }
.live-hover-callsign { font-size: 13px; font-weight: 600; color: #f0ecff; }
.live-hover-route {
  font-family: var(--mono, ui-monospace, monospace);
  font-size: 11px;
  color: #a3a3b2;
}
.live-hover-meta { font-size: 12px; color: #a3a3b2; margin-top: 4px; }
.live-hover-age { font-size: 11px; color: #8a8a99; margin-top: 4px; }

/* Shared thin progress bar (hover card + sidebar hero). */
.live-bar {
  position: relative;
  height: 3px;
  background: #2a2a38;
  border-radius: 2px;
  margin-top: 7px;
}
.live-bar-fill { height: 100%; background: #8b6be0; border-radius: 2px; }

/* Scrollbars on the map overlays: the stock chunky light-grey bar reads as a hole in the
   dark glass. Thin, dark, and quiet - visible on hover/scroll, never a design element. */
.live-sidebar,
.live-side-routetext,
.debrief-timeline,
.table-wrap,
.ap-scroll {
  scrollbar-width: thin;
  scrollbar-color: #34344a transparent;
}
.live-sidebar::-webkit-scrollbar,
.live-side-routetext::-webkit-scrollbar,
.debrief-timeline::-webkit-scrollbar,
.table-wrap::-webkit-scrollbar,
.ap-scroll::-webkit-scrollbar {
  width: 8px;
  height: 8px; /* A horizontal bar (the table wraps) matches the timeline bar */
}
.live-sidebar::-webkit-scrollbar-track,
.live-side-routetext::-webkit-scrollbar-track,
.debrief-timeline::-webkit-scrollbar-track,
.table-wrap::-webkit-scrollbar-track,
.ap-scroll::-webkit-scrollbar-track {
  background: transparent;
}
.live-sidebar::-webkit-scrollbar-thumb,
.live-side-routetext::-webkit-scrollbar-thumb,
.debrief-timeline::-webkit-scrollbar-thumb,
.table-wrap::-webkit-scrollbar-thumb,
.ap-scroll::-webkit-scrollbar-thumb {
  background: #2e2e3c;
  border-radius: 4px;
  border: 2px solid rgba(17, 17, 24, 0.97);
}
.live-sidebar::-webkit-scrollbar-thumb:hover,
.live-side-routetext::-webkit-scrollbar-thumb:hover,
.debrief-timeline::-webkit-scrollbar-thumb:hover,
.table-wrap::-webkit-scrollbar-thumb:hover,
.ap-scroll::-webkit-scrollbar-thumb:hover {
  background: #4a3f78;
}

/* The flight sidebar, overlaid on the map's right edge. */
.live-sidebar {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 248px;
  background: rgba(17, 17, 24, 0.97);
  border-left: 1px solid #2a2a38;
  padding: 14px 16px;
  overflow-y: auto;
  z-index: 4;
}
.live-stale-banner {
  background: rgba(217, 161, 60, 0.12);
  border: 1px solid rgba(217, 161, 60, 0.4);
  color: #e6b45c;
  border-radius: 8px;
  padding: 7px 10px;
  font-size: 11.5px;
  line-height: 1.45;
  margin-bottom: 12px;
}
.live-side-head { display: flex; justify-content: space-between; align-items: center; }
.live-side-title { font-size: 16px; font-weight: 600; color: #b9a4f6; }
.live-side-close {
  background: none;
  border: none;
  color: #8a8a99;
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  padding: 2px 4px;
}
.live-side-close:hover { color: #f0ecff; }
.live-side-phase { font-size: 12px; color: #a3a3b2; margin-top: 2px; }

.live-side-route { margin-top: 14px; }
.live-side-codes { display: flex; justify-content: space-between; }
.live-side-code {
  font-family: var(--mono, ui-monospace, monospace);
  font-size: 16px;
  font-weight: 600;
  color: #f0ecff;
}
.live-side-bar { height: 4px; margin-top: 8px; }
.live-side-dot {
  position: absolute;
  top: -4px;
  width: 11px;
  height: 11px;
  margin-left: -6px;
  border-radius: 50%;
  background: #b9a4f6;
  border: 2px solid #11111a;
}
.live-side-routemeta { font-size: 11px; color: #8a8a99; margin-top: 6px; }
/* The ETA, made obvious: a bold accent span riding the distance line. */
.live-side-eta {
  font-size: 12px;
  font-weight: 600;
  color: #c4b5fd;
}

.live-side-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px;
  margin-top: 14px;
}
.live-side-cell { background: #191922; border-radius: 7px; padding: 7px 10px; }
.live-side-label { font-size: 10px; color: #8a8a99; }
.live-side-value {
  font-family: var(--mono, ui-monospace, monospace);
  font-size: 13px;
  color: #f0ecff;
  margin-top: 1px;
}

.live-side-pilot {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 14px;
  padding-top: 13px;
  border-top: 1px solid #2a2a38;
}

.live-side-facts { margin-top: 13px; padding-top: 12px; border-top: 1px solid #2a2a38; }
.live-fact { display: flex; justify-content: space-between; font-size: 12px; padding: 3px 0; gap: 10px; }
.live-fact-label { color: #8a8a99; flex: 0 0 auto; }
.live-fact-value { color: #cfcfdd; text-align: right; overflow-wrap: anywhere; }

/* The filed route: mono, wrapped, quietly scrollable when a long airways string arrives. */
.live-side-routesection { margin-top: 13px; padding-top: 12px; border-top: 1px solid #2a2a38; }
.live-side-routetext {
  font-family: var(--mono, ui-monospace, monospace);
  font-size: 11px;
  line-height: 1.5;
  color: #cfcfdd;
  overflow-wrap: anywhere;
  max-height: 76px;
  overflow-y: auto;
  margin-top: 4px;
}

/* The ICAO hover tooltip: pure CSS from a data attribute (attr() renders TEXT, so a server
   string can never become markup here). */
.live-tip { position: relative; cursor: help; }
.live-tip:hover::after {
  content: attr(data-tip);
  position: absolute;
  bottom: calc(100% + 7px);
  left: 0;
  background: #15151f;
  border: 1px solid #34344a;
  border-radius: 7px;
  padding: 6px 10px;
  font-family: var(--font, inherit);
  font-size: 11px;
  font-weight: 400;
  line-height: 1.4;
  color: #cfcfdd;
  width: max-content;
  max-width: 190px;
  z-index: 12;
}
.live-tip-right:hover::after { left: auto; right: 0; }

/* Speed & altitude over the flight so far: two self-scaled series from the trail's own
   samples - altitude in the accent, speed in amber, ceilings + time span beneath. */
.live-side-graphsection { margin-top: 13px; padding-top: 12px; border-top: 1px solid #2a2a38; }
.live-graph-head { display: flex; justify-content: space-between; align-items: baseline; }
.live-graph-legend { display: flex; gap: 8px; font-size: 10px; }
.live-graph-key { text-transform: uppercase; letter-spacing: 0.05em; }
.live-graph-key-alt { color: #8b6be0; }
.live-graph-key-gs { color: #e8a33d; }
.live-graph {
  display: block;
  width: 100%;
  height: 76px;
  margin-top: 6px;
  background: #12121a;
  border-radius: 7px;
}
.live-graph-altfill { fill: rgba(139, 107, 224, 0.14); stroke: none; }
.live-graph-alt { fill: none; stroke: #8b6be0; stroke-width: 1.6; }
.live-graph-gs { fill: none; stroke: #e8a33d; stroke-width: 1.4; }
.live-graph-scale {
  display: flex;
  justify-content: space-between;
  font-size: 10px;
  color: #8a8a99;
  margin-top: 4px;
}

.live-side-actions { display: flex; gap: 8px; margin-top: 15px; }
.live-action {
  flex: 1;
  font-size: 12px;
  color: #cfcfdd;
  background: none;
  border: 1px solid #3a3a4c;
  border-radius: 7px;
  padding: 7px 0;
  cursor: pointer;
}
.live-action:hover { border-color: #8b6be0; color: #f0ecff; }
.live-action-active {
  background: #3b2f66;
  border-color: #8b6be0;
  color: #e8e2ff;
}

/* Narrow screens: the sidebar takes the full width of the glass. */
@media (max-width: 640px) {
  .live-sidebar { width: 100%; border-left: none; }
}

/* MapLibre's stock chrome is white (zoom buttons, attribution pill) and glares on a dark map.
   The icons are the vendor's dark SVG background-images, so on a dark button they are inverted
   to light. The light theme's variant is in the light map-chrome block further down.

   Attribution is themed and collapsed, never removed: the tiles are OpenStreetMap-derived and
   naming the source is the licence condition, not decoration. Compact mode is the standard way
   to keep it out of the way - one small circle that expands on click. */
/* One quiet set for every map on the site. `.maplibregl-map` is the class MapLibre puts on every
   map container, so a new map is covered without being listed, and
   `.maplibregl-map .maplibregl-ctrl-group` (0,2,0) outranks the vendor's (0,1,0) whatever order
   the stylesheets load in - an equal-specificity override would silently lose to load order. The
   zoom is small and see-through until the pointer is on it; the attribution stays (the licence
   condition above) as one small dim line. */
.maplibregl-map .maplibregl-ctrl-group {
  background: rgba(16, 17, 21, 0.5);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 8px;
  box-shadow: none;
  backdrop-filter: blur(4px);
}
.maplibregl-map .maplibregl-ctrl-group button {
  width: 26px;
  height: 26px;
  background-color: transparent;
}
.maplibregl-map .maplibregl-ctrl-group button:not(:disabled):hover { background-color: rgba(255, 255, 255, 0.07); }
.maplibregl-map .maplibregl-ctrl-group button + button { border-top: 1px solid rgba(255, 255, 255, 0.08); }
.maplibregl-map .maplibregl-ctrl button .maplibregl-ctrl-icon { filter: invert(1); opacity: 0.6; }
.maplibregl-map .maplibregl-ctrl button:hover .maplibregl-ctrl-icon { opacity: 0.95; }
/* The compact variants are named explicitly: MapLibre's own
   `.maplibregl-ctrl-attrib.maplibregl-compact` sets `background-color:#fff; color:#000` at two
   classes, so naming the variant here (three classes) wins outright instead of depending on the
   order of two <link> tags. */
.maplibregl-map .maplibregl-ctrl-attrib,
.maplibregl-map .maplibregl-ctrl-attrib.maplibregl-compact,
.maplibregl-map .maplibregl-ctrl-attrib.maplibregl-compact-show {
  background: rgba(12, 13, 15, 0.35);
  color: #9a9da5;
  font-size: 10px;
  line-height: 1.4;
  border-radius: 6px 0 0 0;
  opacity: 0.7;
  transition: opacity 0.15s ease;
}
.maplibregl-map .maplibregl-ctrl-attrib:hover { opacity: 1; }
.maplibregl-map .maplibregl-ctrl-attrib a { color: inherit; }
/* The compact toggle is a dark glyph on a white chip by default: inverted and dimmed to match. */
.maplibregl-map .maplibregl-ctrl-attrib-button {
  filter: invert(1);
  opacity: 0.4;
}
/* The hover mini card rides a MapLibre popup, whose stock chrome is white - restyled dark to
   belong to the map. Scoping under #live-map outranks the vendor stylesheet whatever the load
   order, and `.route-map` joins each selector for the other popup consumers, such as the hub
   network map. */
#live-map .maplibregl-popup-content,
.route-map .maplibregl-popup-content {
  background: #15151f;
  border: 1px solid #34344a;
  border-radius: 9px;
  padding: 10px 12px;
  box-shadow: 0 8px 22px rgba(0, 0, 0, 0.45);
}
#live-map .maplibregl-popup-anchor-bottom .maplibregl-popup-tip,
.route-map .maplibregl-popup-anchor-bottom .maplibregl-popup-tip { border-top-color: #34344a; }
#live-map .maplibregl-popup-anchor-top .maplibregl-popup-tip,
.route-map .maplibregl-popup-anchor-top .maplibregl-popup-tip { border-bottom-color: #34344a; }
#live-map .maplibregl-popup-anchor-left .maplibregl-popup-tip,
.route-map .maplibregl-popup-anchor-left .maplibregl-popup-tip { border-right-color: #34344a; }
#live-map .maplibregl-popup-anchor-right .maplibregl-popup-tip,
.route-map .maplibregl-popup-anchor-right .maplibregl-popup-tip { border-left-color: #34344a; }

/* ---- The Live Map's weather ----
   The Weather button at the map's top left opens the control: a popover under the button on a wide screen and, under
   720px, a drawer from the foot of the screen - the base weather as three equal buttons, the wind level while Wind is the
   base, the METAR stations switch, the opacity, the frame strip and the credits. While it is closed the map's own chip
   says what the map shows. The button and the chip sit ON the map, so they keep the map's concrete dark colours; the
   panel is the page's, and takes the theme's tokens so the light theme renders it light. */
.live-wx-btn {
  position: absolute;
  top: 10px;
  left: 10px;
  z-index: 3;
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  padding: 9px 12px;
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  line-height: normal;
  color: #eceded;
  background: rgba(20, 20, 26, 0.92);
  border: 1px solid #4a3387;
  border-radius: 10px;
  cursor: pointer;
}
.live-wx-btn:hover,
.live-wx-btn[aria-expanded="true"] { border-color: #8b6be0; }
.live-wx-cloud {
  flex: none;
  width: 16px;
  height: 16px;
  fill: none;
  stroke: #a672f5;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.live-wx-chip {
  position: absolute;
  left: 10px;
  bottom: 10px;
  z-index: 2;
  max-width: calc(100% - 60px);
  margin: 0;
  padding: 5px 9px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 12px;
  line-height: 1.4;
  color: #cfcfdd;
  background: rgba(17, 17, 24, 0.9);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 8px;
  pointer-events: none;
}
.live-wx-chip-muted { color: #a3a6ad; }
/* 380px: the drawer's own strip - the time, the three buttons and the span - fits inside it, as it does in a 390px phone's
   drawer. */
.live-wx-panel {
  position: absolute;
  top: 56px;
  left: 10px;
  z-index: 5;
  width: 380px;
  max-width: calc(100% - 20px);
  max-height: calc(100% - 66px);
  overflow-y: auto;
  overscroll-behavior: contain;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 10px 16px 18px;
  line-height: 1.4;
  color: var(--text-primary);
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: 14px;
  box-shadow: var(--shadow-2);
}
.live-wx-handle {
  display: none;
  width: 40px;
  height: 4px;
  margin: 0 auto 4px;
  border-radius: 2px;
  background: var(--border-strong);
}
.live-wx-head { display: flex; align-items: center; justify-content: space-between; }
.live-wx-heading { font-size: 17px; font-weight: 700; }
.live-wx-close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  margin: 0;
  padding: 0;
  font: inherit;
  font-size: 22px;
  line-height: 1;
  color: var(--text-muted);
  background: transparent;
  border: 0;
  border-radius: 8px;
  cursor: pointer;
}
.live-wx-close:hover { color: var(--text-primary); }
.live-wx-title {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  color: var(--text-muted);
}
.live-wx-title-note { font-weight: 500; letter-spacing: 0; text-transform: none; }
.live-wx-choices { display: flex; gap: 8px; margin-top: 8px; }
.live-wx-choice,
.live-wx-level {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  margin: 0;
  padding: 8px 12px;
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  line-height: 1.2;
  color: var(--text-primary);
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 8px;
  cursor: pointer;
}
.live-wx-choice { flex: 1; min-width: 0; }
/* The base buttons render 62px tall: 44px of content inside their 8px of padding and 1px border.
   The wind levels keep the 44px touch target. */
.live-wx-choice { min-height: 62px; }
.live-wx-choice:hover,
.live-wx-level:hover { border-color: var(--border-strong); }
.live-wx-choice[aria-checked="true"],
.live-wx-level[aria-checked="true"] {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 18%, transparent);
}
.live-wx-levels { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin-top: 8px; }
.live-wx-level { flex-direction: column; padding: 4px 6px; font-size: 13px; }
.live-wx-level small { font-size: 11px; font-weight: 500; color: var(--text-muted); }
.live-wx-note { margin-top: 8px; font-size: 12px; line-height: 1.45; color: var(--text-muted); }
.live-wx-row { display: flex; align-items: center; justify-content: space-between; min-height: 44px; font-size: 15px; }
.live-wx-switch {
  position: relative;
  flex: none;
  width: 44px;
  height: 24px;
  margin: 0;
  padding: 0;
  background: var(--border-strong);
  border: 0;
  border-radius: 12px;
  cursor: pointer;
}
.live-wx-switch[aria-checked="true"] { background: var(--accent); }
.live-wx-knob {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: #ffffff;
}
.live-wx-switch[aria-checked="true"] .live-wx-knob { left: 23px; }
.live-wx-opacity-head { display: flex; align-items: baseline; justify-content: space-between; }
.live-wx-value { font-size: 12px; color: var(--text-muted); }
/* The slider: a 4px track filled in the accent up to a 22px thumb. The fill follows the thumb's
   centre through --live-wx-fraction, which the page sets as the value moves. */
.live-wx-range {
  --live-wx-fraction: 0.625;
  display: block;
  width: 100%;
  height: 28px;
  margin: 2px 0 0;
  padding: 0;
  background: transparent;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}
.live-wx-range::-webkit-slider-runnable-track {
  height: 4px;
  border-radius: 2px;
  background: linear-gradient(to right,
    var(--accent) calc(11px + (100% - 22px) * var(--live-wx-fraction)),
    var(--border) calc(11px + (100% - 22px) * var(--live-wx-fraction)));
}
.live-wx-range::-webkit-slider-thumb {
  width: 22px;
  height: 22px;
  margin-top: -9px;
  border-radius: 50%;
  background: #eceded;
  border: 2px solid var(--accent);
  -webkit-appearance: none;
  appearance: none;
}
.live-wx-range::-moz-range-track { height: 4px; border-radius: 2px; background: var(--border); }
.live-wx-range::-moz-range-progress { height: 4px; border-radius: 2px; background: var(--accent); }
.live-wx-range::-moz-range-thumb {
  box-sizing: border-box;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: #eceded;
  border: 2px solid var(--accent);
}
.live-wx-credits { font-size: 11px; line-height: 1.45; color: var(--text-muted); }
/* The hover card's model wind: its quietest line. */
.live-hover-wind { font-size: 11px; color: #979aa1; margin-top: 4px; }

/* A phone: the drawer from the foot of the screen, over the page, with its handle. */
@media (max-width: 720px) {
  .live-wx-panel {
    position: fixed;
    top: auto;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 60;
    width: auto;
    max-width: none;
    max-height: min(85vh, calc(100vh - 56px));
    padding-bottom: calc(18px + env(safe-area-inset-bottom, 0px));
    border-width: 1px 0 0;
    border-radius: 18px 18px 0 0;
    box-shadow: 0 -12px 34px rgba(0, 0, 0, 0.45);
    animation: live-wx-rise 160ms ease-out;
  }
  .live-wx-handle { display: block; }
}
@keyframes live-wx-rise {
  from { transform: translateY(24px); opacity: 0; }
  to { transform: none; opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .live-wx-panel { animation: none; }
}

.activity-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.activity-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px 18px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 14px 18px;
  /* The site's card lift. */
  transition: border-color 0.15s ease, transform 0.15s ease;
}

/* ---- type-ahead suggestion dropdowns (pilot forms) ---- */

.suggest-wrap {
  position: relative;
}

.suggest-list {
  position: absolute;
  /* top is set from JS to the input's bottom edge, so the list hangs off the
     field itself and not below any hint/feedback text under it. */
  left: 0;
  right: 0;
  z-index: 30;
  margin-top: 4px;
  background: var(--surface-2);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  max-height: 260px;
  overflow-y: auto;
  box-shadow: 0 12px 28px rgba(0, 0, 0, 0.35);
}

.suggest-item {
  display: block;
  width: 100%;
  text-align: left;
  padding: 9px 12px;
  background: none;
  border: 0;
  color: var(--text-primary);
  cursor: pointer;
  font: inherit;
  font-size: 0.92rem;
}

/* .active is the KEYBOARD highlight (aria-activedescendant). The options are not tab stops - this is
   a combobox, so the field keeps focus and Arrow/Enter work the list - which means :focus never fires
   on them and this class is the only thing a keyboard pilot can see. */
.suggest-item:hover,
.suggest-item:focus,
.suggest-item.active {
  background: var(--surface-3);
  outline: none;
}

.suggest-item .suggest-sub {
  display: block;
  color: var(--text-muted);
  font-size: 0.8rem;
}

/* Country + flag. A flex row rather than a margin on the image: the gap belongs to the layout,
   and it then also applies wherever a country is shown as flag + name outside a suggestion list. */
.country,
.suggest-item.suggest-country {
  display: flex;
  align-items: center;
  gap: 8px;
}


/* Spacing under the credited-experience line on the pilot dashboard. */
.stat-note {
  margin: 10px 0 0;
  font-size: 0.86rem;
}

.country-flag {
  /* Fixed box so a column of countries lines up regardless of each flag's own proportions, and a
     1px edge because several flags are mostly white and would dissolve into the panel behind. */
  width: 20px;
  height: 15px;
  flex: 0 0 auto;
  object-fit: cover;
  border-radius: 2px;
  border: 1px solid var(--border);
}

/* Live field validity feedback (pilot forms): airport codes confirm
   valid (with the resolved airport) or flag not-recognised as you type. */
.field-feedback {
  margin: 6px 0 0;
  font-size: 0.82rem;
  line-height: 1.4;
}

.field-feedback-ok {
  color: var(--success);
}

.field-feedback-error {
  color: var(--danger);
}

/* Activity rows that link somewhere (pilot PIREP history/detail) keep
   the row styling, not link styling. */
a.activity-row {
  text-decoration: none;
  color: inherit;
}

/* Every row lifts, linked or not - My PIREPs' rows carry their link inside ("View report"), and
   the rows of one list should not move differently from each other. */
.activity-row:hover {
  border-color: var(--border-strong);
  transform: translateY(-2px);
}
@media (prefers-reduced-motion: reduce) {
  .activity-row { transition: none; }
  .activity-row:hover { transform: none; }
}

.activity-row .flight-no {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 1.02rem;
  min-width: 84px;
}

.activity-row .route {
  flex: 1;
  min-width: 220px;
}

/* Uniform route geometry in activity rows: both ends get a fixed width, so
   every row's dashed line spans the same region and the plane sits at the
   same spot on every row - otherwise varying airport/city text widths shift
   the midpoint and the plane reads as flight progress. */
.activity-row .route .route-end {
  width: 112px;
  flex: none;
}

.activity-row .activity-meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  margin-left: auto;
  /* Reserve consistent space so varying pilot-name/badge widths do not
     squeeze each row's route line differently (see .route-end note above). */
  min-width: 340px;
  justify-content: flex-end;
}

/* My PIREPs: the status chips keep their own height beside the taller File a PIREP button,
   matching the date chips below them. */
.pireps-status { align-items: center; margin-bottom: 18px; }

.activity-row .pilot {
  color: var(--text-secondary);
  font-size: 0.9rem;
}

.activity-row .when {
  color: var(--text-muted);
  font-size: 0.83rem;
  min-width: 90px;
  text-align: right;
}

/* ---- loading / empty / error states ---- */

.state {
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-md);
  padding: 34px 26px;
  text-align: center;
  color: var(--text-muted);
}

.state p {
  margin: 6px 0 14px;
}

.state-icon {
  font-size: 1.7rem;
  color: var(--accent-bright);
}

.state-loading {
  border-style: solid;
  text-align: unset;
}

.skeleton {
  height: 18px;
  border-radius: 6px;
  margin: 12px 0;
  background: linear-gradient(90deg, var(--surface-2) 25%, var(--surface-3) 50%, var(--surface-2) 75%);
  background-size: 200% 100%;
  animation: shimmer 1.4s infinite;
}

.skeleton:nth-child(2) { width: 82%; }
.skeleton:nth-child(3) { width: 64%; }

@keyframes shimmer {
  to { background-position: -200% 0; }
}

/* Reduced motion: no shimmer, and a solid tone. A stopped 200%-wide gradient leaves the bar's
   left quarter the colour of the card behind it, so the bar looks shifted. */
@media (prefers-reduced-motion: reduce) {
  .skeleton { animation: none; background: var(--surface-3); }
}

.state-error {
  border-color: color-mix(in srgb, var(--danger) 45%, transparent);
  color: var(--danger);
}

/* ---- pilot pages (login/dashboard, wired to the vaBase pilot session
        endpoints) ---- */

.muted {
  color: var(--text-muted);
}

.form-error {
  background: color-mix(in srgb, var(--danger) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--danger) 45%, transparent);
  border-radius: var(--radius-sm);
  color: var(--danger);
  font-size: 0.88rem;
  padding: 10px 12px;
  margin: 14px 0 0;
}

.auth-shell {
  max-width: 420px;
  margin: 70px auto;
}

.auth-card {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-2);
  padding: 34px 32px;
  /* Same lift as .card: on the join page the terms panel beside the form is a .card, and the
     two should move alike on hover. */
  transition: border-color 0.15s ease, transform 0.15s ease;
}

.auth-card:hover {
  border-color: var(--border-strong);
  transform: translateY(-2px);
}

.auth-card h1 {
  margin: 0 0 6px;
  font-size: 1.5rem;
}

.auth-card .auth-sub {
  color: var(--text-muted);
  font-size: 0.92rem;
  margin-bottom: 22px;
}

.auth-card label {
  display: block;
  font-size: 0.84rem;
  font-weight: 600;
  color: var(--text-secondary);
  margin: 14px 0 6px;
}

/* Text-like controls only. The same exclusion .va-form carries, and for the same reason: a
   checkbox given the full-width, padded, bordered text-input treatment inflates into an
   oversized empty box. The join page renders an airline's own tick-box questions here. */
.auth-card input:not([type="radio"]):not([type="checkbox"]) {
  width: 100%;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  font-family: inherit;
  font-size: 0.96rem;
  padding: 11px 14px;
}

/* Autofilled fields keep the dark treatment.

   Chromium paints its own background on a field it autofilled and ignores `background`
   completely, so a saved email or password turns the join and login fields bright white against
   the dark card. The only thing that reaches it is an inset box-shadow large enough to cover the
   field, plus -webkit-text-fill-color for the text - the long-standing workaround, which the
   Admin Portal uses too.

   All four states are listed deliberately. Chromium keeps the autofill styling through hover,
   focus and active, and a rule naming only the bare state loses to any :focus rule that sets
   box-shadow - so the field would snap back to white the moment it was clicked. */
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
input:-webkit-autofill:active,
textarea:-webkit-autofill,
textarea:-webkit-autofill:focus,
select:-webkit-autofill,
select:-webkit-autofill:focus {
  -webkit-box-shadow: 0 0 0 100px var(--surface-1) inset;
  box-shadow: 0 0 0 100px var(--surface-1) inset;
  -webkit-text-fill-color: var(--text-primary);
  caret-color: var(--text-primary);
  /* Chromium animates the autofill background in; a long transition on it is the trick that
     stops the white flash being visible before the shadow lands. */
  transition: background-color 100000s ease-in-out 0s;
}


/* The auth card also holds an airline's own join questions, which can be long text or a choice
   list. Without these a textarea/select falls back to the browser's default chrome - a small
   grey box that matches nothing around it. */
.auth-card textarea,
.auth-card select {
  width: 100%;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  font-family: inherit;
  font-size: 0.96rem;
  padding: 11px 14px;
}

.auth-card textarea {
  min-height: 96px;
  resize: vertical;
}

/* The auth card's focus treatment is the base one (see "Focused form controls, everywhere" near
   the top). Do not list controls individually here: naming some and not others leaves the rest
   with a different ring from their neighbours. */

/* A group of related fields inside a form card. RECESSED rather than raised: the tokens step
   surfaces lighter with elevation, so surface-1 inside a surface-2 card reads as set into it -
   which is what a sub-group of one form is. A browser's default fieldset chrome (hairline box,
   legend notched into the top border) matches nothing else in the template, so the grouping is
   styled here and the heading is a normal element the fieldset points at with aria-labelledby. */
.form-group {
  margin: 18px 0 6px;
  padding: 14px 16px;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
}

/* Fieldsets carry browser defaults that would otherwise fight the box above. */
fieldset.form-group {
  min-inline-size: 0;
}

.form-group-title {
  margin: 0;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--text-primary);
}

/* The first control in a group needs no extra gap - the group's own padding is the gap. */
.form-group > label:first-of-type {
  margin-top: 4px;
}

/* Help text under a field: subordinate to its label and tight against its control. Distinct from
   .auth-sub, which is the card's own subtitle and carries a 22px gap meant for the top of a
   form, not for the space between a control and the next question. */
/* There is a single .field-hint rule, with the free-flight form styles further down; keep it to
   one. .hint is an alias - dispatch.html and submit-pirep.html use that name. */

/* A tick box sits BESIDE its wording, not under a heading of its own - which is what a block
   label above a lone checkbox looks like. Used by the join page's custom questions.

   Qualified `label.check-row` deliberately: `.auth-card label` and `.va-form label` are both
   (0,1,1) and would beat a bare `.check-row` (0,1,0) on SPECIFICITY however late it appears,
   leaving the row stubbornly display:block. Matching their specificity lets source order decide,
   which is the intent. */
label.check-row {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin: 14px 0 6px;
  font-weight: 500;
  color: var(--text-primary);
  cursor: pointer;
}

/* The box itself is drawn here rather than left to the browser. `accent-color` only tints a
   CHECKED native box - the unchecked state stays the platform's pale square with its own border
   radius and metrics, which on a dark card reads as a light grey chip that belongs to no part of
   this design. Replacing it is the only way to make the unchecked state match, and unchecked is
   the state it is in when someone is deciding whether to tick it. */
label.check-row input[type="checkbox"] {
  appearance: none;
  -webkit-appearance: none;
  flex: 0 0 auto;
  position: relative;
  width: 20px;
  height: 20px;
  /* Aligns the box with the CAP of the first line rather than its line box, so a label that
     wraps to two lines still has the tick beside the first word instead of floating. */
  margin: 1px 0 0;
  background: var(--surface-1);
  border: 1px solid var(--border-strong);
  border-radius: 6px;
  cursor: pointer;
  transition: background-color 0.14s ease, border-color 0.14s ease;
}

/* Hovering anywhere on the row lights the box - the whole row is the target, and it should look
   like it. */
label.check-row:hover input[type="checkbox"] {
  border-color: var(--accent-bright);
}

label.check-row input[type="checkbox"]:checked {
  background: var(--accent);
  border-color: var(--accent);
}

/* The tick: the two inner edges of a rotated box. Always present so it can be animated, revealed
   on :checked - a tick that scales up reads as "that registered", which matters for an agreement
   someone is being asked to make deliberately. */
label.check-row input[type="checkbox"]::after {
  content: "";
  position: absolute;
  left: 6px;
  top: 2px;
  width: 5px;
  height: 10px;
  border: solid var(--text-on-accent);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg) scale(0.4);
  opacity: 0;
  transition: opacity 0.12s ease, transform 0.12s ease;
}

label.check-row input[type="checkbox"]:checked::after {
  opacity: 1;
  transform: rotate(45deg) scale(1);
}

/* The base focus ring sits at -1px, which is right for a text field and wrong for a 20px box -
   it would draw the outline through the tick. Pushed outside instead. */
label.check-row input[type="checkbox"]:focus {
  outline-offset: 2px;
}


.auth-card .btn {
  width: 100%;
  justify-content: center;
  margin-top: 22px;
}

.notice {
  display: flex;
  gap: 10px;
  background: var(--accent-soft);
  border: 1px solid var(--accent-glow);
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  font-size: 0.88rem;
  padding: 12px 14px;
  margin-bottom: 18px;
}

/* The "reporting scheduled flight" banner on the PIREP form: icon +
   two-line label on the left, a Clear action pinned right. */
.schedule-banner {
  display: flex;
  align-items: center;
  gap: 14px;
  background: var(--accent-soft);
  border: 1px solid var(--accent-glow);
  border-radius: var(--radius-md);
  padding: 14px 16px;
  margin-bottom: 18px;
}

.schedule-banner-icon {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--accent) 26%, transparent);
  color: var(--text-primary);
  font-size: 1rem;
}

.schedule-banner-body {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.schedule-banner-body strong {
  font-size: 0.98rem;
  letter-spacing: 0.01em;
}

.schedule-banner-sub {
  color: var(--text-secondary);
  font-size: 0.82rem;
}

.btn-sm {
  padding: 6px 14px;
  font-size: 0.85rem;
}

/* ---- footer ---- */

.site-footer {
  margin-top: 70px;
  border-top: 1px solid var(--border);
  background: var(--surface-1);
  padding: 40px 0 30px;
  color: var(--text-muted);
  font-size: 0.9rem;
}

.site-footer .footer-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 20px 60px;
  margin-bottom: 22px;
}

.site-footer h4 {
  margin: 0 0 8px;
  font-size: 0.82rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-secondary);
}

.site-footer [data-va-contact-links] {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 18px;
}

.site-footer .footer-note {
  border-top: 1px solid var(--border);
  padding-top: 18px;
  display: flex;
  flex-wrap: wrap;
  gap: 10px 24px;
  justify-content: space-between;
}

/* ---- utility ---- */

.page-title {
  padding: var(--page-top) 0 6px;
}

.page-title h1 {
  margin: 0 0 6px;
  font-size: var(--page-title-size);
  letter-spacing: -0.02em;
}

.page-title p {
  margin: 0;
  color: var(--text-muted);
  max-width: 640px;
}

/* ---- pilot flight ops ---- */

/* Generic form styling for pilot forms outside the auth card (free flight). */
.va-form label {
  display: block;
  font-size: 0.84rem;
  font-weight: 600;
  color: var(--text-secondary);
  margin: 14px 0 6px;
}

/* Text-like controls only: a radio/checkbox must never take the full-width, padded, bordered
   text-input treatment - it inflates the control into an oversized box. */
.va-form input:not([type="radio"]):not([type="checkbox"]),
.va-form select,
.va-form textarea {
  width: 100%;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  font-family: inherit;
  font-size: 0.96rem;
  padding: 11px 14px;
}

.va-form input:focus,
.va-form select:focus,
.va-form textarea:focus {
  outline: 2px solid var(--accent);
  outline-offset: -1px;
}

/* A field holding a code renders uppercase. Codes are uppercase everywhere else in vaBase - the
   feedback line under the box answers "EGLL - London Heathrow Airport" - so the input should not
   be the one place they are not.

   Same name as the Admin Portal's own rule rather than a second convention: the two stylesheets
   are separate deployables (nothing shared can reach both), but one platform should not have two
   words for one idea.

   Display only, deliberately: the value stays exactly as typed, and every code this is used on is
   resolved case-insensitively server-side (an airport, a registration, a flight number all
   canonicalise there). Nothing here is relied on as normalisation. */
.input-uppercase {
  text-transform: uppercase;
}

.va-form .form-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: 0 14px;
}

/* Route strings and briefing text on the dispatch page. */
.route-block {
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 12px 14px;
  overflow-wrap: anywhere;
}

/* Inline aircraft picker that appears on a route card while booking. */
.book-picker {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 12px;
}

/* Room for the browser's own arrow, which is drawn inside the padding box at the right edge -
   with the same 14px both sides it sits hard against the border.

   Every selector is listed explicitly, and this rule sits after the ones that set the padding
   shorthand. An unqualified element rule would lose: .auth-card select and .va-form select are
   class-qualified, so they outrank it whatever it says. The bare selector stays in the list to
   cover any select that is not inside one of those wrappers. */
select,
.auth-card select,
.va-form select,
.book-picker select {
  /* The arrow is OURS, not the browser's. padding-right alone does nothing: Chromium pins the
     native arrow to the border edge and ignores the padding, so the gap has to be made by
     replacing the arrow rather than by reserving space beside it. appearance:none removes the
     native one (in Firefox too, which is why the background image is not optional), and the
     chevron is positioned exactly where we want it.

     A data URI rather than a file: nothing to fetch, nothing to 404, no asset to keep in step
     with two vendored copies. The stroke colour is baked in, so the light theme overrides it
     below - a data URI cannot read a CSS variable. */
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%23979aa1' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  padding-right: 38px;
}

[data-theme="light"] select,
[data-theme="light"] .auth-card select,
[data-theme="light"] .va-form select,
[data-theme="light"] .book-picker select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%236b6f7a' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}

.book-picker select {
  flex: 1;
  min-width: 160px;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  font-family: inherit;
  font-size: 0.9rem;
  padding: 8px 10px;
}

[hidden] {
  display: none !important;
}

/* Free-flight form: airport feedback, unlisted-location fields, codeshare + planning.
   These use this stylesheet's token names - --border / --text-muted / --text-primary. The ACARS
   Electron app names the same ideas --line / --muted / --text; because var() silently falls back,
   a token name from the wrong stylesheet breaks nothing loudly, it just paints the wrong colour.
   Never give a theme token a hard-coded fallback here: :root always defines them, so a fallback
   can only ever hide a typo. */
.field-hint,
.hint {
  margin: 4px 0 0;
  font-size: 12px;
  line-height: 1.45;
  color: var(--text-muted);
  min-height: 14px;
}
/* Airport codes are uppercase, so the field shows them that way as you type. Display only - .value is
   unchanged, and the server uppercases both the resolve and the search itself, so typing a name or
   city in any case still matches. The placeholder is exempted: it is prose, not a code. */
.airport-code { text-transform: uppercase; }
/* The class is primarily a DISPLAY style (bold codes on cards); on an INPUT the form rules
   override its size/family but its 700 weight leaked into the hint text, rendering every
   "Code, name or city" placeholder bold. A hint is a hint: normal weight, normal case. */
.airport-code::placeholder { text-transform: none; font-weight: 400; }
/* Semantic tokens, not hard-coded hexes: #1a7f37 and #b26a00 are light-theme greens/ambers that only
   reach ~3.7:1 and ~4.4:1 on this dark surface - under the 4.5:1 needed for body text - and they would
   not follow a customer's palette. The tokens clear 8:1 here and adapt with the theme. */
.field-hint.ok { color: var(--success); }
.field-hint.warn { color: var(--warning); }
/* Optional planning details: reachable, but never competing with the required fields above it. */
.optional-details {
  margin: 14px 0 0;
  border-top: 1px solid var(--border);
  padding-top: 8px;
}
.optional-details > summary {
  cursor: pointer;
  font-size: 13px;
  color: var(--text-muted);
  padding: 2px 0;
}
.optional-details > summary:hover { color: var(--text-primary); }
.unlisted-fields {
  margin: 8px 0 4px;
  padding: 12px 14px;
  border: 1px dashed var(--border);
  border-radius: 10px;
}
.unlisted-fields legend { font-size: 12px; padding: 0 6px; color: var(--text-muted); }
/* A segmented option control: each choice is a pill matching the height/border of the text inputs
   beside it. nowrap keeps a two-word option ("Manual route") on one line in a narrow column. */
/* flex-wrap is a SAFETY NET, not a layout choice: the pills carry white-space: nowrap, so their
   min-content width cannot shrink. Without wrapping they OVERFLOW their grid column and overlap the
   next field - measured at -0.53px of gap at the form's 760px max-width, and worsening to -40px as
   the form narrows. Wrapping makes a too-narrow column stack them instead of colliding. */
.radio-row { display: flex; gap: 8px; flex-wrap: wrap; }
.radio-row .radio {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  flex: 1; margin: 0; padding: 11px 10px; white-space: nowrap; cursor: pointer;
  font-weight: 400; font-size: 0.96rem; color: var(--text-primary);
  /* Match the text inputs beside it exactly. They resolve line-height to `normal`; the pill would
     otherwise inherit the body's 1.6 and stand 3.56px taller than every input on its row. */
  line-height: normal;
  background: var(--surface-1); border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}
.radio-row .radio:has(input:checked) {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 10%, var(--surface-1));
}
/* Draw the dot ourselves: the platform's unchecked radio is a filled disc that reads louder than the
   SELECTED option. It stays a real <input type="radio"> - native keyboard/screen-reader behaviour is
   untouched - and uses the theme tokens, so a customer's palette carries through. */
.radio-row input[type="radio"] {
  appearance: none; -webkit-appearance: none;
  flex: none; width: 14px; height: 14px; margin: 0; padding: 0;
  border: 1px solid var(--border); border-radius: 50%; background: transparent;
}
.radio-row input[type="radio"]:checked {
  border-color: var(--accent);
  background: radial-gradient(circle, var(--accent) 0 3.5px, transparent 4px);
}
.radio-row input[type="radio"]:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.codeshare-note { align-self: end; font-size: 13px; color: var(--warning); }

/* ==========================================================================
   Dispatch brief provider chooser, vaBase brief editor + confirmed view, and
   the shared weather panel. All built from the same tokens as the rest of
   the template so a customer's palette carries through, and reusing the
   existing .card / .va-form / .field-hint / .badge conventions. */

/* Method chooser: two equal option cards side by side, stacking when narrow. */
.method-chooser {
  display: grid; gap: 12px; margin-top: 12px;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}
.method-option {
  display: flex; flex-direction: column; gap: 6px; text-align: left;
  padding: 16px; cursor: pointer; font: inherit; color: var(--text-primary);
  background: var(--surface-1); border: 1px solid var(--border);
  border-radius: var(--radius-md); transition: border-color .15s, background .15s;
}
.method-option:hover {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 8%, var(--surface-1));
}
.method-option strong { font-size: 1rem; }
.method-option .method-option-desc { font-size: 0.9rem; color: var(--text-muted); }

/* The vaBase brief editor sits inside a .card; keep its fields compact. */
.vabase-editor { margin-top: 6px; }
.vabase-editor textarea { min-height: 52px; }
.field-hint.provenance { color: var(--accent-bright); font-size: 12px; }

/* Fuel breakdown: label / value rows, with an emphasised block-fuel total. */
.fuel-section { margin-top: 14px; }
.fuel-section h4 { margin: 0 0 6px; font-size: 0.95rem; }
.fuel-breakdown {
  display: flex; flex-direction: column; gap: 2px;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: 8px 12px; background: var(--surface-1);
}
.fuel-row {
  display: flex; align-items: baseline; gap: 8px;
  padding: 3px 0; font-size: 0.92rem;
}
.fuel-row .fuel-label { color: var(--text-muted); }
.fuel-row .fuel-value { margin-left: auto; color: var(--text-primary); font-variant-numeric: tabular-nums; }
.fuel-row .fuel-source { flex: none; color: var(--text-muted); font-size: 11px; }
.fuel-row-total {
  margin-top: 4px; padding-top: 8px; border-top: 1px solid var(--border);
  font-weight: 600;
}
.fuel-row-total .fuel-label, .fuel-row-total .fuel-value { color: var(--text-primary); }

/* Confirmed brief header: the provider badge plus revision/time line. */
.brief-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 10px; }

/* Weather panel: one honest station card per airport. */
.weather-grid {
  display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
}
.weather-station {
  background: var(--surface-1); border: 1px solid var(--border);
  border-radius: var(--radius-md); padding: 14px;
}
.weather-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.weather-icao { display: flex; align-items: baseline; gap: 8px; }
.weather-icao strong { font-size: 1.05rem; }
.weather-role { font-size: 12px; color: var(--text-muted); }
.weather-metar, .weather-taf {
  margin: 8px 0 0; font-size: 12px; line-height: 1.5; color: var(--text-secondary);
  white-space: pre-wrap; word-break: break-word;
}
.weather-foot { margin: 8px 0 0; font-size: 11px; color: var(--text-muted); }

/* The SimBrief brief fills the page width (only one provider region shows at a time), and its
   fuel/weights/times sections lay out in responsive columns rather than a deep column. */
.brief-regions > .card { margin-bottom: 16px; }

/* Route-map thumbnail gallery + a self-contained image lightbox modal. */
.simbrief-maps {
  display: grid; gap: 12px; margin-top: 12px;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
}
.simbrief-map-thumb {
  display: flex; flex-direction: column; gap: 6px; padding: 6px; cursor: pointer;
  background: var(--surface-1); border: 1px solid var(--border);
  border-radius: var(--radius-sm); text-align: center;
}
.simbrief-map-thumb:hover { border-color: var(--accent); }
.simbrief-map-thumb img { width: 100%; height: 130px; object-fit: cover; border-radius: 4px; }
.simbrief-map-name { font-size: 12px; color: var(--text-muted); }

.va-modal {
  position: fixed; inset: 0; z-index: 1000;
  display: flex; align-items: center; justify-content: center; padding: 24px;
  background: rgba(0, 0, 0, 0.82);
}
.va-modal-body { position: relative; max-width: 96vw; max-height: 92vh; display: flex; flex-direction: column; }
.va-modal-body img {
  max-width: 96vw; max-height: 84vh; object-fit: contain;
  border-radius: var(--radius-md); background: #fff;
}
.va-modal-caption { margin: 8px 0 0; text-align: center; color: #eee; font-size: 13px; }
.va-modal-close {
  position: absolute; top: -14px; right: -14px; width: 36px; height: 36px;
  display: flex; align-items: center; justify-content: center;
  font-size: 22px; line-height: 1; cursor: pointer; color: var(--text-primary);
  background: var(--surface-2); border: 1px solid var(--border); border-radius: 50%;
}
.va-modal-close:hover { border-color: var(--accent); }

/* The confirmed-plan layout - a route ribbon, KPI tiles, weight-headroom meters and a
   fuel-proportion bar, so the brief reads like an operational dashboard. */

/* Route ribbon: departure -> arrival with the leg on the line, the alternate branching below. */
.brief-ribbon {
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 16px;
  padding: 16px 18px; margin: 4px 0 14px;
  background: var(--surface-1); border: 1px solid var(--border); border-radius: var(--radius-md);
}
.ribbon-end { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ribbon-r { text-align: right; }
.ribbon-role { font-size: 11px; text-transform: uppercase; letter-spacing: .07em; color: var(--text-muted); }
.ribbon-code { font-family: var(--font-mono); font-size: 22px; font-weight: 600; color: var(--text-primary); line-height: 1.15; }
.ribbon-name { font-size: 13px; color: var(--text-secondary); }
.ribbon-sub { font-size: 12px; color: var(--text-muted); }
.ribbon-proc { font-size: 12px; color: var(--text-muted); font-family: var(--font-mono); }
.ribbon-mid { min-width: 120px; text-align: center; }
.ribbon-leg { display: block; margin-bottom: 5px; font-size: 12px; color: var(--text-secondary); font-variant-numeric: tabular-nums; }
.ribbon-line { position: relative; height: 18px; }
.ribbon-line::before { content: ""; position: absolute; top: 50%; left: 0; right: 0; border-top: 2px dashed var(--border-strong); }
.ribbon-line::after {
  content: "\2708"; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -54%);
  color: var(--accent-bright); background: var(--surface-1); padding: 0 6px; font-size: 0.95rem;
}
.ribbon-altn {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: -8px 0 14px; padding: 10px 14px;
  font-size: 13px; color: var(--text-secondary);
  background: var(--surface-1); border: 1px dashed var(--border-strong); border-radius: var(--radius-sm);
}
.ribbon-altn-tag { font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--text-muted); }
.ribbon-altn .ribbon-code { font-size: 15px; }
/* The alternate's name/runway text has a rule of its own, like the tag and code beside it,
   rather than inheriting 13px secondary from .ribbon-altn. */
.ribbon-altn-detail { font-size: 13px; color: var(--text-secondary); }
@media (max-width: 560px) {
  .brief-ribbon { grid-template-columns: 1fr; }
  .ribbon-r, .ribbon-mid { text-align: left; }
}

/* The full ICAO route line, moved below the ribbon + alternate. */
.brief-route { margin-bottom: 14px; }
.brief-route-label { display: block; margin-bottom: 6px; font-size: 11px; text-transform: uppercase; letter-spacing: .07em; color: var(--text-muted); }
.brief-route .route-block { margin: 0; }

/* The dispatch summary shares the brief's building blocks - the route is the ribbon, the facts
   are KPI tiles, and the lifecycle metadata is a demoted quiet line. */
.brief-route-region { display: block; }
.brief-summary { display: block; }
.brief-meta { display: flex; flex-wrap: wrap; gap: 6px 18px; margin-top: 2px; font-size: 12px; }
.meta-item { display: inline-flex; gap: 5px; }
.meta-k { color: var(--text-muted); }
.meta-v { color: var(--text-secondary); font-variant-numeric: tabular-nums; }

/* KPI tiles: the headline figures a pilot checks first. */
.brief-kpis {
  display: grid; gap: 12px; margin-bottom: 14px;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
}
.kpi-tile { padding: 12px 14px; background: var(--surface-1); border-radius: var(--radius-sm); }
.kpi-k { display: block; font-size: 12px; color: var(--text-muted); }
/* The aircraft's quiet edit pencil, beside the tile's label. */
.kpi-edit {
  display: inline-flex; align-items: center; gap: 4px; margin-left: 8px; padding: 1px 4px;
  border: 0; border-radius: 6px; background: none; color: var(--accent); font: inherit; font-size: 12px;
  font-weight: 600; text-decoration: none; cursor: pointer; vertical-align: baseline;
}
.kpi-edit .icon { width: 12px; height: 12px; }
.kpi-edit:hover { background: color-mix(in srgb, var(--accent) 12%, transparent); }
.kpi-edit:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.kpi-v { display: block; margin-top: 3px; font-size: 1.45rem; font-weight: 600; color: var(--text-primary); font-variant-numeric: tabular-nums; line-height: 1.1; }
.kpi-v small { font-size: 0.72rem; font-weight: 400; color: var(--text-muted); margin-left: 3px; }

/* Weights + Fuel panels, side by side on a wide brief. */
.brief-panels {
  display: grid; gap: 16px; margin-bottom: 14px; align-items: start;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}
.brief-card {
  padding: 14px 16px; background: var(--surface-1);
  border: 1px solid var(--border); border-radius: var(--radius-md);
}
.brief-h { margin: 0 0 12px; font-size: 0.95rem; font-weight: 600; color: var(--text-secondary); }
.brief-h-row { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 12px; }
.brief-h-row .brief-h { margin: 0; }
.brief-total { font-size: 1rem; font-weight: 600; color: var(--text-primary); font-variant-numeric: tabular-nums; }
.brief-total small { font-size: 0.72rem; font-weight: 400; color: var(--text-muted); }
.brief-flat { display: flex; align-items: baseline; gap: 10px; padding: 6px 0; font-size: 0.9rem; border-top: 1px solid var(--border); }
.brief-flat .k { color: var(--text-muted); }
.brief-flat .v { margin-left: auto; text-align: right; color: var(--text-primary); font-variant-numeric: tabular-nums; }

/* Weight headroom meters. */
.wt-meter { margin-bottom: 14px; }
.wt-meter:last-child { margin-bottom: 0; }
.wt-top { display: flex; justify-content: space-between; align-items: baseline; font-size: 0.9rem; }
.wt-label { color: var(--text-secondary); }
.wt-val { color: var(--text-primary); font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.wt-max { color: var(--text-muted); }
.meter { height: 8px; margin: 7px 0 4px; background: var(--surface-2); border-radius: 999px; overflow: hidden; }
.meter-fill { display: block; height: 100%; border-radius: 999px; background: var(--accent); }
.meter-warn { background: var(--warning); }
.meter-danger { background: var(--danger); }
.wt-cap { font-size: 11px; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.wt-cap-warn { color: var(--warning); }
.wt-cap-danger { color: var(--danger); }

/* Fuel proportion bar + legend. Segments share one accent-derived ramp so they read as one thing
   and adapt to the tenant's configured accent colour. */
.fuel-bar { display: flex; height: 14px; gap: 2px; border-radius: 6px; overflow: hidden; background: var(--surface-2); }
.fuel-seg { display: block; height: 100%; }
.fuel-legend { display: flex; flex-wrap: wrap; gap: 10px 16px; margin-top: 12px; font-size: 12px; }
.fuel-leg-item { display: inline-flex; align-items: center; gap: 6px; color: var(--text-secondary); }
.fuel-swatch { width: 10px; height: 10px; border-radius: 2px; flex: none; }
/* The legend's two halves, each with a rule of its own. The label's colour is the one it would
   inherit from .fuel-leg-item, stated explicitly so the pair is styled as a pair. */
.fuel-leg-label { color: var(--text-secondary); }
.fuel-leg-val { color: var(--text-primary); font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.fuel-sub { margin: 12px 0 0; font-size: 12px; color: var(--text-muted); }
.seg-taxi { background: color-mix(in srgb, var(--accent) 22%, var(--surface-2)); }
.seg-trip { background: color-mix(in srgb, var(--accent) 45%, var(--surface-2)); }
.seg-contingency { background: color-mix(in srgb, var(--accent) 62%, var(--surface-2)); }
.seg-alternate { background: var(--accent); }
.seg-reserve { background: color-mix(in srgb, var(--accent) 80%, var(--surface-2)); }
.seg-extra { background: var(--accent-bright); }

/* Times + conditions: compact inline facts, with a compass arrow for the average wind. */
.brief-conditions {
  display: flex; flex-wrap: wrap; gap: 10px 20px; align-items: center; padding: 12px 16px;
  background: var(--surface-1); border: 1px solid var(--border); border-radius: var(--radius-md);
}
.cond { display: inline-flex; align-items: baseline; gap: 6px; font-size: 0.85rem; }
.cond-k { color: var(--text-muted); }
.cond-v { color: var(--text-primary); font-variant-numeric: tabular-nums; }
.cond-wind { align-self: center; display: inline-flex; color: var(--accent-bright); }
.cond-wind::before { content: "\2191"; display: inline-block; font-size: 14px; line-height: 1; transform: rotate(var(--dir, 0deg)); }

/* The full-OFP printout is SimBrief's light/print HTML. In dark mode the iframe is colour-
   inverted (hue-rotate keeps the blue headers blue) so it fits the theme; the border + rounding live
   on the wrapper so they are not inverted with it. A light-themed site keeps the native print look. */
.ofp-frame {
  margin-top: 10px; overflow: hidden; background: #0c0d0f;
  border: 1px solid var(--border); border-radius: 8px;
}
.ofp-frame iframe { display: block; filter: invert(1) hue-rotate(180deg); }
[data-theme="light"] .ofp-frame { background: #fff; }
[data-theme="light"] .ofp-frame iframe { filter: none; }

/* The aircraft-type control sits in its own subtle card so the action does not detach from the
   summary (matching the brief's card rhythm). */
#dispatch-type-card {
  padding: 14px 16px;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
}

/* The dispatch-page aircraft-type picker select, themed like the form inputs so the chosen type
   is legible (unstyled, it renders as a bare caret box). */
#dispatch-type-select, #dispatch-airframe-select {
  flex: 1 1 200px; min-width: 180px; max-width: 360px;
  padding: 8px 10px; font: inherit;
  color: var(--text-primary); background: var(--surface-2);
  border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
}
#dispatch-type-select:focus, #dispatch-airframe-select:focus { outline: none; border-color: var(--accent); }
/* The two ways to bind the aircraft (a specific fleet airframe, or any aircraft of a type). */
.ac-pick-title { display: block; margin-bottom: 10px; font-size: 0.85rem; font-weight: 600; color: var(--text-secondary); }
.ac-pick-row { margin-bottom: 12px; }
.ac-pick-row:last-of-type { margin-bottom: 0; }
.ac-pick-label { display: block; margin-bottom: 6px; font-size: 0.78rem; color: var(--text-muted); }

/* The cancel-reason field, themed like the other inputs. */
#brief-cancel-confirm label { display: block; font-size: 0.85rem; color: var(--text-secondary); }
#brief-cancel-reason {
  display: block; width: 100%; max-width: 420px; margin-top: 6px;
  padding: 10px 12px; font: inherit;
  color: var(--text-primary); background: var(--surface-1);
  border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
}
#brief-cancel-reason:focus { outline: none; border-color: var(--accent); }

/* ---- stacked cards ----
   `.card` carries no margin on purpose - most cards live in `.card-grid`, whose gap spaces
   them - so cards stacked straight down a page sit flush against each other with their borders
   touching, which reads as one broken panel rather than several. Every page that stacks them
   wraps them in this. Mirrors the Admin Portal's `.card-stack`, which exists for the same
   reason. */
.card-stack {
  display: flex;
  flex-direction: column;
  gap: 16px;
}
/* The hover lift is switched off inside a stack. `.card:hover` raises the card and brightens
   its border, which is right for the dashboard's cards - those are links - and wrong for a
   panel of read-only content, where it promises a click that does nothing. A card that is a
   link keeps the lift, because `a.card` re-enables it below. */
.card-stack > .card:hover {
  transform: none;
  border-color: var(--border);
}
.card-stack > a.card:hover {
  transform: translateY(-2px);
  border-color: var(--border-strong);
}


/* ---- tour and event rosters: one pilot per row ---- */
.roster-row {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 11px 0;
}
.roster-row + .roster-row { border-top: 1px solid var(--border); }
.roster-avatar {
  flex: none;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.72rem;
  font-weight: 600;
  /* The token, not a literal, so the circle follows an airline's own brand colour - and it is the
     same value `.pilot-avatar` uses, so the two agree by construction. */
  background: var(--accent-soft);
  color: var(--accent-bright);
}
/* The shared identity takes the space left over and lets the name ellipsis rather than push the
   figures off the end. */
.roster-row > .pilot-identity,
.roster-row > .pilot-identity-bare { flex: 1; min-width: 0; }
.board-record-pilot { display: flex; align-items: center; gap: 8px; }
/* Breathing room between the roster's heading and its first pilot. */
.roster-list { margin-top: 6px; }

/* ---- The awards gallery card, and one award's own page ----

   The card must not change height with its holder count: listing every holder would let a
   popular award grow until one card filled the screen and the grid stopped being a grid. The
   count and a short avatar row do the gallery's job; the names live on award.html.
   The card is an <a> and inherits the a.card rules above, so it does not paint itself as text. */
.award-card {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
/* Pushes the footer line down so cards in a row align on their last line whatever the length of
   the description above it. */
.award-card-text { flex: 1; margin: 0; }
.award-card-foot {
  border-top: 1px solid var(--border);
  padding-top: 10px;
  font-size: 0.86rem;
}
.award-holders { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

/* Overlapping initials, the tour roster's avatar at gallery scale. The ring is the CARD's own
   background rather than a border colour, so the circles read as a stack rather than as a row of
   outlined chips. */
.avatar-stack { display: flex; }
.avatar-stack .roster-avatar {
  width: 28px;
  height: 28px;
  border: 2px solid var(--surface-2);
}
.avatar-stack .roster-avatar + .roster-avatar { margin-left: -9px; }
/* The stack overlaps the shared avatar, so a gallery card keeps its size and rhythm. */
.avatar-stack .pilot-avatar { width: 28px; height: 28px; border: 2px solid var(--surface-2); }
.avatar-stack .pilot-identity-bare + .pilot-identity-bare,
.avatar-stack .pilot-identity-bare + .roster-avatar { margin-left: -9px; }
.avatar-more { background: var(--surface-3); color: var(--text-secondary); }

/* One award's page. The holder list is the tour roster's row, so a pilot looks the same
   wherever they are listed. */
.award-page-head { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.holder-search { margin-bottom: 14px; }
.holder-search input[type="search"] { min-width: 180px; }
.holder-count { font-size: 0.86rem; color: var(--text-muted); }

/* ---- award badges and rank insignia ----
   Four sizes, one treatment.

   object-fit: contain, never cover. A badge or an insignia is a mark on a transparent or flat
   background - cropping one to fill a square cuts the wings off it. The tour and event posters
   do cover, because a poster is a photograph and its edges are scenery; these are not the same
   kind of picture, which is why they do not share a rule.

   The box is square and fixed at every size, so a card's height never depends on the shape of
   the image an airline uploaded. */
.award-emblem,
.award-emblem-lg,
.award-emblem-sm,
.rank-insignia {
  flex: none;
  object-fit: contain;
  /* Nothing behind it: a badge with a transparent background is meant to sit on the card, and a
     tinted plate turns every one of them into a sticker. */
  background: none;
}
.award-emblem { width: 44px; height: 44px; }
.award-emblem-lg { width: 88px; height: 88px; }
.award-emblem-sm { width: 24px; height: 24px; }
.rank-insignia { width: 28px; height: 28px; }

/* The award page's title row: emblem beside the heading, and the heading keeps its own margins
   so the description and chips below are unchanged. */
.award-title-row { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }

/* An award or rank line with its small emblem: the image and the text share a baseline row
   rather than the image sitting on a line of its own. */
.award-line { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

/* ==========================================================================
   The file library
   --------------------------------------------------------------------------
   A grid of cards - a thumbnail per entry, a toolbar that searches and filters, and the
   airline's own categories kept as sections - so what a thing is reads at a glance.

   A card's height is bounded, whatever the entry says: a fixed-ratio thumbnail, a title
   clamped to two lines, a description clamped to two, one meta line and one action row. Cards
   in the same grid row are then identical by construction (grid items stretch), and rows differ
   by at most a line - the same rule as the awards gallery.
   ========================================================================== */

/* ---- toolbar: search, type chips, count ---- */
.lib-toolbar {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 4px;
  padding: 12px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
}

.lib-search { position: relative; flex: 1 1 260px; min-width: 200px; }
/* The glyph sits INSIDE the field, so the input keeps the full width it needs to be typed in. */
.lib-search .icon {
  position: absolute;
  left: 12px;
  top: 50%;
  transform: translateY(-50%);
  width: 18px;
  height: 18px;
  color: var(--text-muted);
  pointer-events: none;
}
.lib-search input {
  width: 100%;
  padding: 10px 12px 10px 38px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-strong);
  background: var(--surface-1);
  color: var(--text-primary);
  font: inherit;
  font-size: 15px;
}
.lib-search input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.lib-filters { display: flex; gap: 6px; flex-wrap: wrap; }
/* Pushed to the far end on a wide toolbar and back into the flow on a narrow one, where
   "auto" would leave it stranded on a line of its own. */
.lib-count { margin-left: auto; color: var(--text-muted); font-size: 13px; white-space: nowrap; }
@media (max-width: 640px) { .lib-count { margin-left: 0; } }

/* ---- sections and the grid ---- */
.lib-section { margin-top: 30px; }
.lib-section-head { display: flex; align-items: baseline; gap: 12px; margin-bottom: 14px; }
.lib-section-head h2 { margin: 0; font-size: 18px; }
.lib-section-head span { font-size: 13px; color: var(--text-muted); }

.lib-grid {
  display: grid;
  gap: 16px;
  /* auto-FILL, not auto-fit: a lone card keeps a card's width instead of stretching to the full
     page, which is what an airline with one document would otherwise see. */
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
}

/* ---- the card ---- */
.lib-card {
  display: flex;
  flex-direction: column;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  overflow: hidden;
  transition: border-color 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease;
}
.lib-card:hover {
  border-color: var(--border-strong);
  transform: translateY(-2px);
  box-shadow: var(--shadow-1);
}

.lib-thumb-wrap { position: relative; }
.lib-thumb {
  aspect-ratio: 16 / 10;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  background: var(--surface-3);
  border-bottom: 1px solid var(--border);
}
/* A checkerboard behind a real image, because badges and insignia are transparent PNGs and
   half of one disappears against a flat dark panel. */
.lib-thumb-image {
  padding: 10px;
  /* Tokens, not hex values: a hard-coded near-black would paint a near-black checkerboard on a
     light site, and the template ships both themes. */
  background:
    linear-gradient(45deg, var(--surface-3) 25%, transparent 25%, transparent 75%,
      var(--surface-3) 75%),
    linear-gradient(45deg, var(--surface-3) 25%, var(--surface-1) 25%, var(--surface-1) 75%,
      var(--surface-3) 75%);
  background-size: 16px 16px;
  background-position: 0 0, 8px 8px;
  cursor: zoom-in;
}
/* CONTAIN, never cover: a badge cropped to fill a box has had its wings cut off. */
.lib-thumb-image img { max-width: 100%; max-height: 100%; object-fit: contain; display: block; }
.lib-thumb .icon { width: 34px; height: 34px; }
.lib-kind {
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-muted);
}

/* One tint per drawer, from the semantic tokens rather than new colours - so the kind of a
   thing is legible before a word is read, and a theme change carries it. */
.lib-thumb-pdf { background: color-mix(in srgb, var(--danger) 7%, var(--surface-3)); }
.lib-thumb-pdf .icon { color: var(--danger); }
.lib-thumb-sheet { background: color-mix(in srgb, var(--success) 7%, var(--surface-3)); }
.lib-thumb-sheet .icon { color: var(--success); }
.lib-thumb-zip { background: color-mix(in srgb, var(--warning) 7%, var(--surface-3)); }
.lib-thumb-zip .icon { color: var(--warning); }
.lib-thumb-link { background: color-mix(in srgb, var(--accent) 9%, var(--surface-3)); }
.lib-thumb-link .icon { color: var(--accent-bright); }
.lib-thumb-text .icon,
.lib-thumb-file .icon { color: var(--text-secondary); }

/* On the thumbnail, not in the meta line. Whether a document is crew-only is the one fact a
   pilot needs when deciding what to forward. */
.lib-lock {
  position: absolute;
  top: 10px;
  right: 10px;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 9px;
  border-radius: 999px;
  font-size: 11px;
  color: var(--text-primary);
  background: color-mix(in srgb, var(--bg) 78%, transparent);
  border: 1px solid var(--border-strong);
  backdrop-filter: blur(4px);
}
.lib-lock .icon { width: 12px; height: 12px; color: var(--warning); }

.lib-body { padding: 14px 14px 0; flex: 1; }
/* Two lines here too, with the full text on the element's title attribute. An unclamped heading
   is the one thing left that could make a card arbitrarily tall - a single wrapped title makes
   its row taller than its neighbours, which is exactly how a grid starts looking ragged. */
.lib-body h3 {
  margin: 0 0 5px;
  font-size: 16px;
  line-height: 1.3;
  overflow-wrap: anywhere;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
/* Two lines, then an ellipsis: the description is a hint, and a card sized by the wordiest
   entry is what the grid exists to avoid. */
.lib-desc {
  margin: 0 0 8px;
  color: var(--text-secondary);
  font-size: 14px;
  line-height: 1.45;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.lib-meta { margin: 0; color: var(--text-muted); font-size: 13px; }
.lib-actions { display: flex; gap: 8px; padding: 12px 14px 14px; }

/* ---- the image lightbox ---- */
.lib-lightbox {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 32px;
  background: color-mix(in srgb, var(--bg) 82%, transparent);
}
.lib-lightbox[hidden] { display: none; }
.lib-lightbox-inner {
  width: 100%;
  max-width: 720px;
  background: var(--surface-2);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-2);
}
.lib-stage {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 260px;
  padding: 24px;
  background: var(--surface-1);
  border-radius: var(--radius-md) var(--radius-md) 0 0;
}
.lib-stage img { max-width: 100%; max-height: 56vh; object-fit: contain; }
.lib-lightbox-foot { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; padding: 14px 18px; }
.lib-lightbox-foot .btn { margin-left: auto; }

/* ==========================================================================
   Homepage and shared chrome
   --------------------------------------------------------------------------
   The grouped navigation, the working hero (live operations + integrated
   stats), the About-the-airline section, the community band, and the
   four-column footer. Later in the file than the originals on purpose:
   where a rule below repeats a selector from above, this one wins.
   ========================================================================== */

/* ---- grouped navigation ---- */

.nav-group {
  position: relative;
  display: flex;
  align-items: center;
  align-self: stretch;
}

.nav-group-btn {
  display: flex;
  align-items: center;
  gap: 6px;
  background: none;
  border: none;
  cursor: pointer;
  font-family: inherit;
  font-size: 0.95rem;
  color: var(--text-secondary);
  padding: 8px 13px;
  border-radius: var(--radius-sm);
}

.nav-group-btn:hover {
  color: var(--text-primary);
  background: var(--surface-2);
}

.nav-group-btn.active {
  color: var(--text-primary);
  background: var(--accent-soft);
}

.nav-group-btn .nav-caret {
  transition: transform 0.15s ease;
}

.nav-group.open .nav-group-btn .nav-caret {
  transform: rotate(180deg);
}

.nav-menu {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  min-width: 210px;
  padding: 8px;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-2);
  z-index: 60;
}

/* Click-only, deliberately: opening on :hover as well would let the menu stay painted after a
   click closed it (the pointer is still over the group), with the caret disagreeing. One
   mechanism - the .open class - so the caret and the menu can never tell different stories. */
.nav-group.open .nav-menu {
  display: block;
}

.nav-links .nav-menu a {
  display: block;
  padding: 9px 12px;
  font-size: 0.93rem;
}

@media (max-width: 800px) {
  /* The expanded menu is taller than a phone with every group open, and it is anchored under
     the sticky header - so it scrolls itself, or Pilot Login / Settings / Sign out sit below
     the viewport with no way to reach them. dvh where supported, vh as the fallback. */
  .nav-links {
    max-height: calc(100vh - 64px);
    max-height: calc(100dvh - 64px);
    overflow-y: auto;
  }

  /* In the mobile menu the groups are always-open labelled sections - a
     dropdown inside a dropdown is a puzzle, not a menu. The group buttons
     become inert headings (layout.js takes them out of the tab order and
     marks them expanded, so assistive tech is never told a visibly open
     menu is closed). */
  .nav-group {
    display: block;
    align-self: auto;
  }

  .nav-group-btn {
    width: 100%;
    text-align: left;
    pointer-events: none;
    font-size: 0.76rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-muted);
    padding: 10px 13px 2px;
  }

  .nav-group-btn .nav-caret {
    display: none;
  }

  .nav-menu {
    display: block;
    position: static;
    min-width: 0;
    padding: 0;
    background: none;
    border: none;
    box-shadow: none;
  }
}

/* ---- the hero: a working surface, not a banner ---- */

.hero {
  min-height: 0;
  border-bottom: 1px solid var(--border);
}

.hero .container {
  padding-top: 72px;
  padding-bottom: 46px;
}

.hero-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 48px;
  align-items: center;
}

/* Two columns only while the live-operations card has something to show. */
.hero-layout.has-live {
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 0.75fr);
}

.hero-copy {
  max-width: 660px;
}

/* The live-operations card: who is in the air right now, straight from the
   public live-flights dataset. Appears only when somebody actually is. */
.hero-live {
  background: color-mix(in srgb, var(--surface-2) 92%, transparent);
  backdrop-filter: blur(10px);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-2);
  overflow: hidden;
}

.hero-live-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--border);
  font-size: 0.95rem;
}

.hero-live-count {
  margin-left: auto;
  color: var(--text-muted);
  font-size: 0.82rem;
}

.hero-live-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 18px;
  border-bottom: 1px solid var(--border);
  font-size: 0.9rem;
}

.hero-live-row .flight-no {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 0.88rem;
  color: var(--accent-bright);
}

.hero-live-route {
  color: var(--text-primary);
}

.hero-live-link {
  display: block;
  padding: 12px 18px;
  font-size: 0.88rem;
  font-weight: 600;
}

.live-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--success);
  flex-shrink: 0;
  animation: live-pulse 2s infinite;
}

@keyframes live-pulse {
  0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--success) 50%, transparent); }
  70% { box-shadow: 0 0 0 7px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}

@media (prefers-reduced-motion: reduce) {
  .live-dot { animation: none; }
}

/* The stats live inside the hero, flattened to bare figures - the tiles
   keep their markup (and their classes elsewhere), this strips the chrome. */
.hero-stats {
  margin-top: 46px;
  padding-top: 26px;
  border-top: 1px solid color-mix(in srgb, #ffffff 14%, transparent);
}

.hero-stats .stat-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 18px 52px;
}

.hero-stats .stat-tile,
.hero-stats .stat-tile.accent {
  background: none;
  border: none;
  box-shadow: none;
  backdrop-filter: none;
  padding: 0;
}

@media (max-width: 900px) {
  .hero-layout.has-live {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ---- About the airline ---- */

.about-layout {
  display: grid;
  grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr);
  gap: 48px;
  align-items: start;
}

.eyebrow {
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent-bright);
  margin-bottom: 10px;
}

.about-copy h2 {
  margin: 0 0 14px;
  font-size: 1.9rem;
  letter-spacing: -0.02em;
}

.about-text {
  margin: 0 0 22px;
  color: var(--text-secondary);
  font-size: 1.03rem;
  max-width: 640px;
  white-space: pre-line;
}

.about-points {
  display: flex;
  flex-wrap: wrap;
  gap: 14px 28px;
}

.about-point {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 0.92rem;
  font-weight: 600;
}

.about-point .point-icon {
  width: 34px;
  height: 34px;
  border-radius: var(--radius-sm);
  background: var(--accent-soft);
  color: var(--accent-bright);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.about-point .point-icon .icon {
  width: 17px;
  height: 17px;
}

.about-facts {
  padding: 22px 24px;
}

.about-facts h3 {
  margin: 0 0 6px;
}

.fact-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 16px;
  padding: 10px 0;
  border-bottom: 1px solid var(--border);
  font-size: 0.92rem;
}

.fact-row:last-child {
  border-bottom: none;
}

.fact-row .fact-label {
  color: var(--text-muted);
}

.fact-row .fact-value {
  color: var(--text-primary);
  font-weight: 600;
  text-align: right;
}

.about-join {
  margin-top: 14px;
  width: 100%;
  justify-content: center;
}

@media (max-width: 900px) {
  .about-layout {
    grid-template-columns: minmax(0, 1fr);
    gap: 28px;
  }
}

/* ---- footer ---- */

.footer-brand {
  max-width: 300px;
}

.footer-brand-name {
  display: flex;
  align-items: center;
  gap: 10px;
  font-weight: 700;
  color: var(--text-primary);
  margin-bottom: 8px;
}

.footer-tag {
  margin: 0 0 14px;
  font-size: 0.85rem;
}

.footer-col {
  display: flex;
  flex-direction: column;
  gap: 7px;
}

.footer-col a {
  color: var(--text-secondary);
  font-size: 0.88rem;
}

/* The signed-in pilot's own nav menu (revealed by vabase.js): the pilot's name on the bar,
   the whole pilot area underneath it. */
.nav-pilot-btn {
  color: var(--text-primary);
  font-weight: 600;
}

.nav-pilot-avatar {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--accent-soft);
  color: var(--accent-bright);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

/* The pilot group sits at the bar's right edge, so its menu hangs left of it. */
.nav-pilot .nav-menu {
  left: auto;
  right: 0;
  min-width: 232px;
  max-height: calc(100vh - 80px);
  max-height: calc(100dvh - 80px);
  overflow-y: auto;
  overscroll-behavior: contain;
}

.pilot-menu-section {
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px solid var(--border);
}

.pilot-menu-label {
  display: block;
  padding: 6px 12px 3px;
  color: var(--text-muted);
  font-size: 0.69rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
}

.nav-links .nav-pilot .nav-menu a {
  padding-block: 7px;
  text-decoration: none;
}

@media (max-width: 800px) {
  .nav-pilot .nav-menu {
    min-width: 0;
    max-height: none;
    overflow: visible;
  }
  .nav-links .nav-pilot .nav-menu a, .nav-pilot .nav-signout {
    display: flex;
    align-items: center;
    min-height: 44px;
  }
}

.nav-menu .nav-signout {
  display: block;
  width: 100%;
  text-align: left;
  margin-top: 6px;
  padding: 9px 12px;
  border: none;
  border-top: 1px solid var(--border);
  border-radius: 0 0 var(--radius-sm) var(--radius-sm);
  background: none;
  font: inherit;
  font-size: 0.93rem;
  color: var(--text-secondary);
  cursor: pointer;
}

.nav-menu .nav-signout:hover {
  color: var(--text-primary);
  background: var(--surface-2);
}

/* ---- pilot dashboard ----
   Three container tiers do the ranking: .tier-hero is the ONE elevated surface (the Next
   Flight card); the lower-grid .cards are flat bordered surfaces; identity, the attention
   ribbons and the progression band carry NO container at all. */

.dash-identity {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 44px 0 4px;
}

.dash-avatar {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: var(--accent-soft);
  border: 1px solid var(--accent-glow);
  color: var(--accent-bright);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 1.1rem;
  flex-shrink: 0;
}

.dash-identity-text {
  min-width: 0;
  flex: 1;
}

/* The SAME size every other page's title uses (.page-title h1) - the dashboard must not
   jump scale as you move between pages. */
.dash-greeting {
  margin: 0;
  font-size: var(--page-title-size);
  letter-spacing: -0.02em;
  line-height: 1.15;
}

.dash-identity-line {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 3px;
  color: var(--text-muted);
  font-size: 0.85rem;
}

.label-sm {
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
}

/* Zone rhythm: related things sit close, major zones breathe. */
.dash-zone {
  margin-top: 32px;
}

.dash-section-title { margin: 0 0 18px; font-size: 1.2rem; }

#dash-shell, #dash-loading { padding-bottom: 60px; }

/* Text accents need darker tones on the dashboard's light surfaces. */
[data-theme="light"] #dash-shell {
  --accent-bright: var(--accent);
  --warning: #8b5b11;
  --success: #16804a;
  --info: #1966aa;
}

/* The row carries the hero's spacing, not the hero's own section. The section sits inside a
   grid beside the Current location card, and a margin on it would push the hero below the card
   it shares the row with (and stack on the row's own .dash-zone margin, doubling the gap above).
   An id, so it outranks .dash-zone's 32px. */
#dash-hero-row {
  margin-top: 28px;
}

/* ---- the loading skeleton: the real page's silhouette, so nothing jumps on load ---- */

/* Every shape carries the #dash-skeleton prefix so the generic .skeleton width rules
   (the :nth-child bars used by list loading states) can never restyle these - they would
   squash the avatar into an oval. */
#dash-skeleton .skeleton {
  margin: 0;
}

#dash-skeleton .sk-avatar {
  width: 96px;
  height: 96px;
  border-radius: 50%;
  flex-shrink: 0;
}

.sk-lines {
  flex: 1;
  max-width: 420px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

#dash-skeleton .sk-title {
  height: 30px;
  width: 62%;
}

#dash-skeleton .sk-sub {
  height: 14px;
  width: 84%;
}

#dash-skeleton .sk-hero {
  height: 280px;
  width: 100%;
  margin-top: 28px;
  border-radius: var(--radius-lg);
}

#dash-skeleton .sk-band {
  height: 215px;
  width: 100%;
  margin-top: 32px;
  border-radius: 14px;
}

.sk-grid {
  margin-top: 32px;
}

#dash-skeleton .sk-main {
  height: 340px;
  width: 100%;
  border-radius: var(--radius-md);
}

#dash-skeleton .sk-card {
  height: 150px;
  width: 100%;
  border-radius: var(--radius-md);
}

/* ---- the attention stack: slim ribbons, only when something needs saying ---- */

.attention-stack {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 26px;
}

.ribbon {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 9px 14px;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-left-width: 3px;
  border-left-color: var(--info);
  border-radius: 10px;
  font-size: 0.86rem;
  color: var(--text-primary);
}

a.ribbon:hover {
  text-decoration: none;
  border-color: var(--border-strong);
  border-left-color: var(--info);
}

.ribbon-warn {
  border-left-color: var(--warning);
}

a.ribbon-warn:hover {
  border-left-color: var(--warning);
}

.ribbon-danger {
  border-left-color: var(--danger);
}

.ribbon-text {
  min-width: 0;
  overflow-wrap: anywhere;
}

.ribbon-text strong {
  color: var(--text-primary);
}

.ribbon-when {
  color: var(--text-muted);
  font-size: 0.78rem;
  white-space: nowrap;
}

.ribbon-action {
  margin-left: auto;
  color: var(--accent-bright);
  font-weight: 600;
  font-size: 0.82rem;
  white-space: nowrap;
}

/* A ribbon action that is a button (the confirm-email prompt), drawn as the link. */
.ribbon-button {
  background: none;
  border: 0;
  padding: 0;
  font-family: inherit;
  cursor: pointer;
}

.ribbon-button:hover { text-decoration: underline; }

.ribbon-button:disabled { opacity: .6; cursor: default; }

/* ---- the Next Flight hero: the one tier-1 surface, the page's one primary action ---- */

.tier-hero {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 12px;
  padding: 26px 30px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-2);
}

/* No booking: a slim band, never a hero-sized void. */
.tier-hero.next-flight-empty {
  flex-direction: row;
  align-items: center;
  padding: 15px 24px;
  gap: 20px;
}

.next-flight-empty .next-flight-actions {
  margin-left: auto;
}

/* ---- the Current location card, beside the hero ----
   Tier 2: a flat card. The hero stays the page's ONE elevated surface. The row is a single
   column until BOTH the hero and the card are there, so an airline with pilot positioning
   switched off sees the dashboard without it. */

.dash-hero-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 20px;
  align-items: stretch;
}

.dash-hero-row.has-location {
  grid-template-columns: minmax(0, 1fr) 380px;
}

/* [hidden] is only a user-agent rule at the bottom of the cascade: a class that sets display
   beats it, and the element then draws while the script believes it is hidden. */
.dash-hero-row[hidden],
.location-card[hidden] {
  display: none;
}

/* Beside the card the empty hero is a column - eyebrow, headline, sentence, the action at the
   foot - not the slim band it is when it has the row to itself. */
/* The hero fills its cell so the two cards share a bottom edge. The SECTION is the grid item
   and stretches by itself; the hero inside it does not (a percentage height needs a definite
   parent, and measured in the browser it came up 28px short), so the section becomes a flex
   column and the hero grows into it. has-location is only ever set while both are visible, so
   this can never un-hide a hidden hero. */
.dash-hero-row.has-location > section {
  display: flex;
  flex-direction: column;
}

.dash-hero-row.has-location .tier-hero {
  flex: 1;
}

.dash-hero-row.has-location .tier-hero.next-flight-empty {
  flex-direction: column;
  align-items: flex-start;
  padding: 26px 30px;
  gap: 12px;
}

.dash-hero-row.has-location .next-flight-empty .next-flight-actions {
  margin-left: 0;
  margin-top: auto;
  padding-top: 8px;
}

/* Beside the location card the empty hero speaks at that card's scale: a headline near the
   card's airport code, the sentence at body size, the lines close together, and the two ways in
   side by side on the shared bottom edge. Wide screens only - under 900px the empty hero is the
   slim band again. */
@media (min-width: 901px) {
  .dash-hero-row.has-location .next-flight-empty .next-flight-facts { gap: 10px; }
  .dash-hero-row.has-location .next-flight-empty .next-flight-id { font-size: 1.75rem; letter-spacing: -0.015em; line-height: 1.15; }
  .dash-hero-row.has-location .next-flight-empty .next-flight-sub { font-size: 1rem; line-height: 1.55; color: var(--text-secondary); max-width: 56ch; }
  .dash-hero-row.has-location .next-flight-empty .next-flight-actions { flex-direction: row; flex-wrap: wrap; gap: 10px; }
}

.location-card {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.location-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.location-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent-bright);
}

.location-info {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  margin: -6px -8px -6px 0;
  padding: 0;
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  color: var(--text-muted);
  cursor: help;
}

.location-info:hover,
.location-info:focus-visible {
  color: var(--text-primary);
  background: var(--surface-3);
}

.location-where {
  min-width: 0;
}

.location-code {
  font-size: 2.35rem;
  letter-spacing: 0.02em;
  line-height: 1.05;
}

.location-name {
  margin-top: 4px;
  font-size: 1.12rem;
  font-weight: 600;
  line-height: 1.3;
  overflow-wrap: anywhere;
}

.location-place {
  font-size: 0.88rem;
  color: var(--text-muted);
}

.location-facts {
  display: flex;
  flex-direction: column;
  gap: 7px;
  margin: 0;
  padding: 12px 0 0;
  border-top: 1px solid var(--border);
  list-style: none;
}

.location-fact {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  font-size: 0.88rem;
  line-height: 1.45;
  color: var(--text-secondary);
}

.location-fact .icon {
  margin-top: 3px;
  color: var(--text-muted);
}

/* ---- the jumpseat ---- */

/* On the location card: the journey in progress, or the offer. */
.location-transit {
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
}

.location-transit-head {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.location-transit-route {
  font-weight: 700;
  color: var(--text-primary);
}

.location-transit-bar {
  display: block;
  width: 100%;
  height: 6px;
  margin: 12px 0 10px;
  border: 0;
  border-radius: 999px;
  overflow: hidden;
  background: var(--border);
  accent-color: var(--accent);
  appearance: none;
  -webkit-appearance: none;
}

/* The track is the BORDER tone: surface-2 on a card is invisible, and a bar with no track reads
   as a short line rather than as progress. */
.location-transit-bar::-webkit-progress-bar { background: var(--border); border-radius: 999px; }
.location-transit-bar::-webkit-progress-value { background: var(--accent); border-radius: 999px; }
.location-transit-bar::-moz-progress-bar { background: var(--accent); border-radius: 999px; }

.location-transit-when {
  font-size: 0.9rem;
  color: var(--text-secondary);
}

.location-transit-when strong { color: var(--text-primary); }

.location-transit-still {
  margin: 8px 0 0;
  font-size: 0.85rem;
  line-height: 1.45;
  color: var(--text-muted);
}

.location-actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px 14px;
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
}

.location-offer {
  font-size: 0.85rem;
  color: var(--text-muted);
}

/* The dialog. Native <dialog>: focus is trapped and Escape closes it without any script. Shared
   with the Leave tour / Withdraw confirmation, its second consumer. */
.jumpseat-dialog,
.confirm-dialog {
  width: min(480px, calc(100vw - 32px));
  max-height: calc(100vh - 48px);
  padding: 0;
  border: 1px solid var(--border-strong);
  border-radius: 18px;
  background: var(--surface-1, var(--surface-2));
  color: var(--text-primary);
  overflow: auto;
}

.jumpseat-dialog::backdrop,
.confirm-dialog::backdrop { background: rgba(5, 5, 8, 0.72); }

.jumpseat-panel { padding: 26px 26px 22px; }

.jumpseat-head { margin-bottom: 18px; }

.jumpseat-title { margin: 0; font-size: 1.35rem; }

.jumpseat-sub {
  margin: 4px 0 0;
  font-size: 0.92rem;
  color: var(--text-secondary);
}

.jumpseat-destination { position: relative; margin-bottom: 16px; }

/* The search field, dressed as the site's own search inputs are (.filter-bar input). */
.jumpseat-destination input {
  display: block;
  width: 100%;
  margin-top: 8px;
  padding: 10px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  color: var(--text-primary);
  font-family: inherit;
  font-size: 0.95rem;
  text-transform: uppercase;
}

.jumpseat-destination input::placeholder { text-transform: none; }

.jumpseat-destination input:focus {
  outline: 2px solid var(--accent);
  outline-offset: -1px;
}

.jumpseat-results {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-top: 6px;
  padding: 6px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface-2);
  max-height: 220px;
  overflow: auto;
}

.jumpseat-results[hidden] { display: none; }

.jumpseat-results .muted { margin: 6px 8px; font-size: 0.88rem; }

.jumpseat-result {
  display: flex;
  align-items: baseline;
  gap: 12px;
  padding: 8px 10px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--text-primary);
  font-family: inherit;
  font-size: 0.92rem;
  text-align: left;
  cursor: pointer;
}

.jumpseat-result:hover,
.jumpseat-result:focus-visible { background: var(--accent-soft); outline: none; }

.jumpseat-result .airport-code { font-size: 0.95rem; }

.jumpseat-result-name { color: var(--text-secondary); }

.jumpseat-terms {
  margin: 0 0 14px;
  border: 1px solid var(--border);
  border-radius: 12px;
  overflow: hidden;
}

.jumpseat-term {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  padding: 10px 14px;
  font-size: 0.92rem;
}

.jumpseat-term + .jumpseat-term { border-top: 1px solid var(--border); }

.jumpseat-term dt { color: var(--text-secondary); }

.jumpseat-term dd {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font-weight: 600;
  text-align: right;
}

.jumpseat-term-changed { background: color-mix(in srgb, var(--warning) 9%, transparent); }

.jumpseat-changed,
.jumpseat-warning {
  margin: 0 0 14px;
  padding: 10px 12px;
  border: 1px solid color-mix(in srgb, var(--warning) 40%, var(--border));
  border-radius: 8px;
  background: color-mix(in srgb, var(--warning) 9%, transparent);
  font-size: 0.88rem;
  line-height: 1.45;
}

.jumpseat-note {
  margin: 0 0 4px;
  font-size: 0.85rem;
  line-height: 1.45;
  color: var(--text-muted);
}

.jumpseat-actions {
  display: flex;
  justify-content: flex-end;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 18px;
}

.next-flight-facts {
  display: flex;
  flex-direction: column;
  gap: 18px;
  min-width: 0;
  flex: 1;
}

.next-flight-id {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 1.05rem;
  font-weight: 700;
  flex-wrap: wrap;
  overflow-wrap: anywhere;
}

.next-flight-id .flight-no {
  font-family: var(--font-mono);
  font-size: 1.25rem;
  color: var(--accent-bright);
}

.next-flight-heading .badge .live-dot {
  width: 7px;
  height: 7px;
}

.next-flight-sub {
  color: var(--text-muted);
  font-size: 0.8rem;
}

.next-flight-route {
  display: grid;
  align-items: start;
  grid-template-columns: minmax(0, 1fr) minmax(50px, 0.75fr) minmax(0, 1fr);
  gap: 18px;
  margin: 0;
}

.next-flight-route .route-end .airport-code {
  font-size: clamp(2rem, 4.5vw, 3.5rem);
  line-height: 1.1;
  letter-spacing: 0.01em;
  overflow-wrap: anywhere;
}

.next-flight-route .route-end {
  min-width: 0;
  text-align: left;
}

.next-flight-route .route-end .route-city {
  max-width: none;
  white-space: normal;
  overflow: visible;
  overflow-wrap: anywhere;
  font-size: 0.95rem;
  margin: 6px 0 0;
}

.next-flight-route .route-line { min-width: 0; margin-top: 20px; }
.next-flight-route .route-line::before { border-top: 1px solid var(--accent-bright); }
.next-flight-route .route-plane { background: var(--surface-2); }

.next-flight-heading {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}

.next-flight-journey {
  display: flex;
  align-items: center;
  gap: 48px;
  padding-top: 10px;
}

.next-flight-meta {
  display: flex;
  gap: 8px 20px;
  flex-wrap: wrap;
  color: var(--text-secondary);
  font-size: 0.83rem;
}

.next-flight-assignment {
  display: flex;
  flex-direction: column;
  gap: 5px;
  border-top: 1px solid var(--border);
  padding-top: 18px;
  margin-top: 6px;
  font-size: 0.88rem;
  color: var(--text-secondary);
}

.next-flight-assignment strong {
  font-size: 1.05rem;
  color: var(--warning);
}

.next-flight-bonus {
  margin-top: 5px;
  max-width: 220px;
  text-align: center;
  font-size: 0.8rem;
  color: var(--text-muted);
}

.next-flight-actions {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 7px;
  min-width: 190px;
}

.next-flight-actions .btn {
  justify-content: center;
}

/* Secondary to the button without reading as a footnote. */
.next-flight-acars {
  color: var(--text-secondary);
  font-size: 0.8rem;
  text-align: center;
}

/* ---- the career band: rank progress above a single row of statistics ---- */

.progression-band {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 24px;
  padding: 0 0 26px;
  border-bottom: 1px solid var(--border);
}

/* Rank progress has its own row, so the bar keeps room even with all five statistics enabled. */
.progression-main {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 7px;
}

.progression-rank-row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: start;
  gap: 6px 16px;
}

.career-rank-name {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font-size: 1.15rem;
  font-weight: 700;
  min-width: 0;
  overflow-wrap: anywhere;
  min-height: 42px;
}

/* Real rank artwork at a READABLE size, aspect preserved and height-bound so it can never
   distort the row - and never a colour swatch: the img hides itself when there is no insignia
   or the bytes fail (dashboard.js). */
.progression-rank-row .rank-insignia {
  width: auto;
  height: 42px;
  max-width: 90px;
}

.progression-rank-row .progress-bar {
  min-width: 60px;
}

.career-progress { display: grid; gap: 8px; min-width: 0; padding-top: 18px; }
.career-progress:has(#career-bar[hidden]) { padding-top: 0; align-self: center; }

/* The target rank reads at the SAME weight as the held one - both ends of one journey. */
.progression-next {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font-size: 1.15rem;
  color: var(--text-primary);
  min-width: 0;
  overflow-wrap: anywhere;
  min-height: 42px;
}

.progression-next strong {
  font-weight: 700;
}

.career-note {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 4px 16px;
  margin: 0;
  font-size: 0.85rem;
  color: var(--text-secondary);
}

.career-note strong { color: var(--accent-bright); font-weight: 600; }
.progression-next { grid-column: 3; grid-row: 1; }

/* Icon + big figure over a muted label, hairline-divided between the figures - deliberately not
   three bordered KPI cards. No divider against the rank: the band's gap already separates the
   two halves, and a bar down the middle would read as a second card. */
.progression-stats {
  display: flex;
  align-items: stretch;
  flex-wrap: wrap;
  gap: 20px 0;
}

/* Long figures and labels can wrap without forcing the page sideways. */
.prog-stat {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
  flex: 1 1 145px;
  min-width: 0;
  padding-right: 16px;
}

.prog-stat-value {
  overflow-wrap: anywhere;
}

.prog-stat-label {
  max-width: none;
}

.prog-stat + .prog-stat {
  border-left: 1px solid var(--border);
  padding-left: 22px;
}

.prog-stat:has(+ [hidden]:last-child), .prog-stat:last-child { padding-right: 0; }
.prog-stat .section-link, .prog-stat-detail { font-size: 0.8rem; line-height: 1.5; }
.prog-stat-detail { color: var(--text-secondary); }
.prog-stat[data-tone="warn"] .prog-stat-detail { color: var(--warning); }
.prog-stat .prog-stat-value svg { flex: none; }
.prog-stat .section-link { padding-top: 2px; }
.prog-stat a:hover { text-decoration: none; color: var(--text-primary); }

.prog-stat-value {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  color: var(--accent-bright);
}

.prog-stat-value strong {
  color: var(--text-primary);
  font-size: 1.35rem;
  font-weight: 700;
  line-height: 1.15;
}

.prog-stat-label {
  color: var(--text-muted);
  font-size: 0.85rem;
}

.progress-bar {
  height: 6px;
  border-radius: 999px;
  background: var(--surface-3);
  overflow: hidden;
}

.progress-fill {
  height: 100%;
  border-radius: 999px;
  background: var(--accent);
}

/* ---- the band's footer: the lines that qualify the figures - credited hours, this month's
   standing with its way through to the board, the streak deadline. Inside the band, under one
   hairline, they read as the band's own footnotes rather than stray text. The band wraps, so a
   100% basis puts the footer on its own row beneath the two halves. ---- */
.progression-notes {
  flex-basis: 100%;
  display: flex;
  flex-direction: column;
  gap: 7px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
}

/* A glyph leads each line so three sentences scan as three facts; the glyph takes the same
   accent the figures' icons do, the words the secondary text colour - readable, not a
   footnote. The glyph and ONE text block sit side by side and never wrap as a row: on a
   phone the sentence wraps inside its block, beside the glyph, rather than dropping under
   it and leaving the glyph alone on a line of its own. A link is inline text inside the
   block, so it follows its sentence like prose - never pushed to the far edge. */
.progression-note {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  margin: 0;
  font-size: 0.85rem;
  line-height: 1.4;
  color: var(--text-secondary);
}

/* 2px down so a 15px glyph centres on the FIRST line of a wrapped sentence (19px tall). */
.progression-note svg {
  flex: 0 0 auto;
  margin-top: 2px;
  color: var(--accent-bright);
}

.progression-note-text {
  min-width: 0;
}

.progression-note .section-link {
  font-size: inherit;
  white-space: nowrap;
  margin-left: 2px;
}

/* The streak line carries its tile's tone (dashboard.js): an at-risk deadline reads amber
   like the figure above it; an ended streak reads muted like its figure. */
.progression-note[data-tone="warn"],
.progression-note[data-tone="warn"] svg {
  color: var(--warning);
}

.progression-note[data-tone="muted"],
.progression-note[data-tone="muted"] svg {
  color: var(--text-muted);
}

/* ---- the lower grid: record (wide) + activities (narrow, but not squeezed) ---- */

.dash-columns {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
  gap: 24px;
  align-items: start;
}

.dash-card-head {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 10px;
}

.dash-card-head h2 {
  margin: 0;
  font-size: 1.02rem;
}

.dash-card-head h3 {
  margin: 0;
  font-size: 0.95rem;
  min-width: 0;
  overflow-wrap: anywhere;
}

.dash-card-head .section-link {
  margin-left: auto;
  font-size: 0.82rem;
}

/* Two links in one head: only the LAST takes the auto margin, the rest pack beside it. */
.dash-card-head .section-link ~ .section-link {
  margin-left: 0;
}

/* The PIREP card runs flush: a padded head over full-bleed rows. */
#pireps-card {
  padding: 0;
  overflow: hidden;
}

#pireps-card .dash-card-head {
  margin-bottom: 0;
  padding: 14px 18px;
  padding-bottom: 0;
}

#pireps-preview-label { margin: 4px 18px 14px; font-size: 0.8rem; }
.dash-card-foot { padding: 14px 18px; border-top: 1px solid var(--border); font-size: 0.85rem; }

#pireps-body.recent-flights { padding: 0 10px; }
#pireps-body .recent-flight-list > li:last-child { border-bottom: 0; }

#pireps-card .state {
  margin: 18px;
}

/* A status is a dot plus a word - colour alone never carries the meaning. Fixed-width so the
   dots and words line up as a column whatever the word ("Submitted" is the longest). */
.pirep-status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-left: auto;
  min-width: 94px;
}

.pirep-status-word {
  font-size: 0.78rem;
  color: var(--text-secondary);
}

.status-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}

.dot-success { background: var(--success); }
.dot-info { background: var(--info); }
.dot-warning { background: var(--warning); }
.dot-danger { background: var(--danger); }
.dot-muted { background: var(--text-muted); }

/* ---- the activities rail ---- */

.dash-rail {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

#rail-activities {
  display: flex;
  flex-direction: column;
  gap: 0;
}

#rail-activities:empty {
  display: none;
}

.rail-card {
  display: block;
  color: var(--text-primary);
  padding: 16px 18px;
}

.rail-card:hover {
  text-decoration: none;
}

.rail-card .progress-bar {
  margin: 8px 0;
}

.rail-card .card-sub {
  margin: 6px 0 0;
}

.rail-next-leg {
  color: var(--text-primary);
  font-weight: 600;
}

.rail-card .rail-action {
  display: inline-block;
  margin-top: 10px;
  font-size: 0.85rem;
}

.dashboard-activity { display: block; padding: 12px 0; color: var(--text-primary); }
.dashboard-activity + .dashboard-activity { border-top: 1px solid var(--border); }
.dashboard-activity:last-child { padding-bottom: 0; }
.dashboard-activity h3 { color: var(--accent-bright); }
.dashboard-activity:hover { text-decoration: none; }
.dashboard-activity:hover h3 { color: var(--text-primary); }
.dashboard-activity:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 4px; }

/* Award artwork at a readable size on the dashboard card (the site-wide -sm is a 24px list
   glyph, which read as an unreadable dot here). */
.rail-card .award-emblem-sm {
  width: 72px;
  height: 72px;
}

.rail-card .award-line {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 8px 0;
  flex-wrap: wrap;
}

.award-total {
  margin: 10px 0 0;
  font-size: 0.8rem;
}

/* ---- interaction polish: a visible keyboard focus everywhere the mouse has a hover ---- */

.btn:focus-visible,
.chip:focus-visible,
.ribbon:focus-visible,
.rail-card:focus-visible,
.section-link:focus-visible,
.nav-group-btn:focus-visible,
.nav-menu a:focus-visible,
.nav-menu .nav-signout:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ---- responsive ---- */

@media (max-width: 900px) {
  .dash-identity {
    flex-wrap: wrap;
    padding-top: 32px;
  }

  .tier-hero {
    flex-direction: column;
    align-items: stretch;
    gap: 18px;
  }

  .tier-hero.next-flight-empty {
    flex-direction: row;
    align-items: center;
  }

  /* One column, and where you are comes first. */
  .dash-hero-row.has-location {
    grid-template-columns: minmax(0, 1fr);
  }

  .dash-hero-row.has-location .location-card {
    order: -1;
  }

  .dash-hero-row.has-location .tier-hero.next-flight-empty {
    flex-direction: row;
    align-items: center;
    padding: 15px 24px;
    gap: 20px;
  }

  .dash-hero-row.has-location .next-flight-empty .next-flight-actions {
    margin-left: auto;
    margin-top: 0;
    padding-top: 0;
  }

  .next-flight-journey {
    gap: 24px;
  }

  .next-flight-actions .btn {
    flex: 1;
  }

  .progression-band {
    flex-direction: column;
    align-items: stretch;
    gap: 16px;
  }

  .dash-columns {
    grid-template-columns: minmax(0, 1fr);
  }
}

@media (max-width: 600px) {
  /* The route hero stays the biggest thing on the page - it just gets a phone-sized big. */
  .next-flight-route .route-end .airport-code {
    font-size: clamp(1.8rem, 7vw, 2.5rem);
  }

  .next-flight-route .route-end {
    min-width: 0;
  }

  .dash-identity { gap: 14px; align-items: flex-start; }
  #dash-shell .dash-avatar, #dash-skeleton .sk-avatar { width: 64px; height: 64px; }
  .dash-identity-line { font-size: 0.78rem; gap: 6px 10px; }
  .tier-hero { padding: 20px; }
  .next-flight-heading .label-sm { font-size: 0.65rem; }
  .next-flight-journey { flex-direction: column; align-items: stretch; padding-top: 0; }
  .next-flight-route { gap: 10px; grid-template-columns: minmax(0, 1fr) 32px minmax(0, 1fr); }
  .next-flight-route .route-line { margin-top: 8px; }
  .next-flight-route .route-end .route-city { font-size: 0.83rem; }
  .next-flight-meta { font-size: 0.78rem; gap: 6px; flex-direction: column; }
  .next-flight-actions { min-width: 0; }
  .next-flight-bonus { max-width: none; }
  .next-flight-assignment strong { font-size: 0.95rem; }
  .progression-rank-row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .career-progress { grid-row: 2; grid-column: 1 / -1; padding-top: 0; }
  .progression-next { grid-column: 2; justify-content: flex-end; text-align: right; }
  .career-rank-name, .progression-next { font-size: 0.95rem; gap: 8px; min-height: 28px; }
  .progression-rank-row .rank-insignia { height: 28px; max-width: 56px; }
  .progression-stats { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; }
  .progression-stats .prog-stat { border-left: 0; padding: 0; margin: 0; }
  .prog-stat-value strong { font-size: 1.15rem; }
  #stat-streak-tile { grid-column: 1 / -1; }
  .ribbon { flex-wrap: wrap; gap: 8px; }
  .ribbon-text { flex: 1 1 150px; }
  .ribbon-when { margin-left: 0; }

  .tier-hero.next-flight-empty {
    flex-direction: column;
    align-items: stretch;
  }

  .next-flight-empty .next-flight-actions {
    margin-left: 0;
  }

  .dash-hero-row.has-location .tier-hero.next-flight-empty {
    flex-direction: column;
    align-items: stretch;
    padding: 20px;
  }

  .dash-hero-row.has-location .next-flight-empty .next-flight-actions {
    margin-left: 0;
  }

  .ribbon-text {
    white-space: normal;
  }
}


/* The airline's stored routes for the pair being planned, offered under the route box on the
   free-flight form. Not a .suggest-list - that is an absolutely-positioned type-ahead popout that
   hangs off an input and closes; this is part of the form, always in flow, and stays on screen
   while the pilot reads the route they are about to copy. */
.company-routes {
  margin-top: 10px;
}

.company-routes-heading {
  margin: 0 0 6px;
  color: var(--text-muted);
  font-size: 0.8rem;
}

.company-route {
  display: block;
  width: 100%;
  text-align: left;
  margin-bottom: 6px;
  padding: 9px 12px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  color: var(--text-primary);
  cursor: pointer;
  font: inherit;
}

.company-route:hover,
.company-route:focus-visible {
  border-color: var(--accent-glow);
  background: var(--surface-3);
}

/* The route text is what is being picked, so it reads as a route: monospace, like every other
   place a route string is shown. */
.company-route-text {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.9rem;
}

.company-route-note {
  display: block;
  margin-top: 2px;
  color: var(--text-muted);
  font-size: 0.8rem;
}

/* Which tour leg or event asked for this routing. Above the route, because it is why that entry
   leads the list. */
.company-route-source {
  display: block;
  margin-bottom: 3px;
  color: var(--accent-bright);
  font-size: 0.75rem;
  font-weight: 600;
}

/* Leaderboard rows. They reuse .roster-row (a flex row with the avatar and name), so only the
   two columns that row does not have need rules: the position on the left and the figure pushed
   to the right. Tabular figures so the numbers line up as a column rather than jittering between
   rows. */
.board-position {
  flex: none;
  min-width: 2.2rem;
  font-weight: 700;
  font-size: 15px;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.board-value {
  margin-left: auto;
  flex: none;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* The streak records strip above a streak board - two small cards (longest live streak,
   longest ever) that wrap under each other on a phone. Hidden when the board is not a streak
   board, so there is no rule for an empty state. */
.board-records {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin: 0 0 16px;
}
.board-record {
  flex: 1 1 220px;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface-2);
}
.board-record-label {
  font-size: 0.8rem;
  color: var(--text-muted);
  margin-bottom: 2px;
}
.board-record-value {
  font-size: 1.25rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.board-record-pilot {
  font-size: 0.85rem;
  color: var(--text-muted);
  margin-top: 2px;
}

/* ---- The Flight Debrief ----------------------------------------------------- */
/* The flown-track map: .route-map carries the dark chrome overrides above; the compound
   selector wins the height whatever the file order. */
.route-map.debrief-map { height: 380px; margin-top: 0; }

/* The profile chart: a fixed-viewBox SVG stretched to the card, with everything textual as
   absolutely positioned HTML (SVG text would be squashed by the stretch). */
.debrief-chart {
  position: relative;
  height: 220px;
  margin-top: 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  overflow: hidden;
  background: rgba(255, 255, 255, 0.02);
}
.debrief-chart-svg { display: block; width: 100%; height: 100%; }
.debrief-alt-area { fill: rgba(139, 92, 246, 0.28); stroke: rgba(168, 131, 255, 0.9); stroke-width: 1.5; vector-effect: non-scaling-stroke; }
.debrief-spd-line { fill: none; stroke: #7bd8c2; stroke-width: 1.5; vector-effect: non-scaling-stroke; }
.debrief-band-label {
  position: absolute;
  top: 6px;
  transform: translateX(6px);
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
  pointer-events: none;
}
.debrief-chart-ticks { position: relative; height: 18px; margin-top: 4px; }
.debrief-tick {
  position: absolute;
  transform: translateX(-50%);
  font-size: 11px;
  color: var(--text-muted);
  white-space: nowrap;
}
.debrief-tick:first-child { transform: none; }
.debrief-tick:last-child { transform: translateX(-100%); }
.debrief-readout { min-height: 1.2em; margin: 8px 0 0; }

/* The timeline: dense flush rows, monospace times as a column. */
/* The Flight analysis band: Departure, the Landing fallback and Flight integrity as captioned
   columns of dense fact lists, no boxes - so a one-row integrity column beside a nine-row
   Departure column is a short column, not a card stretched to its neighbour. Grid rows still
   align the captions; the lists hang from them. */
.analysis-band { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 22px 40px; align-items: start; }
.analysis-col { min-width: 0; }
.analysis-col h4 { margin: 0 0 8px; font-size: 0.76rem; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-muted); }
.analysis-facts { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 6px 16px; margin: 0; font-size: 0.88rem; }
.analysis-facts dt { color: var(--text-muted); }
.analysis-facts dd { margin: 0; color: var(--text-primary); min-width: 0; overflow-wrap: anywhere; }
/* A fact may carry the runway card's confidence chip. appendChild puts no whitespace between the
   text and the badge, so the gap lives here rather than as a space nobody can see in the JS. */
.analysis-facts dd .runway-badge { margin-left: 8px; vertical-align: middle; }
.analysis-empty { margin: 0; font-size: 0.88rem; font-style: italic; color: var(--text-muted); }
@media (max-width: 700px) { .analysis-facts { grid-template-columns: 1fr; gap: 2px 0; } .analysis-facts dd { margin-bottom: 6px; } }

/* The timeline's heading line: the title and its own search, the way the reviewer's has. */
.debrief-timeline-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 10px;
}
.debrief-timeline-head h3 { margin: 0; }
.debrief-timeline-search { flex: 0 1 260px; min-width: 180px; }

/* Bounded and scrolling in place: an ordinary flight derives around forty events and a busy
   one several hundred, and the points breakdown below is what the pilot opened the page for.
   The padding is inside the scroll box, so it sits between the altitude column and the bar -
   right-aligned numbers otherwise touch it. */
.debrief-timeline {
  display: flex;
  flex-direction: column;
  max-height: 22rem;
  overflow-y: auto;
  padding-right: 12px;
}
.debrief-event {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 6px 0;
  border-top: 1px solid var(--border);
  font-size: 14px;
}
.debrief-event:first-child { border-top: 0; }
.debrief-event-time { flex: 0 0 auto; color: var(--text-muted); font-size: 12.5px; }
.debrief-event-label { flex: 0 1 auto; }
.debrief-event-alt { margin-left: auto; font-size: 12.5px; }
/* The timeline's weight: a box of its own under a sub-heading rather than a card heavier than
   the replay above it; the rows read at three weights - a coloured dot and a bold label for what
   a pilot scans for (integrity, the shaping phases), a quieter line for the routine
   configuration and light changes, plain for the rest - and a seek glyph shows on hover so a row
   says it can be clicked. */
.timeline-box {
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface-1);
  padding: 10px 14px 12px;
  margin-bottom: 18px;
}
.timeline-filters { margin-bottom: 8px; }
.debrief-timeline-head .debrief-timeline-search { margin-left: auto; }
.debrief-event-time, .debrief-event-alt { white-space: nowrap; }
.debrief-event-dot { flex: 0 0 auto; width: 7px; height: 7px; border-radius: 50%; background: var(--border-strong); align-self: center; }
.debrief-event-high .debrief-event-label { font-weight: 600; color: var(--text-primary); }
.debrief-event-high.debrief-event-integrity .debrief-event-dot { background: var(--danger); }
.debrief-event-high.debrief-event-phases .debrief-event-dot { background: var(--accent-bright); }
.debrief-event-low { font-size: 13px; color: var(--text-muted); }
.debrief-event-low .debrief-event-label { color: var(--text-secondary); }
.debrief-event-seek { flex: 0 0 auto; font-size: 10px; color: var(--accent-bright); opacity: 0; transition: opacity 120ms; }
.debrief-event.replay-seekable:hover .debrief-event-seek, .debrief-event.debrief-highlight .debrief-event-seek { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .debrief-event-seek { transition: none; } }

/* ---- The flight story ------------------------------------------------------ */

/* One sentence per line, read as prose rather than as a table: the story is the debrief's
   opening paragraph, and a line with a moment behind it is a seek target like a timeline row. */
.debrief-story { display: flex; flex-direction: column; gap: 4px; }
.debrief-story-line {
  margin: 0;
  padding: 5px 8px;
  border-radius: var(--radius-sm);
  font-size: 15px;
  line-height: 1.5;
  color: var(--text-primary);
}
.debrief-story-line.replay-seekable { cursor: pointer; }
.debrief-story-line.replay-seekable:hover { background: var(--accent-soft); }

/* ---- Score-line evidence + the approach card --------------------------------- */

/* A score line that carries evidence is wrapped so its drill-down sits INSIDE the row's own
   border: the wrap takes over the divider and the inner line stands down from it. */
.scoring-report-linewrap { border-bottom: 1px solid var(--border); }
.scoring-report-linewrap .scoring-report-line { border-bottom: 0; padding-bottom: 4px; }

.evidence-toggle {
  background: none;
  border: 0;
  padding: 0 0 8px;
  color: var(--accent-bright);
  font: inherit;
  font-size: 0.78rem;
  cursor: pointer;
}
.evidence-toggle:hover { text-decoration: underline; }
.evidence-list { display: flex; flex-direction: column; gap: 2px; padding: 0 0 10px; }
.evidence-item {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 4px 8px;
  border: 0;
  border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, 0.03);
  color: var(--text-primary);
  font: inherit;
  font-size: 0.82rem;
  text-align: left;
  cursor: pointer;
}
.evidence-item:hover { background: var(--accent-soft); }
.evidence-item .muted { font-size: 0.76rem; }
.evidence-time { flex: 0 0 auto; color: var(--text-muted); font-size: 0.76rem; }

/* The highlighted timeline row: a brief emphasis a click can find again, not a permanent
   state - re-clicking moves it. */
.debrief-event.debrief-highlight {
  background: var(--accent-soft);
  border-radius: var(--radius-sm);
  padding-left: 6px;
  padding-right: 6px;
}

/* The chart's evidence marker: a vertical line at the clicked moment's fraction. */
.debrief-chart-marker {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 2px;
  background: var(--warning);
  pointer-events: none;
}

/* ---- The Flight Replay ------------------------------------------------------ */
/* Mounted by the shared flight-replay-stage.js (byte-identical in the Admin Portal, which
   carries the same rules in its own stylesheet under its own tokens). The map is a .route-map
   so the dark chrome overrides reach it; the compound selector wins the height whatever the
   file order. */
/* The hero treatment: the map tallest on the page with the altitude legend laid over it, ONE
   toolbar beneath, the readout in two tiers, the profile inside the same surface. */
.replay-stage { outline: none; }
.replay-stage:focus-visible { box-shadow: 0 0 0 2px var(--accent-soft); border-radius: var(--radius-md); }
.replay-map-wrap { position: relative; }
.route-map.replay-map { height: 480px; margin-top: 0; }
.replay-legend {
  position: absolute;
  top: 10px;
  left: 10px;
  z-index: 2;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px 10px;
  max-width: calc(100% - 64px);
  padding: 5px 10px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 12px;
  background: rgba(12, 13, 15, 0.78);
  font-size: 0.72rem;
  color: var(--text-secondary);
  pointer-events: none;
}
.replay-legend-item { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; }
.replay-legend-swatch { display: inline-block; width: 12px; height: 6px; border-radius: 3px; }
.replay-controls {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 10px;
  padding: 7px 10px;
  min-height: 44px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface-2);
  flex-wrap: wrap;
}
.replay-btn {
  background: var(--surface-3);
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--text-primary);
  font-family: inherit;
  font-size: 0.84rem;
  font-weight: 600;
  padding: 6px 13px;
  cursor: pointer;
  min-width: 44px;
}
.replay-btn:hover { border-color: var(--accent); }
.replay-play { font-size: 0.8rem; }
.replay-scrub { position: relative; flex: 1 1 220px; min-width: 140px; padding-bottom: 7px; }
.replay-scrubber { display: block; width: 100%; margin: 0; accent-color: var(--accent); }
.replay-phase-ticks { position: absolute; left: 0; right: 0; bottom: 0; height: 6px; pointer-events: none; }
.replay-phase-tick { position: absolute; bottom: 0; width: 1px; height: 6px; background: var(--text-muted); opacity: 0.7; }
.replay-clock { font-variant-numeric: tabular-nums; color: var(--text-muted); min-width: 7.5ch; }
.replay-panel { margin-top: 12px; }
.replay-readout { display: grid; gap: 8px 14px; margin: 0; }
.replay-readout-primary { grid-template-columns: repeat(6, minmax(0, 1fr)); }
.replay-readout-more {
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--border);
}
.replay-readout-cell { min-width: 0; }
.replay-readout-cell dt { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-muted); margin: 0; }
.replay-readout-cell dd { margin: 2px 0 0; font-size: 1rem; font-variant-numeric: tabular-nums; }
.replay-readout-primary .replay-readout-cell dd { font-size: 1.25rem; font-weight: 600; color: var(--text-primary); }
.replay-panel-row { display: flex; align-items: center; gap: 10px; margin-top: 10px; flex-wrap: wrap; }
.replay-chips { display: flex; flex-wrap: wrap; gap: 6px; flex: 1 1 auto; }
.replay-chip {
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 2px 9px;
  font-size: 0.74rem;
  color: var(--text-muted);
}
.replay-chip-on { color: var(--text-primary); border-color: var(--accent); background: var(--accent-soft); }
.replay-chip-warn { color: var(--danger); border-color: var(--danger); background: transparent; }
.replay-more-toggle {
  margin-left: auto;
  background: none;
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--text-secondary);
  font-family: inherit;
  font-size: 0.76rem;
  font-weight: 600;
  padding: 3px 11px;
  cursor: pointer;
}
.replay-more-toggle:hover { border-color: var(--accent); color: var(--text-primary); }
.replay-profile { margin-top: 12px; cursor: crosshair; touch-action: none; }
.debrief-chart.replay-profile { height: 150px; }
.replay-cursor {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 2px;
  margin-left: -1px;
  background: #ffffff;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.6);
  pointer-events: none;
}
.replay-caption { min-height: 1.2em; }
.replay-notes { margin: 8px 0 0; font-size: 0.8rem; }
.replay-skip { margin: 4px 0 0; font-size: 0.8rem; }
@media (max-width: 700px) {
  .route-map.replay-map { height: 60vh; min-height: 320px; }
  .replay-scrub { flex-basis: 100%; order: 10; }
  .replay-readout-primary { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .replay-readout-primary .replay-readout-cell dd { font-size: 1.05rem; white-space: nowrap; }
  .replay-legend { font-size: 0.66rem; gap: 3px 7px; }
}
@media (max-width: 420px) {
  .replay-readout-primary { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (pointer: coarse) {
  .replay-scrubber { height: 32px; }
}

/* ---- The report header band and the story lede ------------------------------ */
/* ONE surface for the report's identity: flight number and status, the date, the actions, the
   route with the aircraft beside it, and the headline figures as a flat strip. The KPI tiles
   and the metadata cards live in Flight details at its foot. */
.report-head {
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface-1);
  padding: 20px 22px;
  margin-bottom: 26px;
}
.report-head-top { display: flex; align-items: center; gap: 10px 16px; flex-wrap: wrap; }
.report-head-id { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.report-head-badges { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.report-head-meta { color: var(--text-muted); font-size: 0.88rem; }
.report-head-actions { margin-left: auto; display: flex; gap: 8px; flex-wrap: wrap; }
.report-head-route { display: flex; align-items: center; justify-content: space-between; gap: 16px 24px; flex-wrap: wrap; margin-top: 16px; }
.report-head-aircraft { display: flex; flex-direction: column; align-items: flex-end; gap: 2px; text-align: right; }
.report-head-aircraft .mono { font-size: 1.05rem; font-weight: 600; color: var(--text-primary); }
.report-head-aircraft span:last-child { color: var(--text-muted); font-size: 0.85rem; }
.report-head-aircraft .mono:last-child { color: var(--text-primary); font-size: 1.05rem; }
.report-head-figures {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
}
.report-figure { padding: 0 16px; border-left: 1px solid var(--border); min-width: 0; }
.report-figure:first-child { padding-left: 0; border-left: 0; }
.report-figure-value {
  font-family: var(--font-mono);
  font-size: 1.35rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  line-height: 1.2;
  color: var(--text-primary);
}
.report-figure-label { margin-top: 2px; font-size: 0.72rem; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-muted); }
.report-head .notice { margin-top: 14px; }
@media (max-width: 700px) {
  .report-head { padding: 16px; }
  .report-head-actions { margin-left: 0; }
  .report-head-aircraft { align-items: flex-start; text-align: left; }
  .report-head-figures { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px 0; }
  .report-figure:nth-child(3n + 1) { padding-left: 0; border-left: 0; }
}
/* The story as the debrief's opening paragraph: unboxed, an accent rule down its left, the
   first sentence leading, and a way straight into the replay. */
.debrief-lede { border-left: 3px solid var(--accent); padding: 2px 0 2px 18px; margin: 4px 0 22px; max-width: 760px; }
.debrief-lede .debrief-story { gap: 2px; }
.debrief-lede .debrief-story-line { padding: 3px 6px; font-size: 0.95rem; color: var(--text-secondary); }
.debrief-lede .debrief-story-lead { font-size: 1.2rem; font-weight: 600; line-height: 1.4; color: var(--text-primary); text-wrap: balance; }
.debrief-story-replay {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin: 8px 0 0 6px;
  background: none;
  border: 0;
  padding: 0;
  font-family: inherit;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--accent-bright);
  cursor: pointer;
}
.debrief-story-replay:hover { text-decoration: underline; }
/* Flight details at the foot: three captioned columns, no boxes. */
.details-band { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 22px 32px; }
.details-block { min-width: 0; }
.details-block h3 { margin: 0 0 8px; font-size: 0.76rem; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-muted); }
.details-block-wide { grid-column: 1 / -1; }
@media (max-width: 900px) { .details-band { grid-template-columns: 1fr; } }
/* A timeline row a click can seek to. */
.debrief-event.replay-seekable { cursor: pointer; }
.debrief-event.replay-seekable:hover { background: var(--accent-soft); }

/* ---- The Landing Runway Analysis card ------------------- */
/* Drawn by the shared runway-card.js over runway-diagram.js and flight-instruments.js
   (byte-identical in the Admin Portal, whose stylesheet carries the same rules under its own
   tokens). The card is a CONTAINER: below 560px its bands stack and the stat rail becomes a
   2x2 grid, whatever the page's own breakpoints are doing around it. */
.runway-card { container-type: inline-size; }
.runway-card-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.runway-card-heading { display: flex; flex-direction: column; gap: 4px; }
.runway-card-title { margin: 0; }
.runway-card-ident { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.runway-card-code { font-family: var(--font-mono); font-size: 1rem; font-weight: 600; letter-spacing: 0.02em; color: var(--text-primary); }
.runway-card-name { color: var(--text-muted); font-size: 0.85rem; }
.runway-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  padding: 3px 10px;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-secondary);
  white-space: nowrap;
}
.runway-badge::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.runway-badge-high { color: var(--success); border-color: color-mix(in srgb, var(--success) 45%, transparent); }
.runway-badge-inferred { color: var(--warning); border-color: color-mix(in srgb, var(--warning) 45%, transparent); }
.runway-badge-unknown { color: var(--text-muted); }
.runway-card-main { display: grid; grid-template-columns: minmax(0, 1fr) 220px; gap: 20px; margin-top: 14px; }
.runway-card-hero { min-width: 0; }
.runway-sentences { margin-top: 10px; }
.runway-sentence-lead { font-size: 1.05rem; font-weight: 600; line-height: 1.4; color: var(--text-primary); text-wrap: balance; }
.runway-sentence-sub { margin-top: 4px; font-size: 0.9rem; color: var(--text-secondary); }
.runway-flag {
  margin-top: 8px;
  padding: 6px 10px;
  border-left: 3px solid var(--warning);
  background: color-mix(in srgb, var(--warning) 12%, transparent);
  font-size: 0.85rem;
  color: var(--text-primary);
}
.runway-tertiary { margin: 10px 0 0; font-size: 0.76rem; line-height: 1.5; color: var(--text-muted); }
.runway-rail { display: grid; grid-template-columns: 1fr; gap: 10px; align-content: start; }
.runway-stat { padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--surface-2); }
.runway-stat-label { font-size: 0.7rem; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-muted); }
.runway-stat-value {
  display: flex;
  align-items: baseline;
  gap: 6px;
  flex-wrap: wrap;
  margin-top: 2px;
  font-family: var(--font-mono);
  font-size: 1.35rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--text-primary);
}
.runway-stat-unit { font-family: var(--font-body); font-size: 0.72rem; font-weight: 500; color: var(--text-muted); }
.runway-stat-pair { font-family: var(--font-body); font-size: 0.85rem; font-weight: 500; color: var(--text-secondary); }
.runway-stat-sub { display: flex; align-items: center; gap: 4px; margin-top: 2px; font-size: 0.76rem; color: var(--text-muted); }
.runway-stat-ok { color: var(--success); font-weight: 700; }
.runway-card-second { display: grid; grid-template-columns: 150px minmax(0, 1fr); gap: 20px; margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--border); }
.runway-tile { min-width: 0; }
.runway-tile-cap { margin-bottom: 6px; font-size: 0.7rem; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-muted); }
.runway-tile-body { max-width: 150px; }
.runway-facts { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 6px 16px; align-content: start; font-size: 0.88rem; }
.runway-fact-key { color: var(--text-muted); }
.runway-fact-value { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; min-width: 0; color: var(--text-primary); }
.runway-fact-note { font-size: 0.8rem; color: var(--text-muted); }
.runway-fact-absent { font-style: italic; color: var(--text-muted); }
.runway-aoa-gauge { width: 100%; max-width: 260px; }
.runway-depart {
  display: flex;
  align-items: center;
  gap: 8px 14px;
  flex-wrap: wrap;
  margin-top: 16px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface-2);
  font-size: 0.85rem;
  color: var(--text-secondary);
}
.runway-depart-tag { font-size: 0.7rem; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-muted); }
.runway-depart-code { font-family: var(--font-mono); font-weight: 600; color: var(--text-primary); }
.runway-depart-figs { flex: 1 1 auto; min-width: 0; }
.runway-depart-fig { font-family: var(--font-mono); font-weight: 600; color: var(--text-primary); }
/* The diagram: the runway to scale along its length, labels as HTML rows above and below. */
.runway-diagram { position: relative; margin-top: 6px; }
.runway-diagram-svg { display: block; width: 100%; height: auto; overflow: visible; }
.runway-diagram-labels { position: relative; min-height: 1.35em; font-size: 0.74rem; color: var(--text-muted); }
.runway-diagram-label { position: absolute; transform: translateX(-50%); white-space: nowrap; max-width: 48%; overflow: hidden; text-overflow: ellipsis; }
.runway-diagram-label-start { transform: none; max-width: 70%; }
.runway-diagram-label-strong { color: var(--text-primary); font-weight: 600; }
.runway-diagram-label-zone { color: var(--success); }
.runway-diagram-tick-end { color: var(--text-secondary); }
.runway-pavement { fill: rgba(255, 255, 255, 0.09); stroke: var(--border-strong); stroke-width: 1.5; }
.runway-pavement-assumed { stroke: var(--warning); }
.runway-displaced { stroke: rgba(255, 255, 255, 0.28); stroke-width: 2; }
.runway-zone { fill: color-mix(in srgb, var(--success) 16%, transparent); }
.runway-zone-edge { stroke: color-mix(in srgb, var(--success) 60%, transparent); stroke-width: 1; stroke-dasharray: 3 3; }
.runway-threshold { fill: var(--text-primary); }
.runway-threshold-keys { fill: rgba(255, 255, 255, 0.55); }
.runway-centreline { stroke: rgba(255, 255, 255, 0.4); stroke-width: 1.5; stroke-dasharray: 14 10; }
.runway-ident { fill: rgba(255, 255, 255, 0.7); font-family: var(--font-mono); font-size: 16px; font-weight: 700; letter-spacing: 0.04em; }
.runway-rollout { fill: color-mix(in srgb, var(--accent-bright) 26%, transparent); }
.runway-end-stopped { fill: var(--text-primary); }
.runway-end-vacated { fill: none; stroke: var(--text-primary); stroke-width: 1.5; }
.runway-end-observed { fill: var(--text-muted); }
.runway-leader { stroke: rgba(255, 255, 255, 0.35); stroke-width: 1; stroke-dasharray: 2 3; }
.runway-tick { stroke: var(--text-muted); stroke-width: 1; }
.runway-contact { stroke: rgba(10, 10, 14, 0.9); stroke-width: 1.5; }
.runway-contact-touchdown { fill: #f2b56b; }
.runway-contact-liftoff { fill: #7bd88f; }
.runway-contact-halo { fill: #f2b56b; opacity: 0.55; transform-box: fill-box; transform-origin: center; }
/* The compact AOA gauge in the facts list: a scale, never a band. */
.aoa-gauge-svg { display: block; width: 100%; height: auto; overflow: visible; }
.aoa-gauge-track { fill: rgba(255, 255, 255, 0.1); }
.aoa-gauge-fill { fill: color-mix(in srgb, var(--accent-bright) 55%, transparent); }
.aoa-gauge-mark { stroke: var(--text-primary); stroke-width: 2; }
.aoa-gauge-tick-label { fill: var(--text-muted); font-size: 8px; }
.aoa-gauge-value { fill: var(--text-primary); font-size: 9px; font-weight: 600; }
@container (max-width: 560px) {
  .runway-card-main, .runway-card-second { grid-template-columns: 1fr; }
  .runway-rail { grid-template-columns: 1fr 1fr; }
  .runway-diagram-tick-minor { display: none; }
  .runway-tile-body { max-width: 120px; }
}
/* The attitude tile, drawn by flight-instruments.js inside the card's second band. */
.instrument-svg { display: block; width: 100%; height: auto; }
.instrument-face { fill: rgba(255, 255, 255, 0.04); stroke: var(--border); stroke-width: 1.5; }
.instrument-face-ring { fill: none; stroke: var(--border); stroke-width: 1.5; }
.instrument-tick { stroke: var(--text-muted); stroke-width: 1.5; }
.instrument-tick-label { fill: var(--text-muted); font-size: 8px; }
.instrument-needle { stroke: var(--text-primary); stroke-width: 2.5; stroke-linecap: round; }
.instrument-hub { fill: var(--text-primary); }
.instrument-value { fill: var(--text-primary); font-size: 13px; font-weight: 600; }
.instrument-caption { fill: var(--text-muted); font-size: 8px; letter-spacing: 0.06em; text-transform: uppercase; }
.attitude-sky { fill: #2f6fb0; }
.attitude-ground { fill: #7a5a2f; }
.attitude-horizon { stroke: #ffffff; stroke-width: 1.5; }
.attitude-pitch-line { stroke: rgba(255, 255, 255, 0.7); stroke-width: 1; }
.attitude-aircraft { fill: none; stroke: #f2b56b; stroke-width: 2.5; stroke-linejoin: round; }
/* ---- Arrival analysis: the gates ladder over the runway card ------------------ */
/* A sub-heading inside the debrief (the page has two heading levels: sections, and these). */
.debrief-subhead { display: flex; align-items: baseline; gap: 12px; margin: 26px 0 12px; padding-top: 14px; border-top: 1px solid var(--border); }
/* An accent rail down a whole debrief section - the story lede's own treatment - so the analysis
   sections read as one object rather than a loose heading above a list. The subhead's top rule
   would double the separation, so it stands down inside a railed section and the bar does the
   dividing. */
.debrief-rail { border-left: 3px solid var(--accent); padding-left: 18px; }
.debrief-rail .debrief-subhead { border-top: 0; padding-top: 0; }
.debrief-subhead h3 { margin: 0; font-size: 1.15rem; letter-spacing: -0.01em; }
/* The ladder: the analyzer's four altitudes as columns, a configured gate a button that seeks
   the replay, an unconfigured altitude a dashed placeholder so the ladder keeps its shape.
   Colour lives only on the verdict mark - never a column background. */
.gate-ladder {
  margin-bottom: 16px;
  padding: 12px 14px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface-1);
}
.gate-ladder-cap { margin: 0 0 10px; font-size: 0.78rem; color: var(--text-muted); }
.gate-ladder-row { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px; }
.gate {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  min-width: 0;
  padding: 10px 12px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface-2);
  font-family: inherit;
  text-align: left;
  color: var(--text-primary);
}
button.gate { cursor: pointer; }
button.gate:hover, button.gate:focus-visible { border-color: var(--accent); }
.gate-unset { border-style: dashed; background: transparent; color: var(--text-muted); }
.gate-selected { outline: 2px solid var(--accent); outline-offset: 1px; }
.gate-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; width: 100%; }
.gate-alt { font-family: var(--font-mono); font-size: 1.1rem; font-weight: 600; }
.gate-unset .gate-alt { font-weight: 500; color: var(--text-muted); }
.gate-mark { font-size: 1rem; font-weight: 700; color: var(--text-muted); }
.gate-pass .gate-mark { color: var(--success); }
.gate-fail .gate-mark { color: var(--danger); }
.gate-notes { display: flex; flex-direction: column; gap: 1px; font-family: var(--font-mono); font-size: 0.76rem; color: var(--text-secondary); }
.gate-unset .gate-notes { font-family: inherit; }
.gate-note { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.gate-hint { position: absolute; right: 10px; bottom: 8px; font-size: 0.7rem; color: var(--accent-bright); opacity: 0; transition: opacity 120ms; }
button.gate:hover .gate-hint, button.gate:focus-visible .gate-hint { opacity: 1; }
.gate-ladder-verdict { margin: 10px 0 0; font-size: 0.82rem; }
@media (max-width: 700px) {
  .gate-ladder-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .gate-hint { display: none; }
}
@media (prefers-reduced-motion: reduce) { .gate-hint { transition: none; } }

/* ---- The terrain profile ------------------------------------------------------- */
/* Drawn by the shared terrain-profile.js (byte-identical in the Admin Portal, whose
   stylesheet carries the same rules under its own tokens): altitude over the DEM-derived
   terrain per section, the ticks as HTML at percentages, the source note beneath. */
.terrain-profile { margin-top: 8px; }
.terrain-chart { position: relative; height: 150px; margin-top: 10px; }
.terrain-chart-svg { display: block; width: 100%; height: 100%; }
.terrain-fill { fill: rgba(122, 90, 47, 0.55); stroke: #b08a55; stroke-width: 1.5; }
.terrain-corridor-fill { fill: rgba(176, 138, 85, 0.22); stroke: #b08a55; stroke-width: 1; stroke-dasharray: 4 3; }
.terrain-altitude { stroke: var(--accent); stroke-width: 2; stroke-linejoin: round; }
.terrain-chart-ceiling, .terrain-chart-floor { position: absolute; left: 6px; font-size: 0.7rem; color: var(--text-muted); pointer-events: none; }
.terrain-chart-ceiling { top: 4px; }
.terrain-chart-floor { bottom: 4px; }
.terrain-chart-ticks { position: relative; height: 1.4em; font-size: 0.72rem; color: var(--text-muted); }
.terrain-chart-tick { position: absolute; top: 0; transform: translateX(-50%); white-space: nowrap; }
.terrain-chart-tick:first-child { transform: none; }
.terrain-chart-tick-end { transform: translateX(-100%); }
.terrain-chart-caption { margin: 2px 0 0; font-size: 0.78rem; color: var(--text-muted); }
.terrain-note { margin: 12px 0 0; font-size: 0.78rem; color: var(--text-muted); }
.terrain-attribution { margin: 4px 0 0; font-size: 0.72rem; color: var(--text-muted); }

/* The public flight page's share box: a dashed container for the share link with a
   copy-to-clipboard icon beside it. The button is the ordinary small button squared off to hold
   one icon. */
.share-box {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px 12px;
  margin-top: 14px;
  padding: 10px 12px;
  border: 1px dashed var(--border);
  border-radius: var(--radius-sm);
}
.share-box .share-label { font-size: 0.85rem; color: var(--text-muted); white-space: nowrap; }
.share-box .share-url { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; font-size: 0.9rem; }
.share-box .share-copy {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  flex: 0 0 auto;
}
.share-box .share-copy svg { width: 16px; height: 16px; }

/* The terrain card's data-sources disclosure: one summary line stays in view, the full source
   note and the dataset's attribution open on demand. */
.terrain-sources { margin-top: 8px; font-size: 0.78rem; color: var(--text-muted); }
.terrain-sources summary { cursor: pointer; }
.terrain-sources .terrain-note { margin-top: 6px; }
/* The segmented terrain card: one chart behind Full flight | Departure | Approach, the headline
   minima as a strip, the detailed evidence behind a disclosure. */
.terrain-segments {
  display: inline-flex;
  gap: 2px;
  margin-bottom: 4px;
  padding: 3px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface-2);
}
.terrain-seg {
  border: 0;
  border-radius: 999px;
  min-height: 32px;
  padding: 5px 14px;
  background: transparent;
  color: var(--text-secondary);
  font-family: inherit;
  font-size: 0.82rem;
  font-weight: 600;
  cursor: pointer;
}
.terrain-seg:hover { color: var(--text-primary); }
.terrain-seg-on { background: var(--surface-3); color: var(--text-primary); box-shadow: 0 0 0 1px var(--border-strong); }
.terrain-card-chart .terrain-chart { height: 220px; }
.terrain-metrics {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 12px 24px;
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}
.terrain-metric { min-width: 0; }
.terrain-metric-label { font-size: 0.7rem; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-muted); }
.terrain-metric-value { margin-top: 2px; font-family: var(--font-mono); font-size: 1.25rem; font-weight: 600; font-variant-numeric: tabular-nums; color: var(--text-primary); }
.terrain-metric-sub { margin-top: 2px; font-size: 0.76rem; color: var(--text-muted); }
.terrain-details summary { font-weight: 600; color: var(--text-secondary); }
.terrain-detail-rows { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 4px 16px; margin: 10px 0 0; font-size: 0.8rem; }
.terrain-detail-rows dt { color: var(--text-muted); }
.terrain-detail-rows dd { margin: 0; color: var(--text-primary); }
@media (max-width: 700px) {
  .terrain-segments { display: flex; width: 100%; box-sizing: border-box; }
  .terrain-seg { flex: 1 1 0; min-width: 0; min-height: 44px; padding: 5px 6px; font-size: 0.78rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .terrain-card-chart .terrain-chart { height: 200px; }
  .terrain-detail-rows { grid-template-columns: 1fr; }
  /* Five tick labels collide on a phone; the ends and the middle are enough. */
  .terrain-chart-tick:nth-child(2), .terrain-chart-tick:nth-child(4) { display: none; }
}

/* ---- the Flight Streak tile ----------------------------------------
   The tile is a .prog-stat like its neighbours; only its TONE is new, and it travels as a
   data attribute set by dashboard.js so the stylesheet decides what "warn" looks like. The
   flame flares once when the week is secured (600 ms), and not at all under reduced motion. */
.prog-stat[data-tone="warn"] .prog-stat-value { color: var(--warning); }
.prog-stat[data-tone="warn"] .prog-stat-label { color: var(--warning); }
.prog-stat[data-tone="muted"] .prog-stat-value { color: var(--text-muted); }
.streak-flame { transform-origin: 50% 90%; }
.prog-stat[data-tone="ok"] .streak-flame { animation: streak-flare 600ms ease-out 1; }
@keyframes streak-flare {
  0% { transform: scale(1); }
  40% { transform: scale(1.35); }
  100% { transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .prog-stat[data-tone="ok"] .streak-flame { animation: none; }
}

/* ---- the My streak page --------------------------------------
   The hero is the dashboard tile grown up: the same figure, label and tone, with the sentence
   and a fact list beside it. The calendar is a grid of cells that each carry a GLYPH and a WORD
   (never colour alone) plus the period's date, in the tones the tile already uses. The two cards
   beneath are ordinary .cards; the history is an ordinary data table. */
.streak-section { padding: 28px 0 0; }
.streak-section .section-head { margin-bottom: 14px; }

.streak-hero {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 18px 40px;
  padding: 22px 26px;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: 14px;
}
.streak-hero-main { flex: 1.4; min-width: 260px; display: flex; flex-direction: column; gap: 6px; }
.streak-hero-figure {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  color: var(--accent-bright);
}
.streak-hero-figure strong {
  font-size: 2rem;
  font-weight: 700;
  line-height: 1.1;
  color: var(--text-primary);
  white-space: nowrap;
}
.streak-hero-label { font-size: 0.95rem; color: var(--text-muted); }
.streak-hero-line { margin: 6px 0 0; font-size: 1rem; line-height: 1.45; color: var(--text-secondary); }
.streak-hero-deadline { margin: 0; font-size: 0.85rem; color: var(--text-muted); }
.streak-hero[data-tone="warn"] .streak-hero-figure,
.streak-hero[data-tone="warn"] .streak-hero-figure strong,
.streak-hero[data-tone="warn"] .streak-hero-label { color: var(--warning); }
.streak-hero[data-tone="muted"] .streak-hero-figure,
.streak-hero[data-tone="muted"] .streak-hero-figure strong { color: var(--text-muted); }
.streak-hero[data-tone="ok"] .streak-flame { animation: streak-flare 600ms ease-out 1; transform-origin: 50% 90%; }
@media (prefers-reduced-motion: reduce) {
  .streak-hero[data-tone="ok"] .streak-flame { animation: none; }
}

/* The fact list: label over value, in a row that wraps. */
.streak-hero-facts {
  flex: 1;
  min-width: 220px;
  display: flex;
  flex-wrap: wrap;
  gap: 12px 28px;
  margin: 0;
}
.streak-hero-fact { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.streak-hero-fact dt { font-size: 0.76rem; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-muted); }
.streak-hero-fact dd { margin: 0; font-weight: 600; color: var(--text-primary); white-space: nowrap; }

/* The calendar. Cells are a fixed shape so the grid reads as a grid; the glyph is the first
   thing in the cell and the word sits under it, so the meaning survives a colour-blind reader
   and a monochrome print alike. */
.streak-calendar {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(78px, 1fr));
  gap: 8px;
}
.streak-cell {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 10px 6px 8px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface-2);
  text-align: center;
  min-width: 0;
}
.streak-cell-glyph { font-size: 1.15rem; line-height: 1.2; color: var(--text-secondary); }
.streak-cell-word { font-size: 0.72rem; font-weight: 600; color: var(--text-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; min-height: 1em; }
.streak-cell-label { font-size: 0.72rem; color: var(--text-muted); white-space: nowrap; }
.streak-cell[data-tone="ok"] { border-color: color-mix(in srgb, var(--success) 45%, transparent); background: color-mix(in srgb, var(--success) 12%, var(--surface-2)); }
.streak-cell[data-tone="ok"] .streak-cell-glyph,
.streak-cell[data-tone="ok"] .streak-cell-word { color: var(--success); }
.streak-cell[data-tone="warn"] { border-color: color-mix(in srgb, var(--warning) 45%, transparent); background: color-mix(in srgb, var(--warning) 12%, var(--surface-2)); }
.streak-cell[data-tone="warn"] .streak-cell-glyph,
.streak-cell[data-tone="warn"] .streak-cell-word { color: var(--warning); }
.streak-cell[data-tone="accent"] { border-color: var(--accent-glow); background: var(--accent-soft); }
.streak-cell[data-tone="accent"] .streak-cell-glyph,
.streak-cell[data-tone="accent"] .streak-cell-word { color: var(--accent-bright); }
.streak-cell[data-tone="muted"] .streak-cell-glyph,
.streak-cell[data-tone="muted"] .streak-cell-word { color: var(--text-muted); }
.streak-cell[data-tone="empty"] { border-style: dashed; background: transparent; }
.streak-cell[data-tone="empty"] .streak-cell-glyph { color: var(--text-muted); }

.streak-legend { display: flex; flex-wrap: wrap; gap: 6px 18px; margin-top: 12px; font-size: 0.82rem; color: var(--text-secondary); }
.streak-legend-item { display: inline-flex; align-items: center; gap: 4px; }
.streak-legend-item .streak-cell-glyph { font-size: 1rem; }
.streak-legend-item[data-tone="ok"] .streak-cell-glyph { color: var(--success); }
.streak-legend-item[data-tone="warn"] .streak-cell-glyph { color: var(--warning); }
.streak-legend-item[data-tone="accent"] .streak-cell-glyph { color: var(--accent-bright); }
.streak-legend-item[data-tone="muted"] .streak-cell-glyph { color: var(--text-muted); }

/* The two cards side by side, stacking on a phone. .card carries no margin on purpose (it lives
   in grids), so the columns grid supplies the gap. */
.streak-columns {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 16px;
  padding-top: 28px;
}
.streak-card:hover { transform: none; }
.streak-card h3 { margin-bottom: 12px; }
.streak-line { margin: 0 0 8px; font-size: 0.92rem; line-height: 1.45; color: var(--text-secondary); }
.streak-note { margin: 10px 0 0; font-size: 0.82rem; line-height: 1.45; color: var(--text-muted); }

/* The three freeze figures: banked, covering, in hand. */
.streak-figures { display: flex; gap: 22px; margin: 4px 0 14px; }
.streak-figure { display: flex; flex-direction: column; gap: 1px; }
.streak-figure strong { font-size: 1.35rem; font-weight: 700; line-height: 1.15; color: var(--text-primary); }
.streak-figure span { font-size: 0.78rem; color: var(--text-muted); }

/* The milestone list: dense rows, a rule between them, the tone on the left edge. */
.streak-list { display: flex; flex-direction: column; }
.streak-list-item { padding: 10px 0 10px 12px; border-top: 1px solid var(--border); border-left: 3px solid transparent; }
.streak-list-item:first-child { border-top: none; }
.streak-list-item[data-tone="ok"] { border-left-color: var(--success); }
.streak-list-item[data-tone="accent"] { border-left-color: var(--accent-bright); }
.streak-list-item[data-tone="muted"] { border-left-color: var(--border-strong); }
.streak-item-head { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 10px; }
.streak-item-title { font-weight: 600; color: var(--text-primary); }
.streak-item-meta { font-size: 0.82rem; color: var(--text-muted); }
.streak-item-status { margin-top: 2px; font-size: 0.88rem; color: var(--text-secondary); }
.streak-item-note { margin-top: 2px; font-size: 0.82rem; color: var(--text-muted); }
.streak-list-item[data-tone="ok"] .streak-item-note { color: var(--success); }

/* The history table's current run, and the record tiles' small detail line. */
.streak-history-current td:first-child { color: var(--accent-bright); }
.streak-tile-detail { margin-top: 4px; font-size: 0.8rem; color: var(--text-muted); }

@media (max-width: 700px) {
  .streak-hero { padding: 18px; }
  .streak-hero-figure strong { font-size: 1.6rem; }
  .streak-calendar { grid-template-columns: repeat(auto-fill, minmax(64px, 1fr)); gap: 6px; }
  .streak-cell { padding: 8px 4px 6px; }
  .streak-cell-word { font-size: 0.66rem; }
  .streak-cell-label { font-size: 0.66rem; }
}

/* ---- the pilot identity primitive ----

   One vocabulary for a pilot wherever one is named, so every surface - the leaderboard, the hub
   standings, the rosters - renders the same person through the same rules.

   The box is fixed from the first paint. Both the uploaded image and the generated data URI
   arrive after layout, so a circle that sized itself to its contents would move the row under
   the reader's cursor - fifty times on a fifty-row roster. Width, height and flex: none are all
   load-bearing, not decoration. */
.pilot-avatar {
  position: relative;
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  border-radius: 50%;
  background: var(--accent-soft);
  color: var(--accent-bright);
  font-weight: 600;
  line-height: 1;
  /* The default is SM; the size classes below override. */
  width: 32px;
  height: 32px;
  font-size: 0.72rem;
}
.pilot-avatar-xs { width: 24px; height: 24px; font-size: 0.6rem; }
.pilot-avatar-sm { width: 32px; height: 32px; font-size: 0.72rem; }
.pilot-avatar-md { width: 40px; height: 40px; font-size: 0.82rem; }
.pilot-avatar-lg { width: 96px; height: 96px; font-size: 1.7rem; }

/* The initials sit UNDER the image rather than instead of it: that is the no-layout-shift half
   and the image's error fallback in one - removing a failed <img> reveals what was already
   there instead of leaving an empty hole. */
.pilot-avatar-initials { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; }
.pilot-avatar-image { position: relative; width: 100%; height: 100%; object-fit: cover; display: block; }

.pilot-identity,
.pilot-identity-bare {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
  color: inherit;
  text-decoration: none;
}
/* The whole-row link must not inherit the global `a` underline-on-hover: an identity is a name
   and a picture, and underlining every line of it reads as a rendering fault. The name alone
   responds, which is what says it is clickable. */
a.pilot-identity:hover { text-decoration: none; }
a.pilot-identity:hover .pilot-identity-name { color: var(--accent-bright); }
a.pilot-identity:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 2px; border-radius: 8px; }

.pilot-identity-body { display: flex; flex-direction: column; min-width: 0; gap: 1px; }
.pilot-identity-name { font-size: 0.92rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Mono, because it is a CODE - the same convention every identifier on this platform uses. */
.pilot-identity-number { font-family: var(--font-mono); font-size: 0.7rem; color: var(--text-muted); }
.pilot-identity-line { font-size: 0.74rem; color: var(--text-muted); }

/* ---- The signed-in header's pilot button ---- */
.pilot-menu-identity { display: inline-flex; align-items: center; gap: 9px; min-width: 0; }
.pilot-menu-text { display: flex; flex-direction: column; align-items: flex-start; min-width: 0; gap: 0; }
.pilot-menu-number { font-family: var(--font-mono); font-size: 0.64rem; color: var(--text-muted); line-height: 1.2; }

/* ---- profile-settings.html: the avatar card ---- */
.avatar-editor { display: flex; flex-wrap: wrap; gap: 22px; align-items: flex-start; }
.avatar-editor-current { display: flex; flex-direction: column; align-items: center; gap: 9px; }
.avatar-editor-caption { font-size: 0.74rem; color: var(--text-muted); }
.avatar-editor-choices { flex: 1; min-width: 240px; }
/* The family chips above the grid. They are the site's own .chip / .chip.active - matched, not
   invented - and this rule only gives the row the gap the grid beneath it needs.
   [hidden] is spelled out because a bare hidden attribute loses to a display rule at equal
   specificity. */
.avatar-style-chips { margin-bottom: 12px; }
.avatar-style-chips[hidden] { display: none; }
.avatar-option-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(56px, 1fr)); gap: 10px; margin-bottom: 14px; }
/* A button, so it is reachable by keyboard and announces itself as pressable - a clickable div
   would be neither. */
.avatar-option {
  appearance: none;
  border: 2px solid transparent;
  background: none;
  padding: 2px;
  border-radius: 50%;
  cursor: pointer;
  line-height: 0;
}
.avatar-option:hover { border-color: var(--border-strong); }
.avatar-option-selected { border-color: var(--accent-bright); }
.avatar-editor-actions { display: flex; flex-wrap: wrap; gap: 9px; align-items: center; }
/* `.auth-card .btn` is `width: 100%` with a 22px top margin because an auth card normally ends
   in one submit button (sign in, register, reset). The avatar editor puts a row of small buttons
   inside that same card, so without this exemption Shuffle / Upload / Use my initials each
   stretch to the full card width and stack three deep - and so do the cropper's Save and
   Cancel. Every class involved is well defined, so `stylesheet-classes.test.js` cannot see this
   (it checks a class is defined, never that it is the right one for where it sits); only
   rendering it does. Written at (0,3,0) rather than as a same-specificity rule further down the
   file, so it cannot be undone by a reorder. */
.auth-card .avatar-editor-actions .btn { width: auto; margin-top: 0; }
.avatar-editor-note { font-size: 0.76rem; color: var(--text-muted); margin-top: 10px; }

/* The cropper: a square stage the picture is dragged inside, with a circular mask over it so
   the pilot sees what everybody else will see rather than a rectangle they have to imagine. */
.avatar-cropper { display: none; flex-direction: column; gap: 12px; margin-top: 16px; }
.avatar-cropper-open { display: flex; }
.avatar-cropper-stage {
  position: relative;
  width: 240px;
  height: 240px;
  max-width: 100%;
  border-radius: 12px;
  overflow: hidden;
  background: var(--surface-3);
  touch-action: none;
  cursor: grab;
}
.avatar-cropper-canvas { display: block; width: 100%; height: 100%; }
.avatar-cropper-mask {
  position: absolute;
  inset: 0;
  pointer-events: none;
  /* The circle is a hole in a dimmed overlay - one element, no maths, and it cannot fall out of
     step with the crop the server actually takes (a centre square). */
  background: radial-gradient(circle at 50% 50%, transparent 0 49.5%, rgba(0, 0, 0, 0.55) 50%);
}
.avatar-cropper-controls { display: flex; align-items: center; gap: 10px; max-width: 240px; }
.avatar-cropper-zoom { flex: 1; accent-color: var(--accent); } /* the theme's accent, not the browser's blue (the replay scrubber's rule) */

/* ---- Pilot profile: identity and totals above a flat, responsive editorial layout. ---- */
.profile-page { padding-top: 24px; }
.profile-eyebrow { margin: 0 0 14px; color: var(--text-secondary); font-size: 0.84rem; }
.profile-hero {
  padding: 28px;
  border-radius: 16px;
  border: 1px solid var(--border);
  background: linear-gradient(135deg, var(--accent-soft), transparent 70%), var(--surface-2);
}
.profile-hero-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 24px; }
.profile-hero-identity { display: flex; align-items: center; gap: 24px; min-width: 0; }
.profile-hero-identity > .pilot-identity-bare { flex: none; }
.profile-hero-copy { min-width: 0; }
.profile-name { margin: 0 0 8px; font-size: clamp(1.75rem, 3vw, 2.4rem); line-height: 1.2; letter-spacing: -0.025em; overflow-wrap: anywhere; }
.profile-hero-meta { display: flex; align-items: center; flex-wrap: wrap; gap: 12px; margin-bottom: 8px; font-size: 0.88rem; color: var(--text-secondary); }
.profile-hero-lines { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; }
.profile-hero-line { font-size: 0.88rem; color: var(--text-secondary); }
a.profile-hero-line { color: var(--text-secondary); text-decoration: none; }
a.profile-hero-line:hover { color: var(--accent-bright); text-decoration: underline; }
.profile-hero-activity { display: flex; flex-direction: column; align-items: flex-end; gap: 10px; max-width: 32%; }

.profile-layout { display: grid; grid-template-columns: minmax(0, 2.15fr) minmax(0, 1fr); gap: 36px; margin-top: 30px; }
.profile-layout:has(> :only-child) { grid-template-columns: minmax(0, 1fr); }
.profile-main, .profile-sidebar { min-width: 0; }
.profile-sidebar { border-left: 1px solid var(--border); padding-left: 28px; }
.profile-sidebar:only-child { border: 0; padding: 0; }
.profile-section { min-width: 0; }
.profile-section + .profile-section { margin-top: 26px; padding-top: 24px; border-top: 1px solid var(--border); }
.profile-section-head { display: flex; align-items: baseline; justify-content: space-between; flex-wrap: wrap; gap: 8px 16px; margin-bottom: 16px; }
.profile-section-title { font-size: 1.3rem; font-weight: 650; line-height: 1.3; color: var(--text-primary); margin: 0; }
.profile-section > .muted { font-size: 0.86rem; margin: 12px 0 0; }
.profile-network-summary { color: var(--text-secondary); font-size: 0.82rem; }

/* Missing statistics remain absent; the available figures divide the strip equally. */
.profile-career { margin-top: 26px; padding-top: 22px; border-top: 1px solid var(--border); }
.profile-career > .muted { font-size: 0.84rem; margin: 16px 0 0; }
.profile-tiles { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); }
.profile-tile { display: flex; flex-direction: column; gap: 2px; text-align: center; padding: 0 12px; }
.profile-tile + .profile-tile { border-left: 1px solid var(--border); }
.profile-tile-value { font-size: clamp(1.4rem, 2.5vw, 2rem); font-weight: 650; color: var(--text-primary); font-variant-numeric: tabular-nums; overflow-wrap: anywhere; line-height: 1.3; }
.profile-tile-label { font-size: 0.88rem; color: var(--text-secondary); }
.profile-rank { display: flex; align-items: center; flex-wrap: wrap; gap: 12px; }
.profile-rank-badge { width: 40px; height: 40px; object-fit: contain; }
.profile-rank-copy { display: flex; flex-direction: column; gap: 2px; min-width: 0; overflow-wrap: anywhere; }
.profile-rank-name { font-size: 1.05rem; font-weight: 600; }
.profile-rank-next { font-size: 0.86rem; color: var(--text-secondary); }
.profile-rank-hours { font-size: 0.9rem; margin: 22px 0 0; font-variant-numeric: tabular-nums; }
/* Rank progress measures hours only. The adjoining sentence retains every other requirement. */
.profile-bar { height: 8px; border-radius: 5px; background: var(--surface-3); margin: 12px 0 8px; overflow: hidden; }
.profile-bar-fill { height: 100%; background: var(--accent); border-radius: inherit; }
.profile-streak-line { font-size: 0.82rem; margin: 0; padding: 6px 12px; border: 1px solid var(--border-strong); border-radius: 999px; color: var(--accent-bright); }
.profile-streak-line[data-tone="warn"] { color: var(--warning); border-color: var(--warning); }
.profile-streak-line[data-tone="muted"] { color: var(--text-muted); }
.profile-live-pill { display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px; border-radius: 999px; background: var(--accent-soft); color: var(--text-primary); font-size: 0.82rem; text-decoration: none; }
.profile-live-pill::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--accent); flex: none; }
.profile-live-pill:hover { text-decoration: none; filter: brightness(1.15); }

.route-map.profile-map { height: 340px; width: 100%; margin-top: 0; border-radius: 12px; overflow: hidden; }
.profile-insight-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 20px; margin-top: 18px; }
.profile-insight { display: flex; flex-direction: column; gap: 4px; min-width: 0; overflow-wrap: anywhere; }
.profile-insight-label { font-size: 0.78rem; color: var(--text-secondary); }
.profile-insight-value { font-size: 1.05rem; font-weight: 600; color: var(--text-primary); }
.profile-insight-detail { font-size: 0.78rem; color: var(--text-secondary); }

/* Shared profile and dashboard flight rows: route first, secondary details, neutral rates. */
.recent-flight-columns, .recent-flight-row { display: grid; grid-template-columns: minmax(0, 2.2fr) minmax(0, 1.15fr) minmax(58px, 0.65fr) minmax(72px, 0.8fr); gap: 12px; align-items: center; padding: 12px 8px; }
.recent-flights[data-landing="hidden"] .recent-flight-columns,
.recent-flights[data-landing="hidden"] .recent-flight-row { grid-template-columns: minmax(0, 2.2fr) minmax(0, 1.15fr) minmax(58px, 0.65fr); }
.recent-flight-columns { background: var(--surface-1); border-radius: 6px; font-size: 0.8rem; color: var(--text-secondary); padding-block: 8px; }
.recent-flight-columns > :last-child { text-align: right; }
.recent-flight-list { list-style: none; padding: 0; margin: 0; }
.recent-flight-list > li { border-bottom: 1px solid var(--border); }
.recent-flight-row { color: var(--text-primary); font-size: 0.9rem; text-decoration: none; border-radius: 6px; }
.recent-flight-row > * { min-width: 0; overflow-wrap: anywhere; }
a.recent-flight-row:hover { background: var(--surface-1); text-decoration: none; }
a.recent-flight-row:hover .recent-flight-route strong { color: var(--accent-bright); }
a.recent-flight-row:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 2px; }
.recent-flight-detail { display: flex; flex-direction: column; gap: 3px; }
.recent-flight-detail .pirep-status { margin: 0; min-width: 0; }
.recent-flight-route { display: flex; flex-direction: column; gap: 3px; }
/* The site's list type, as on My PIREPs and Recent flights: airport codes and the flight number
   in the code font, the flight number the row's bold identifier rather than a grey caption, and
   one step larger throughout. */
.recent-flight-route strong { font-family: var(--font-mono); font-weight: 700; letter-spacing: 0.02em; }
.recent-flight-no { font-family: var(--font-mono); font-weight: 700; color: var(--text-primary); }
.recent-flight-secondary { color: var(--text-secondary); font-size: 0.8rem; line-height: 1.4; }
.recent-flight-detail, .recent-flight-time, .recent-flight-landing { color: var(--text-secondary); font-size: 0.86rem; }
.recent-flight-time, .recent-flight-landing { font-variant-numeric: tabular-nums; }
.recent-flight-landing { font-family: var(--font-mono); }
.recent-flight-landing, .recent-flights[data-landing="hidden"] .recent-flight-time { text-align: right; }
.profile-page a:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 3px; border-radius: 4px; }

.profile-type { padding: 12px 0; border-bottom: 1px solid var(--border); }
.profile-type-head { display: grid; grid-template-columns: 20px 4ch minmax(0, 1fr) auto; align-items: baseline; gap: 14px; }
.profile-type-icon { color: var(--text-secondary); }
.profile-type-code { font-family: var(--font-mono); font-size: 0.88rem; color: var(--text-primary); }
.profile-type-name { color: var(--text-secondary); font-size: 0.86rem; overflow-wrap: anywhere; }
.profile-type-figures { color: var(--text-secondary); font-size: 0.8rem; text-align: right; font-variant-numeric: tabular-nums; }

.profile-award-grid { display: flex; flex-direction: column; gap: 10px; }
.profile-award { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; padding: 12px; border: 1px solid var(--border); border-radius: 12px; background: var(--surface-1); }
.profile-award-pinned { border-color: var(--border-strong); }
.profile-award-badge { width: 40px; height: 40px; object-fit: contain; }
.profile-award-copy { display: flex; flex-direction: column; gap: 3px; flex: 1; min-width: 90px; overflow-wrap: anywhere; }
.profile-award-name { font-size: 0.88rem; font-weight: 600; }
.profile-award-source { font-size: 0.76rem; color: var(--text-secondary); }
.profile-bio { white-space: pre-line; overflow-wrap: anywhere; margin: 0 0 16px; font-size: 0.92rem; }
.profile-facts { display: grid; gap: 16px; margin: 0; }
.profile-facts div { display: flex; flex-direction: column; gap: 3px; }
.profile-facts dt { font-size: 0.84rem; color: var(--text-secondary); }
.profile-facts dd { margin: 0; font-size: 0.88rem; overflow-wrap: anywhere; }
.profile-unavailable { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; }

.profile-tour { margin-bottom: 12px; }
.profile-tour-head { display: flex; align-items: baseline; flex-wrap: wrap; gap: 8px; margin-bottom: 5px; }
.profile-tour-name { color: var(--text-primary); font-size: 0.9rem; overflow-wrap: anywhere; }
.profile-tour-progress { flex-basis: 100%; color: var(--text-secondary); font-size: 0.84rem; }
.profile-timeline-month { margin-bottom: 16px; }
.profile-timeline-label { font-size: 0.88rem; font-weight: 600; color: var(--text-primary); margin: 0 0 14px; }
.profile-timeline-entries { display: flex; flex-direction: column; gap: 12px; padding-left: 14px; border-left: 1px solid var(--border); }
.profile-timeline-entry { display: flex; align-items: center; gap: 8px; }
.profile-timeline-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--accent); flex: 0 0 auto; margin-left: -18px; }
.profile-timeline-text { color: var(--text-secondary); font-size: 0.86rem; overflow-wrap: anywhere; }
[data-theme="light"] .profile-streak-line[data-tone="warn"] { color: color-mix(in srgb, var(--warning) 60%, #000000); }

@media (max-width: 900px) {
  .profile-layout { grid-template-columns: minmax(0, 1fr); gap: 28px; }
  .profile-sidebar { border-left: 0; padding-left: 0; border-top: 1px solid var(--border); padding-top: 24px; }
  .profile-hero-top { flex-wrap: wrap; }
  .profile-hero-activity { max-width: 100%; flex-direction: row; flex-wrap: wrap; align-items: center; }
}
@media (max-width: 640px) {
  .profile-page { padding-top: 20px; }
  .profile-hero { padding: 20px; }
  .profile-hero-identity { align-items: flex-start; gap: 16px; }
  .profile-hero .pilot-avatar-lg { width: 64px; height: 64px; font-size: 1.2rem; }
  .profile-name { font-size: 1.6rem; }
  .profile-hero-line { font-size: 0.82rem; }
  .profile-tiles { grid-auto-flow: row; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px 0; }
  .profile-tile:nth-child(odd) { border-left: 0; }
  .profile-layout { margin-top: 24px; }
  .route-map.profile-map { height: 260px; }
  .recent-flight-columns { display: none; }
  .recent-flight-row, .recent-flights[data-landing="hidden"] .recent-flight-row { grid-template-columns: minmax(0, 1fr) auto; gap: 6px 12px; padding: 14px 4px; }
  .recent-flight-route { grid-column: 1 / -1; }
  .recent-flight-detail { grid-column: 1; }
  .recent-flight-time { grid-column: 2; grid-row: 2; text-align: right; }
  .recent-flight-landing { grid-column: 1 / -1; text-align: left; }
  .recent-flight-landing:not(:empty)::before { content: "Landing: "; font-family: var(--font-body); }
  .profile-type-head { grid-template-columns: 18px 4ch minmax(0, 1fr); gap: 8px 12px; }
  .profile-type-figures { grid-column: 2 / -1; text-align: left; }
}

@media (max-width: 380px) {
  .profile-hero-identity { flex-direction: column; }
}

/* ---- My PIREPs' filter bar ---- */

.flight-filters { margin-bottom: 22px; }
.flight-filter-fields { display: grid; grid-template-columns: minmax(0, 2.8fr) minmax(140px, 0.85fr) minmax(150px, 0.85fr); align-items: end; gap: 16px; }
.flight-filters label { display: flex; flex-direction: column; gap: 6px; margin: 0; color: var(--text-secondary); font-size: 0.82rem; min-width: 0; }
.flight-filters input, .flight-filters select { width: 100%; min-width: 0; min-height: 42px; padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface-2); color: var(--text-primary); font: inherit; font-size: 0.9rem; }
.flight-filters select { appearance: auto; }
.flight-filters input:focus-visible, .flight-filters select:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 2px; }
.flight-periods { margin-top: 14px; }
/* Classes, not ids, so they reach every page that uses the bar. */
.flight-filters-clear { margin-left: auto; }
.flight-dates { display: flex; align-items: end; flex-wrap: wrap; gap: 12px; margin-top: 14px; }
.flight-dates label { flex: 0 1 190px; }
.flight-dates-note { font-size: 0.8rem; padding-bottom: 10px; }
.flight-count { font-size: 0.82rem; margin: 18px 0 10px; }

@media (max-width: 640px) {
  .flight-filter-fields { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 12px; }
  .flight-search { grid-column: 1 / -1; }
  .flight-dates label { flex: 1 1 140px; }
  .flight-filters-clear { margin-left: 0; }
}

/* ---- Find a flight ----
   Every status carries an icon AND words (never colour alone); Booked is a badge, not a status. */

.fd-page { padding-bottom: 56px; }

.fd-head {
  display: flex;
  align-items: flex-end;
  gap: 16px;
  padding: var(--page-top) 0 16px;
}

.fd-head h1 {
  margin: 0;
  font-size: var(--page-title-size);
  letter-spacing: -0.02em;
}

.fd-sub {
  margin: 2px 0 0;
  color: var(--text-muted);
  font-size: 0.95rem;
}

.fd-muted { color: var(--text-muted); }
.fd-code { font-family: var(--font-mono); font-weight: 700; }

.fd-btn {
  padding: 9px 15px;
  font-size: 0.9rem;
  border: 1px solid var(--border-strong);
  background: var(--surface-2);
  color: var(--text-primary);
  white-space: nowrap;
}

.fd-btn:hover { border-color: var(--text-muted); }
.fd-btn.btn-primary { border-color: transparent; background: var(--accent); color: var(--text-on-accent); }
.fd-btn.btn-sm { padding: 6px 11px; font-size: 0.82rem; border-radius: 7px; }
.fd-btn .icon { width: 16px; height: 16px; }

/* The current location band. */
.fd-band {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 16px;
  padding: 16px 20px;
  border-radius: var(--radius-lg);
  border: 1px solid color-mix(in srgb, var(--accent-bright) 35%, transparent);
  background: linear-gradient(90deg, color-mix(in srgb, var(--accent) 20%, transparent),
    color-mix(in srgb, var(--accent) 5%, transparent) 60%, color-mix(in srgb, var(--surface-2) 60%, transparent));
}

.fd-band[hidden] { display: none; }

.fd-band-icon {
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  border-radius: var(--radius-md);
  display: flex;
  align-items: center;
  justify-content: center;
  background: color-mix(in srgb, var(--accent) 30%, transparent);
  color: var(--accent-bright);
}

.fd-band-icon .icon { width: 22px; height: 22px; }

.fd-band-k {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--text-secondary);
}

.fd-band-line { font-size: 1.18rem; }
.fd-band-note { color: var(--text-muted); font-size: 0.9rem; }
.fd-band-actions { margin-left: auto; display: flex; gap: 10px; align-items: center; }
.fd-band-actions .fd-btn { background: transparent; }

/* Travelling, and a pilot-wide block: said once, above everything they change. */
.fd-banner {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 16px;
  padding: 14px 18px;
  border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--warning) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--warning) 45%, transparent);
}

.fd-banner[hidden] { display: none; }
.fd-banner > .icon { width: 20px; height: 20px; flex-shrink: 0; color: var(--warning); }
.fd-banner-text { flex: 1; }
.fd-banner-detail { color: var(--text-secondary); }

/* The toolbar: the search and More filters on one row, the chips and the sort under them. Three
   columns, so More filters and Sort each end at the grid's right edge - with two, they would share
   one column as wide as the sort, and More filters would stop short of the cards. */
.fd-toolbar {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  grid-template-areas: "search search more" "chips sort sort";
  gap: 16px 12px;
  align-items: center;
}

.fd-search { grid-area: search; position: relative; }
.fd-more-wrap { grid-area: more; position: relative; }
.fd-chips { grid-area: chips; }
.fd-sort { grid-area: sort; }

.fd-search .fd-search-icon {
  position: absolute;
  left: 14px;
  top: 14px;
  width: 17px;
  height: 17px;
  color: var(--text-muted);
  pointer-events: none;
}

.fd-search input {
  width: 100%;
  height: 46px;
  box-sizing: border-box;
  padding: 0 14px 0 40px;
  border-radius: 10px;
  border: 1px solid var(--border-strong);
  background: var(--surface-1);
  color: var(--text-primary);
  font: inherit;
  font-size: 0.95rem;
}

.fd-search input:focus {
  outline: none;
  border-color: var(--accent-bright);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 30%, transparent);
}

.fd-more-wrap > .fd-btn { height: 46px; }

.fd-count {
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  box-sizing: border-box;
  border-radius: 999px;
  background: var(--accent);
  color: var(--text-on-accent);
  font-size: 0.75rem;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.fd-count[hidden] { display: none; }

.fd-chips { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.fd-presets { display: contents; }

.fd-chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  border: 1px solid var(--border-strong);
  background: transparent;
  color: var(--text-secondary);
  border-radius: 999px;
  padding: 7px 14px;
  font: inherit;
  font-size: 0.875rem;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
}

.fd-chip:hover { color: var(--text-primary); border-color: var(--text-muted); }
.fd-chip.on {
  color: var(--text-primary);
  border-color: color-mix(in srgb, var(--accent-bright) 60%, transparent);
  background: color-mix(in srgb, var(--accent) 28%, transparent);
}

.fd-chip[hidden] { display: none; }
.fd-chip .icon { width: 13px; height: 13px; }
.fd-chip-sm { padding: 5px 12px; font-size: 0.84rem; }
.fd-chip-short, .fd-narrow { display: none; }
.fd-vr { width: 1px; height: 22px; background: var(--border); margin: 0 6px; }
.fd-label { font-size: 0.8rem; font-weight: 600; color: var(--text-muted); }

.fd-sort { display: inline-flex; align-items: center; gap: 6px; font-size: 0.875rem; color: var(--text-muted); justify-self: end; }
/* The "Sort: Flight number ▾" control: the caret is drawn, the native arrow is not. */
.fd-sort::after { content: "\25BE"; margin-left: -2px; color: var(--text-muted); font-size: 0.75rem; pointer-events: none; }
.fd-sort select {
  appearance: none;
  -webkit-appearance: none;
  padding: 0;
  border: none;
  background: transparent;
  color: var(--text-primary);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}
/* The open list takes its colours from the options, and a transparent select gives it none: it
   would open white, the light text unreadable on it. ACARS does the same. */
.fd-sort select option { background: var(--surface-1); color: var(--text-primary); font-weight: 400; }

/* The applied filters and the count. */
.fd-applied {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin: 16px 0;
  font-size: 0.875rem;
}

.fd-summary strong { color: var(--text-primary); }

.fd-applied-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  border: none;
  border-radius: 999px;
  padding: 4px 8px 4px 12px;
  font: inherit;
  font-size: 0.8rem;
  background: var(--surface-3);
  color: var(--text-primary);
  cursor: pointer;
}

.fd-x { color: var(--text-muted); font-weight: 700; }

.fd-link {
  border: none;
  background: none;
  padding: 0 0 0 4px;
  font: inherit;
  color: var(--accent-bright);
  cursor: pointer;
}

.fd-link:hover { text-decoration: underline; }
.fd-unmeasured { margin-left: auto; font-size: 0.8rem; }

/* The cards. */
.fd-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; }

.fd-card {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 18px;
  border-radius: var(--radius-md);
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: inherit;
}

.fd-card-top { display: flex; align-items: center; gap: 10px; }
/* The card is a link to Flight Detail through its flight number, stretched over the card; the
   jumpseat remedy sits above it and stays its own button. */
.fd-card { position: relative; transition: border-color 0.15s ease; }
.fd-card:hover, .fd-card:focus-within { border-color: color-mix(in srgb, var(--accent-bright) 55%, var(--border)); }
.fd-card-link { color: var(--text-primary); text-decoration: none; }
.fd-card-link::after { content: ""; position: absolute; inset: 0; border-radius: var(--radius-md); }
.fd-card-link:focus-visible { outline: none; }
.fd-card-link:focus-visible::after { box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 45%, transparent); }
.fd-card .fd-foot-row .fd-btn { position: relative; z-index: 1; }
.fd-fn { font-weight: 700; font-size: 1rem; }
.fd-airline { font-size: 0.8rem; color: var(--text-muted); }
.fd-badges { margin-left: auto; display: flex; gap: 6px; }

.fd-badge {
  font-size: 0.75rem;
  font-weight: 600;
  padding: 2px 10px;
  border-radius: 999px;
  color: var(--text-secondary);
  background: var(--surface-3);
  border: 1px solid var(--border);
}

/* Each end takes at most 40% of the card and its city stays on one line, so a long municipality
   ("Paris (Roissy-en-France, Val-d'Oise)") never squeezes the route line or wraps the card. */
.fd-route { display: grid; grid-template-columns: fit-content(40%) minmax(40px, 1fr) fit-content(40%); align-items: center; gap: 12px; }
.fd-route .fd-end { min-width: 0; }
.fd-end-end { text-align: right; }
.fd-ap { font-family: var(--font-mono); font-weight: 700; font-size: 1.56rem; letter-spacing: 0.01em; line-height: 1.3; }
.fd-city { font-size: 0.84rem; color: var(--text-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* The dashed route line and its aircraft: vaBase.routeLine(), the one every route draws with. */
.fd-route .route-line { position: relative; height: 18px; min-width: 40px; }
.fd-route .route-line::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  border-top: 2px dashed var(--border-strong);
}
.fd-route .route-plane {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  padding: 0 4px;
  line-height: 0;
  color: var(--text-muted);
  background: var(--surface-2);
}
.fd-route .route-plane svg { transform: rotate(90deg); }
.fd-card-dim .fd-route .route-plane { background: color-mix(in srgb, var(--surface-2) 70%, var(--bg)); }

.fd-facts { display: flex; flex-wrap: wrap; gap: 8px; font-size: 0.875rem; color: var(--text-secondary); }
.fd-dot, .fd-est { color: var(--text-muted); }

.fd-card-foot {
  margin-top: auto;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
  font-size: 0.84rem;
}

.fd-foot-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.fd-st { display: inline-flex; align-items: center; gap: 6px; font-weight: 600; }
.fd-st .icon { width: 14px; height: 14px; }
.fd-st-ok { color: var(--success); }
.fd-st-warn { color: var(--warning); }
.fd-st-accent { color: var(--accent-bright); }
.fd-st-muted { color: var(--text-muted); }
.fd-cue { margin-left: auto; color: var(--accent-bright); font-size: 0.8rem; font-weight: 600; }
.fd-cue-plain { margin-left: auto; color: var(--text-muted); font-size: 0.8rem; }

.fd-booked {
  margin-left: auto;
  font-size: 0.75rem;
  font-weight: 600;
  padding: 2px 9px;
  border-radius: 999px;
  color: var(--success);
  background: color-mix(in srgb, var(--success) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--success) 40%, transparent);
}

.fd-why { margin: 0; font-size: 0.8rem; color: var(--text-secondary); }
/* A flight the pilot cannot fly from here stays visible and explained, plainly second. */
.fd-card-dim { background: color-mix(in srgb, var(--surface-2) 70%, var(--bg)); }
.fd-card-dim .fd-route, .fd-card-dim .fd-facts { opacity: 0.7; }

.fd-foot { display: flex; justify-content: center; align-items: center; gap: 14px; padding-top: 18px; font-size: 0.875rem; }
.fd-foot[hidden] { display: none; }
.fd-foot .fd-btn[hidden] { display: none; }

/* The empty states: each names what was asked for and offers the way out. */
.fd-empty {
  grid-column: 1 / -1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 28px 28px 26px;
  text-align: center;
  border-radius: var(--radius-md);
  border: 1px dashed var(--border-strong);
  background: color-mix(in srgb, var(--surface-1) 60%, var(--bg));
}

.fd-empty h3, .fd-empty h1 { margin: 0; font-size: 1.12rem; letter-spacing: -0.01em; }
.fd-empty p { margin: 0; max-width: 440px; font-size: 0.9rem; color: var(--text-secondary); }
.fd-empty-icon {
  width: 44px;
  height: 44px;
  margin-bottom: 4px;
  border-radius: var(--radius-md);
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--surface-3);
  color: var(--text-secondary);
}
.fd-empty-icon.warn { background: color-mix(in srgb, var(--warning) 14%, transparent); color: var(--warning); }
.fd-empty-icon .icon { width: 22px; height: 22px; }
.fd-empty-acts { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin-top: 10px; }

/* The search box's suggestions. */
.fd-suggest {
  position: absolute;
  left: 0;
  right: 0;
  top: calc(100% + 6px);
  z-index: 30;
  overflow: hidden;
  border-radius: var(--radius-md);
  border: 1px solid var(--border-strong);
  background: var(--surface-3);
  box-shadow: var(--shadow-2);
  padding-bottom: 6px;
}

.fd-suggest[hidden] { display: none; }
.fd-suggest-inline { top: calc(100% + 4px); }
.fd-grp { padding: 10px 14px 4px; font-size: 0.75rem; font-weight: 600; letter-spacing: 0.07em; text-transform: uppercase; color: var(--text-muted); }
.fd-grp-sep { height: 1px; margin-top: 6px; background: var(--border); }
.fd-result { display: flex; align-items: center; gap: 10px; padding: 9px 14px; font-size: 0.9rem; cursor: pointer; }
.fd-result:hover, .fd-result.on { background: color-mix(in srgb, var(--accent) 18%, transparent); }
.fd-result mark { background: transparent; color: var(--accent-bright); font-weight: 700; }
.fd-m { margin-left: auto; color: var(--text-muted); font-size: 0.8rem; white-space: nowrap; }

/* More filters: a popover under its button; a bottom sheet on a phone. */
.fd-more {
  position: absolute;
  right: 0;
  left: auto;
  top: calc(100% + 8px);
  z-index: 40;
  width: min(760px, calc(100vw - 48px));
  margin: 0;
  padding: 0;
  border-radius: var(--radius-lg);
  border: 1px solid var(--border-strong);
  background: var(--surface-3);
  color: var(--text-primary);
  box-shadow: var(--shadow-2);
}

.fd-sheet-head { display: flex; align-items: center; gap: 10px; padding: 16px 20px 0; }
.fd-sheet-title { font-weight: 700; }
.fd-close {
  margin-left: auto;
  border: none;
  background: none;
  color: var(--text-muted);
  font-size: 1.4rem;
  line-height: 1;
  cursor: pointer;
}

.fd-pop { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 14px 16px; padding: 16px 20px; }
.fd-field { min-width: 0; }
.fd-field.s2 { grid-column: span 2; }
.fd-field.s3 { grid-column: span 3; }
.fd-field.s6, .fd-switch-row.s6 { grid-column: span 6; }
.fd-field-label { display: block; margin-bottom: 6px; font-size: 0.8rem; font-weight: 600; color: var(--text-secondary); }

.fd-input {
  width: 100%;
  height: 42px;
  box-sizing: border-box;
  padding: 0 12px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-strong);
  background: var(--surface-1);
  color: var(--text-primary);
  font: inherit;
  font-size: 0.9rem;
}

.fd-input[aria-invalid="true"] { border-color: var(--danger); }
.fd-airport { position: relative; }
.fd-stack { display: flex; flex-direction: column; gap: 8px; }
.fd-chipset { display: flex; flex-wrap: wrap; gap: 6px; }
.fd-range { display: flex; align-items: center; gap: 8px; }

.fd-seg { display: inline-flex; border: 1px solid var(--border-strong); border-radius: var(--radius-sm); overflow: hidden; }
.fd-seg button {
  border: none;
  background: transparent;
  color: var(--text-secondary);
  font: inherit;
  font-size: 0.84rem;
  font-weight: 600;
  padding: 0 14px;
  height: 38px;
  cursor: pointer;
}
.fd-seg button + button { border-left: 1px solid var(--border-strong); }
.fd-seg button.on { background: var(--surface-1); color: var(--text-primary); }
/* In the filters popup a segmented choice fills its field, its buttons sharing the width and as
   tall as the fields beside it - three buttons at their own width are wider than a two-column
   field and run into the next one. */
.fd-pop .fd-seg { display: flex; width: 100%; }
.fd-pop .fd-seg button { flex: 1 1 auto; min-width: 0; height: 40px; padding: 0 8px; white-space: nowrap; }
/* Under 800px the popup is too narrow for three fields a row (a choice's buttons no longer fit
   their third): it takes the phone sheet's two-column grid, still as a popup. */
@media (max-width: 800px) {
  .fd-pop { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .fd-field.s2, .fd-field.s3 { grid-column: span 1; }
  .fd-field.s6, .fd-switch-row.s6, .fd-field.fd-full-narrow { grid-column: span 2; }
}

.fd-switch-row { display: flex; align-items: center; gap: 10px; font-size: 0.9rem; }
.fd-switch {
  position: relative;
  width: 40px;
  height: 22px;
  flex-shrink: 0;
  padding: 0;
  border: none;
  border-radius: 999px;
  background: var(--border-strong);
  cursor: pointer;
}
.fd-switch::after {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--text-primary);
  transition: left 0.15s ease;
}
.fd-switch.on { background: var(--accent); }
.fd-switch.on::after { left: 21px; }

.fd-pop-foot { display: flex; align-items: center; gap: 10px; padding: 14px 20px 18px; border-top: 1px solid var(--border); }
.fd-pop-hint { font-size: 0.84rem; }
.fd-pop-foot .btn-primary { margin-left: auto; }

@media (max-width: 1000px) {
  .fd-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* The phone: search, location and ONE scrolling chip row stay on screen; the rest lives in the
   Filters sheet, whose button counts what is applied. */
@media (max-width: 640px) {
  .fd-band { gap: 12px; padding: 9px 12px; border-radius: 14px; }
  .fd-band-icon { width: 32px; height: 32px; border-radius: 9px; }
  .fd-band-icon .icon { width: 17px; height: 17px; }
  .fd-band-k { display: none; }
  .fd-band-line { font-size: 1rem; }
  .fd-band-note { display: block; font-size: 0.8rem; }
  .fd-toolbar { grid-template-columns: minmax(0, 1fr) auto; gap: 12px; }
  .fd-search input { height: 42px; }
  .fd-search .fd-search-icon { top: 12px; }
  .fd-more-wrap > .fd-btn { height: 40px; }
  .fd-chips { flex-wrap: nowrap; overflow-x: auto; margin: 0 -24px; padding: 0 24px 2px; scrollbar-width: none; }
  .fd-chips::-webkit-scrollbar { display: none; }
  .fd-chip-long, .fd-vr, .fd-label, .fd-wide { display: none; }
  .fd-chip-short, .fd-narrow { display: inline; }
  .fd-band-note.fd-narrow { display: block; }
  .fd-grid { grid-template-columns: minmax(0, 1fr); gap: 12px; }
  .fd-unmeasured { margin-left: 0; flex-basis: 100%; }
  .fd-more {
    position: fixed;
    inset: auto 0 0 0;
    top: auto;
    width: 100%;
    max-width: 100%;
    max-height: 88vh;
    overflow: auto;
    border-radius: 18px 18px 0 0;
    border-width: 1px 0 0;
    background: var(--surface-1);
  }
  .fd-more::backdrop { background: rgba(5, 5, 8, 0.66); }
  .fd-pop { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .fd-field.s2, .fd-field.s3 { grid-column: span 1; }
  .fd-field.s6, .fd-switch-row.s6 { grid-column: span 2; }
  .fd-field.fd-full-narrow { grid-column: span 2; }
  .fd-pop-hint { display: none; }
  .fd-pop-foot { position: sticky; bottom: 0; background: var(--surface-1); }
  .fd-pop-foot .btn-primary { flex: 1; justify-content: center; }
}

/* A label for assistive technology only (the search box names itself without a visible label). */
.visually-hidden {
  position: absolute !important;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.fd-input.input-uppercase::placeholder { text-transform: none; }

/* The band's text column may shrink (a long airport name wraps, never pushes the Jumpseat button
   off), and a suggestion's label takes the row's spare width. */
.fd-band-text { min-width: 0; }
.fd-result-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---- Flight Detail ---- */

.fdd-page { padding-top: 24px; padding-bottom: 64px; display: flex; flex-direction: column; gap: 18px; }
.fdd-back { color: var(--accent-bright); font-size: 0.9rem; font-weight: 600; align-self: flex-start; }
#fdd-body { display: flex; flex-direction: column; gap: 18px; }

.fdd-hero {
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding: 28px 32px;
  border-radius: var(--radius-lg);
  border: 1px solid var(--border);
  background: radial-gradient(900px 300px at 15% 0%, color-mix(in srgb, var(--accent) 22%, transparent), transparent 70%), var(--surface-1);
}

.fdd-top { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.fdd-fn { font-weight: 700; font-size: 1.15rem; }

.fdd-route { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 28px; }
.fdd-end-right { text-align: right; }
.fdd-ap { font-family: var(--font-mono); font-weight: 700; font-size: clamp(2.4rem, 5vw, 3.4rem); letter-spacing: 0.01em; line-height: 1.05; }
.fdd-city { font-size: 1.18rem; }
.fdd-route .route-line { position: relative; height: 26px; }
.fdd-route .route-line::before { content: ""; position: absolute; top: 50%; left: 0; right: 0; border-top: 2px dashed var(--border-strong); }
.fdd-route .route-plane {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  padding: 0 6px;
  line-height: 0;
  color: var(--accent-bright);
  background: var(--surface-1);
}
.fdd-route .route-plane svg { width: 22px; height: 22px; transform: rotate(90deg); }

.fdd-hub {
  display: inline-block;
  font-size: 0.75rem;
  font-weight: 600;
  padding: 2px 9px;
  border-radius: 999px;
  color: var(--accent-bright);
  background: color-mix(in srgb, var(--accent) 20%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent-bright) 40%, transparent);
  vertical-align: middle;
}

.fdd-kfacts { display: flex; gap: 34px; flex-wrap: wrap; }
.fdd-kf { min-width: 0; }
.fdd-apcard { min-width: 0; }
.fdd-kf-k { font-size: 0.75rem; font-weight: 600; letter-spacing: 0.07em; text-transform: uppercase; color: var(--text-muted); }
.fdd-kf-v { font-size: 1.12rem; font-weight: 600; }
.fdd-kf-name { color: var(--text-secondary); font-weight: 400; }
.fdd-kf-s { max-width: 260px; font-size: 0.78rem; color: var(--text-muted); }

/* The action strip: the words on the left, at most one primary action on the right. */
.fdd-action { display: flex; align-items: center; gap: 16px; padding-top: 18px; border-top: 1px solid var(--border); }
.fdd-words { min-width: 0; }
.fdd-words .fd-st { font-size: 1rem; }
.fdd-words .fd-st .icon { width: 16px; height: 16px; }
.fdd-sub { margin-top: 2px; color: var(--text-secondary); font-size: 0.9rem; }
.fdd-note { margin-top: 2px; color: var(--text-muted); font-size: 0.84rem; }
.fdd-acts { margin-left: auto; display: flex; flex-wrap: wrap; gap: 10px; align-items: center; justify-content: flex-end; flex-shrink: 0; }
.fdd-cta { padding: 12px 22px; font-size: 1rem; }
.fdd-state-reposition, .fdd-state-blocked, .fdd-state-noType { align-items: flex-start; }
.fdd-sticky { display: none; }

.fdd-map-wrap { position: relative; }
.fdd-map-wrap[hidden] { display: none; }
.fdd-map { height: 380px; border-radius: var(--radius-lg); border: 1px solid var(--border); overflow: hidden; background: var(--surface-1); }
.fdd-map-note { position: absolute; left: 16px; bottom: 12px; font-size: 0.8rem; pointer-events: none; }
.route-map-marker { display: flex; flex-direction: column; align-items: center; gap: 4px; cursor: pointer; }
.fdd-mk-dot { width: 12px; height: 12px; border-radius: 50%; background: var(--accent-bright); border: 2px solid #ffffff; }
.route-map-marker[data-kind="alternate"] .fdd-mk-dot { width: 9px; height: 9px; background: var(--bg); border-color: var(--text-muted); }
.fdd-mk-lbl {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 0.8rem;
  padding: 1px 7px;
  border-radius: 6px;
  border: 1px solid var(--border-strong);
  background: color-mix(in srgb, var(--bg) 85%, transparent);
  color: var(--text-primary);
}
.fdd-pop { font-size: 0.84rem; color: #1b1c21; }
.fdd-pop .fd-muted { color: #55585f; }

/* Sections: open on a wide screen, folds on a phone. */
.fdd-section { border-radius: var(--radius-md); background: var(--surface-2); border: 1px solid var(--border); }
.fdd-section > summary {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 18px 22px 0;
  list-style: none;
  cursor: default;
}
.fdd-section > summary::-webkit-details-marker { display: none; }
.fdd-section-title { font-size: 0.8rem; font-weight: 600; letter-spacing: 0.07em; text-transform: uppercase; color: var(--text-muted); }
.fdd-section-note { display: none; font-size: 0.84rem; }
.fdd-section-body { padding: 14px 22px 20px; }
.fdd-dl { display: grid; grid-template-columns: 150px minmax(0, 1fr); gap: 7px 14px; margin: 0; font-size: 0.95rem; }
.fdd-dl dt { color: var(--text-muted); }
.fdd-dl dd { margin: 0; overflow-wrap: anywhere; }
.fdd-tag { display: inline-block; margin: 0 6px 4px 0; padding: 2px 10px; border-radius: 999px; font-size: 0.8rem; color: var(--text-secondary); background: var(--surface-3); border: 1px solid var(--border); }

.fdd-airports { background: transparent; border: none; }
.fdd-airports > summary { padding: 0; }
.fdd-airports .fdd-section-title { display: none; }
.fdd-airports .fdd-section-body { padding: 0; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; }
.fdd-panel { border-radius: var(--radius-md); background: var(--surface-2); border: 1px solid var(--border); padding: 20px 22px; }
.fdd-panel h2 { margin: 0 0 12px; font-size: 0.8rem; font-weight: 600; letter-spacing: 0.07em; text-transform: uppercase; color: var(--text-muted); }
.fdd-ap-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.fdd-apcode { font-family: var(--font-mono); font-weight: 700; font-size: 1.5rem; }
.fdd-facts { display: flex; flex-wrap: wrap; gap: 22px; margin-top: 10px; font-size: 0.95rem; }
.fdd-facts span { display: block; font-size: 0.75rem; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-muted); }

@media (max-width: 900px) {
  .fdd-airports .fdd-section-body { grid-template-columns: minmax(0, 1fr); }
}

/* The phone: the route leads, the action bar stays on screen, sections fold. */
@media (max-width: 640px) {
  .fdd-page { padding-top: 16px; padding-bottom: 150px; }
  .fdd-hero { padding: 16px; gap: 14px; border-radius: 16px; }
  .fdd-route { grid-template-columns: minmax(0, 1fr); gap: 6px; padding-left: 22px; position: relative; }
  .fdd-route::before { content: ""; position: absolute; left: 6px; top: 14px; bottom: 14px; border-left: 2px dashed var(--border-strong); }
  .fdd-route .route-line { display: none; }
  .fdd-end-right { text-align: left; }
  .fdd-ap { font-size: 2.4rem; }
  .fdd-city { font-size: 1rem; }
  .fdd-kfacts { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
  .fdd-kf-v { font-size: 1rem; }
  .fdd-hero > .fdd-action { display: none; }
  .fdd-map { height: 200px; border-radius: 14px; }
  .fdd-sticky {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 9px;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 40;
    padding: 11px 16px 16px;
    background: color-mix(in srgb, var(--surface-1) 97%, transparent);
    border-top: 1px solid var(--border);
    box-shadow: 0 -12px 30px rgba(0, 0, 0, 0.5);
  }
  .fdd-sticky .fdd-acts { margin-left: 0; justify-content: stretch; }
  .fdd-sticky .fdd-acts > * { flex: 1; justify-content: center; }
  .fdd-section > summary { cursor: pointer; padding: 14px 16px; }
  .fdd-section[open] > summary { padding-bottom: 0; }
  .fdd-section-note { display: inline; }
  .fdd-section-body { padding: 12px 16px 16px; }
  .fdd-airports { background: var(--surface-2); border: 1px solid var(--border); }
  .fdd-airports > summary { padding: 14px 16px; }
  .fdd-airports .fdd-section-title { display: inline; }
  .fdd-airports .fdd-section-body { padding: 12px 16px 16px; }
  .fdd-dl { grid-template-columns: minmax(0, 1fr); gap: 2px; }
  .fdd-dl dd { margin-bottom: 8px; }
}

/* ---- Flight Detail's own sections: weather, activity, recently flown, history and related
   panels. Each loads on its own and shows the skeleton until then. */
.fdd-row { display: grid; gap: 18px; align-items: start; }
.fdd-row-info { grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr); }
.fdd-row-activity { grid-template-columns: minmax(0, 1fr) minmax(0, 1.55fr); }
.fdd-row-related { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.fdd-row-related[hidden] { display: none; }
.fdd-sec { min-width: 0; }
.fdd-sec-head { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
.fdd-sec-head h2 { margin: 0; }
.fdd-linkbtn {
  margin-left: auto;
  padding: 0;
  border: none;
  background: none;
  color: var(--accent-bright);
  font: inherit;
  font-size: 0.84rem;
  font-weight: 600;
  cursor: pointer;
}
.fdd-linkbtn:hover { text-decoration: underline; }
.fdd-sec-fail, .fdd-sec-text { margin: 0; color: var(--text-secondary); font-size: 0.95rem; }
.fdd-sec-line { margin-top: 14px; font-size: 0.86rem; }
.fdd-sec-note { margin-top: 10px; font-size: 0.8rem; }
.fdd-skel { display: flex; flex-direction: column; gap: 10px; }
.fdd-skel-bar {
  height: 14px;
  border-radius: 6px;
  background: linear-gradient(90deg, var(--surface-3), var(--border), var(--surface-3));
  background-size: 200% 100%;
  animation: fdd-skel 1.4s ease-in-out infinite;
}
.fdd-skel-bar:nth-child(1) { width: 38%; }
.fdd-skel-bar:nth-child(2) { width: 92%; }
.fdd-skel-bar:nth-child(3) { width: 74%; }
@keyframes fdd-skel { 0% { background-position: 100% 0; } 100% { background-position: -100% 0; } }
@media (prefers-reduced-motion: reduce) { .fdd-skel-bar { animation: none; } }

/* Weather now: three stations across; the category pill in the --wx-* tokens, never colour alone. */
.fdd-wx-tabs { display: none; }
.fdd-wx-grid { display: grid; gap: 22px; grid-template-columns: repeat(3, minmax(0, 1fr)); }
.fdd-wx-grid.fdd-wx-n2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.fdd-wx { min-width: 0; }
.fdd-wx-top { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.fdd-wx-role { font-size: 0.82rem; }
.fdd-wx-name { display: none; color: var(--text-secondary); font-size: 0.85rem; }
.fdd-wx-pill {
  margin-left: auto;
  padding: 2px 9px;
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: #0b0c0e;
  background: var(--text-muted);
}
.fdd-wx-pill[data-cat="vfr"] { background: var(--wx-vfr); }
.fdd-wx-pill[data-cat="mvfr"] { background: var(--wx-mvfr); }
.fdd-wx-pill[data-cat="ifr"] { background: var(--wx-ifr); }
.fdd-wx-pill[data-cat="lifr"] { background: var(--wx-lifr); }
.fdd-wx-none { margin-top: 12px; color: var(--text-secondary); font-size: 0.92rem; }
.fdd-wx-age { margin-top: 8px; font-size: 0.8rem; color: var(--text-muted); }
.fdd-wx-age.is-stale { color: var(--warning); }
.fdd-wx-raw { margin-top: 10px; display: flex; flex-direction: column; gap: 6px; }
.fdd-wx-raw pre {
  margin: 0;
  padding: 8px 10px;
  border-radius: 8px;
  background: var(--surface-1);
  border: 1px solid var(--border);
  font-family: var(--font-mono);
  font-size: 0.8rem;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* Route activity. */
.fdd-stats { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px 10px; }
.fdd-stat-v { font-size: 1.75rem; font-weight: 700; letter-spacing: -0.01em; font-variant-numeric: tabular-nums; }
.fdd-stat-k { font-size: 0.82rem; color: var(--text-muted); }

/* Recently flown: a table on a wide screen, one line per flight on a phone. */
.fdd-rf-all { display: none; }
.fdd-rf-table { width: 100%; border-collapse: collapse; font-size: 0.92rem; }
.fdd-rf-table th {
  text-align: left;
  padding: 0 8px 8px 0;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.fdd-rf-table td { padding: 9px 8px 9px 0; border-top: 1px solid var(--border); font-variant-numeric: tabular-nums; }
.fdd-rf-table .fdd-rf-link { text-align: right; padding-right: 0; }
.fdd-rf-table a, .fdd-rf a, .fdd-hist-link { color: var(--accent-bright); font-weight: 600; }
.fdd-rf-list { display: none; }
.fdd-rf { display: flex; align-items: center; gap: 10px; padding: 8px 0; border-top: 1px solid var(--border); font-size: 0.92rem; line-height: 1.35; }
.fdd-rf a { margin-left: auto; font-size: 0.85rem; white-space: nowrap; }
.fdd-rf-m { font-size: 0.8rem; color: var(--text-muted); }

/* Your history. */
.fdd-hist-title { font-size: 1.06rem; font-weight: 600; }
.fdd-hist-dl { margin-top: 12px; grid-template-columns: 140px minmax(0, 1fr); }
.fdd-hist-link { display: inline-block; margin-top: 12px; font-size: 0.9rem; }
.fdd-sec-history .fdd-sec-text { margin-top: 4px; }

/* Return / onward / similar. */
.fdd-rel { min-width: 0; }
.fdd-minis { display: flex; flex-direction: column; gap: 8px; }
.fdd-mini {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  border-radius: 10px;
  background: var(--surface-1);
  border: 1px solid var(--border);
  color: inherit;
  font-size: 0.92rem;
  text-decoration: none;
}
.fdd-mini:hover { border-color: var(--border-strong); }
.fdd-mini-fn { font-weight: 700; }
.fdd-mini > span { white-space: nowrap; }
.fdd-mini > .fd-muted { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.fdd-mini-m { margin-left: auto; color: var(--text-muted); font-size: 0.85rem; white-space: nowrap; }

@media (max-width: 900px) {
  .fdd-row-info, .fdd-row-activity, .fdd-row-related { grid-template-columns: minmax(0, 1fr); }
}

/* The phone: the rows open up so each section takes its phone order - the route, the map, your
   history, the weather (one station at a time), route activity, recently flown, related flights,
   then the folds. */
@media (max-width: 640px) {
  .fdd-row { display: contents; }
  .fdd-row.fdd-row-related { display: grid; }
  #fdd-body > .fdd-hero { order: 1; }
  #fdd-body > .fdd-map-wrap { order: 2; }
  .fdd-sec-history { order: 3; }
  .fdd-sec-weather { order: 4; }
  .fdd-sec-activity { order: 5; }
  .fdd-sec-recent { order: 6; }
  .fdd-sec-related { order: 7; }
  .fdd-row-info > .fdd-section { order: 8; }
  #fdd-body > .fdd-airports { order: 9; }
  #fdd-body > .fdd-sticky { order: 10; }
  .fdd-panel { padding: 16px; }
  .fdd-wx-tabs {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    margin-bottom: 12px;
    border: 1px solid var(--border-strong);
    border-radius: 8px;
    overflow: hidden;
  }
  .fdd-wx-tabs button {
    padding: 8px 0;
    border: none;
    background: transparent;
    color: var(--text-secondary);
    font: inherit;
    font-size: 0.85rem;
    font-weight: 600;
    cursor: pointer;
  }
  .fdd-wx-tabs button.is-on { background: var(--surface-3); color: var(--text-primary); }
  .fdd-wx-grid, .fdd-wx-grid.fdd-wx-n2 { grid-template-columns: minmax(0, 1fr); }
  .fdd-wx:not(.is-selected) { display: none; }
  .fdd-wx-role { display: none; }
  .fdd-wx-name { display: inline; }
  .fdd-sec-activity .fdd-sec-line { display: none; }
  .fdd-stat-v { font-size: 1.5rem; }
  .fdd-rf-table { display: none; }
  .fdd-rf-list { display: block; }
  .fdd-rf-all { display: inline; }
  .fdd-rf.is-folded { display: none; }
  .fdd-sec-recent .fdd-sec-note { display: none; }
  .fdd-hist-dl { grid-template-columns: minmax(0, 1fr); }
}

/* ---- the public network and a public route. The list is the finder's card and toolbar; the
   route page is Flight Detail's own panels (flight-detail-view.js). */
.ps-grid { margin-top: 16px; }
.ps-flown { color: var(--text-secondary); font-size: 0.86rem; font-weight: 600; }
.ps-new { color: var(--accent-bright); font-size: 0.86rem; font-weight: 600; }
#rt-body { display: flex; flex-direction: column; gap: 18px; }
.rt-invite-title { font-size: 1.06rem; font-weight: 600; }
.rt-info-cols { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 40px; }
.rt-info-cols .fdd-dl { grid-template-columns: 130px minmax(0, 1fr); }
.rt-airports { display: grid; grid-template-columns: 1fr 1fr 0.8fr; gap: 18px; }
.rt-related { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 2.2fr); gap: 18px; align-items: start; }
.rt-related[hidden] { display: none; }
.rt-related.rt-related-one { grid-template-columns: minmax(0, 1fr); }
.rt-minis { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
.rt-minis .fdd-mini { min-width: 0; }
.rt-minis .fdd-mini-m { white-space: normal; text-align: right; }
.rt-row-single { grid-template-columns: minmax(0, 1fr); }
.rt-rf-table .mono { font-family: var(--font-mono); }

@media (max-width: 900px) {
  .rt-airports, .rt-related, .rt-minis, .rt-info-cols { grid-template-columns: minmax(0, 1fr); }
}

/* ---- Suggest me a flight (in the jumpseat dialog's frame) ---- */
.fd-sg-btn .icon { width: 16px; height: 16px; }
.fd-sg-m { display: none; }
.fd-head .fd-sg-head { margin-left: auto; align-self: flex-end; }
.fd-band-actions .fd-btn.btn-primary { background: var(--accent); }

.sg-dialog {
  width: min(640px, calc(100vw - 32px));
  max-height: calc(100vh - 48px);
  padding: 0;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg);
  background: var(--surface-3);
  color: var(--text-primary);
  box-shadow: var(--shadow-2);
}
.sg-dialog::backdrop { background: rgba(5, 5, 7, 0.62); }
.sg-panel { display: flex; flex-direction: column; gap: 16px; padding: 24px 26px; }
.sg-panel h2 { margin: 0; font-size: 1.31rem; letter-spacing: -0.01em; }
.sg-head { display: flex; align-items: center; gap: 12px; }
.sg-x {
  margin-left: auto;
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text-muted);
  font-size: 1.4rem;
  line-height: 1;
  cursor: pointer;
}
.sg-x:hover { color: var(--text-primary); background: var(--surface-2); }
.sg-here {
  display: flex;
  align-items: center;
  gap: 10px;
  height: 44px;
  padding: 0 14px;
  border-radius: var(--radius-sm);
  background: var(--surface-1);
  border: 1px solid var(--border);
  font-size: 0.94rem;
}
.sg-here .icon { width: 16px; height: 16px; color: var(--accent-bright); flex-shrink: 0; }
.sg-here-note { margin-left: auto; color: var(--text-muted); font-size: 0.84rem; }
.sg-q { font-size: 0.94rem; font-weight: 600; margin-bottom: 8px; }
.sg-chips { display: flex; gap: 8px; flex-wrap: wrap; }
.sg-optional { display: flex; flex-direction: column; gap: 14px; padding-top: 16px; border-top: 1px solid var(--border); }
.sg-opt-row { display: grid; grid-template-columns: 200px minmax(0, 1fr); gap: 20px; align-items: end; }
.sg-field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.sg-field-label { font-size: 0.81rem; font-weight: 600; color: var(--text-secondary); }
.sg-optional-word { color: var(--text-muted); font-weight: 400; }
.sg-field .fd-input { height: 42px; }
.sg-carry { min-height: 42px; align-items: center; }
.sg-switch-row { display: flex; align-items: center; gap: 12px; font-size: 0.94rem; }
.sg-actions { display: flex; align-items: center; gap: 10px; padding-top: 16px; border-top: 1px solid var(--border); flex-wrap: wrap; }
.sg-push { margin-left: auto; }
.sg-note { color: var(--text-muted); font-size: 0.84rem; }
.sg-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--accent-bright);
}
.sg-eyebrow.warn { color: var(--warning); text-transform: none; letter-spacing: 0; font-size: 0.875rem; }
.sg-eyebrow .icon { width: 15px; height: 15px; }
.sg-top { display: flex; align-items: center; gap: 12px; margin-top: -8px; }
.sg-top .fd-badge { margin-left: auto; }
.sg-fn { font-size: 1.25rem; font-weight: 700; }
.sg-route { display: grid; grid-template-columns: fit-content(40%) minmax(40px, 1fr) fit-content(40%); align-items: center; gap: 20px; }
.sg-route .route-line { position: relative; height: 22px; }
.sg-route .route-line::before { content: ""; position: absolute; top: 50%; left: 0; right: 0; border-top: 2px dashed var(--border-strong); }
.sg-route .route-plane { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); padding: 0 6px; line-height: 0; color: var(--accent-bright); background: var(--surface-3); }
.sg-route .route-plane svg { width: 20px; height: 20px; transform: rotate(90deg); }
.sg-end { min-width: 0; }
.sg-end-right { text-align: right; }
.sg-ap { font-family: var(--font-mono); font-weight: 700; font-size: 2.5rem; letter-spacing: 0.01em; line-height: 1.1; }
.sg-city { font-size: 0.97rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sg-facts { display: flex; gap: 9px; flex-wrap: wrap; font-size: 0.94rem; color: var(--text-secondary); }
.sg-map {
  height: 200px;
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
  background: linear-gradient(180deg, #10151c, #0d1117);
  overflow: hidden;
}
.sg-map svg { display: block; width: 100%; height: 100%; }
.sg-map-arc { fill: none; stroke: var(--accent-bright); stroke-width: 3; stroke-linecap: round; }
.sg-map-dot { fill: var(--accent-bright); stroke: #ffffff; stroke-width: 2; }
.sg-map-lbl { fill: #eceded; font-family: var(--font-mono); font-weight: 700; font-size: 12.5px; }
.sg-why-k { font-size: 0.75rem; font-weight: 600; letter-spacing: 0.07em; text-transform: uppercase; color: var(--text-muted); margin-bottom: 3px; }
.sg-why { font-size: 0.97rem; }
.sg-relaxed {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 4px 12px;
  border-radius: 999px;
  font-size: 0.81rem;
  font-weight: 600;
  color: color-mix(in srgb, var(--warning) 45%, #ffffff);
  background: color-mix(in srgb, var(--warning) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--warning) 45%, transparent);
}
.sg-wx-row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; min-height: 0; }
.sg-wx-row:empty { display: none; }
.sg-wx {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 4px 6px 4px 11px;
  border-radius: 999px;
  font-size: 0.81rem;
  background: var(--surface-1);
  border: 1px solid var(--border);
}
.sg-wx .fdd-wx-pill { margin-left: 0; }
.sg-panel .fd-st { font-size: 0.9rem; font-weight: 600; }
.sg-panel .fd-st .icon { width: 15px; height: 15px; }
.sg-msg { margin: 0; }
.sg-nothing { position: relative; display: flex; flex-direction: column; align-items: center; text-align: center; gap: 8px; padding: 6px 2px 0; }
/* The corner the other states' cross sits in: the panel's own padding, on a phone too. */
.sg-none-x { position: absolute; top: 0; right: 0; }
.sg-nothing h2 { font-size: 1.19rem; }
.sg-nothing p { margin: 0; max-width: 420px; font-size: 0.94rem; color: var(--text-secondary); }
.sg-none-icon {
  width: 44px;
  height: 44px;
  margin-bottom: 4px;
  border-radius: var(--radius-md);
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--surface-1);
  color: var(--text-secondary);
}
.sg-none-icon.warn { background: color-mix(in srgb, var(--warning) 14%, transparent); color: var(--warning); }
.sg-none-icon .icon { width: 22px; height: 22px; }
.sg-none-acts { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; margin-top: 12px; }
.sg-result, .sg-nothing, .sg-blocked { max-width: 100%; }
.sg-panel.sg-result { gap: 14px; }

/* The phone: Suggest has its own row beside Filters; the dialog is a full sheet. */
@media (max-width: 640px) {
  .fd-head .fd-sg-head, .fd-band-actions .fd-sg-band { display: none; }
  .fd-sg-m { display: inline-flex; grid-area: suggest; justify-content: center; }

  .fd-toolbar { grid-template-areas: "search search" "chips chips" "suggest more" "sort sort"; }
  .sg-dialog { width: 100vw; max-width: 100vw; height: 100dvh; max-height: 100dvh; margin: 0; border-radius: 0; border: none; }
  .sg-panel { padding: 18px 16px 22px; }
  .sg-opt-row { grid-template-columns: minmax(0, 1fr); gap: 14px; }
  .sg-ap { font-size: 2rem; }
  .sg-actions .btn { flex: 1; justify-content: center; }
  .sg-push { margin-left: 0; }
}

/* ---- the network map (network-map-view.js draws it) ----
   The List | Map toggle in the heading, the map in place of the cards, the selected airport's panel
   on the map's right - a bottom sheet on a phone. The map's own colours are the tokens below, read by
   the view for its native layers, so a re-brand re-colours the lines with the rest of the page. */
.fd-view { margin-left: auto; align-self: flex-end; flex-shrink: 0; }
.fd-sg-head:not([hidden]) ~ .fd-view { margin-left: 0; }
.fd-view.fd-seg button { display: inline-flex; align-items: center; gap: 7px; padding: 0 16px; font-size: 0.875rem; }
.fd-view.fd-seg button .icon { width: 15px; height: 15px; }
.fd-page.fd-mapview .fd-sort,
.fd-page.fd-mapview #flights-list,
.fd-page.fd-mapview #schedules-list,
.fd-page.fd-mapview .fd-foot { display: none; }
@media (min-width: 641px) {
  .fd-page.fd-mapview .fd-toolbar { grid-template-areas: "search search more" "chips chips chips"; }
  /* The public map: the search, the length chips and More filters on one row. */
  .ps-page.fd-mapview .fd-toolbar { grid-template-columns: minmax(0, 1fr) auto auto; grid-template-areas: "search chips more"; }
  .ps-page.fd-mapview .fd-label { display: none; }
}
.fd-map-note { margin: 0 0 12px; font-size: 0.875rem; color: var(--text-secondary); }
.fd-map-note[hidden] { display: none; }

.nm-map {
  --nm-me: var(--accent-bright);
  --nm-sel: color-mix(in srgb, var(--accent) 30%, #ffffff);
  --nm-other: #4a4c55;
  --nm-dot: #eceded;
  --nm-hub: var(--accent-bright);
  --nm-ring: color-mix(in srgb, var(--accent-bright) 55%, transparent);
  --nm-edge: #0d1117;
  --nm-label: #d5d7dc;
  position: relative;
  height: 560px;
  overflow: hidden;
  border-radius: var(--radius-lg);
  border: 1px solid var(--border);
  background: linear-gradient(180deg, #10151c, #0d1117);
}
.nm-map[hidden] { display: none; }
/* MapLibre marks its container .maplibregl-map { position: relative } and loads after this sheet. */
.nm-map > .nm-canvas { position: absolute; inset: 0; }
.nm-code { font-family: var(--font-mono); font-weight: 700; }

.nm-chips { position: absolute; left: 16px; top: 16px; display: flex; gap: 8px; z-index: 2; }
.nm-chips[hidden] { display: none; }
.nm-chip {
  display: inline-flex; align-items: center; gap: 7px;
  border: 1px solid var(--border-strong); border-radius: 999px; padding: 7px 14px;
  background: rgba(20, 21, 25, 0.94); color: var(--text-secondary);
  font: inherit; font-size: 0.875rem; font-weight: 600; white-space: nowrap; cursor: pointer;
}
.nm-chip:hover { color: var(--text-primary); }
.nm-chip.on {
  color: #ffffff;
  border-color: color-mix(in srgb, var(--accent-bright) 60%, transparent);
  background: color-mix(in srgb, var(--accent) 60%, #0c0d0f);
}

.nm-zoom {
  position: absolute; left: 16px; top: 64px; z-index: 2;
  display: flex; flex-direction: column;
  background: rgba(20, 21, 25, 0.94); border: 1px solid var(--border-strong); border-radius: 10px; overflow: hidden;
}
.nm-zoom-top { top: 16px; }
.nm-zoom-btn {
  width: 34px; height: 34px; display: flex; align-items: center; justify-content: center;
  border: none; background: transparent; color: var(--text-primary); font: inherit; font-size: 18px; cursor: pointer;
}
.nm-zoom-btn + .nm-zoom-btn { border-top: 1px solid var(--border-strong); }
.nm-zoom-btn:hover { background: var(--surface-3); }

.nm-legend {
  position: absolute; left: 16px; bottom: 16px; z-index: 2;
  display: flex; gap: 18px; align-items: center; padding: 9px 14px;
  font-size: 0.78rem; color: var(--text-secondary);
  background: rgba(20, 21, 25, 0.94); border: 1px solid var(--border); border-radius: 10px;
}
.nm-lg { display: inline-flex; align-items: center; gap: 7px; white-space: nowrap; }
.nm-lg-hub { width: 10px; height: 10px; border-radius: 50%; background: var(--nm-hub); border: 2px solid #ffffff; box-shadow: 0 0 0 3px var(--nm-ring); }
.nm-lg-airport { width: 8px; height: 8px; border-radius: 50%; background: var(--nm-dot); }
.nm-lg-me, .nm-lg-base { width: 22px; height: 0; border-top: 3px solid var(--nm-me); border-radius: 2px; }
.nm-lg-base { opacity: 0.6; border-top-width: 2px; }
.nm-lg-other { width: 22px; height: 0; border-top: 2px solid var(--nm-other); }
.nm-legend-btn { display: none; }

.nm-attr { position: absolute; right: 16px; bottom: 14px; z-index: 1; font-size: 11px; color: var(--text-muted); }
.nm-attr a { color: inherit; }
/* The credit starts as a small (i) and opens to its two sources. */
.nm-attr { display: flex; align-items: center; gap: 6px; }
.nm-attr-links[hidden] { display: none; }
.nm-attr-toggle {
  width: 18px; height: 18px; padding: 0; border-radius: 50%;
  border: 1px solid currentColor; background: transparent; color: inherit;
  font: italic 600 11px/1 Georgia, "Times New Roman", serif; cursor: pointer; opacity: 0.55;
}
.nm-attr-toggle:hover, .nm-attr-toggle[aria-expanded="true"] { opacity: 0.9; }
.nm-attr-toggle:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 2px; opacity: 1; }
.nm-has-side .nm-attr { right: 372px; }

.nm-tag {
  display: inline-flex; align-items: center; gap: 6px; white-space: nowrap;
  font-size: 0.78rem; font-weight: 600; border-radius: 8px; padding: 3px 9px;
  background: rgba(12, 13, 15, 0.9); border: 1px solid color-mix(in srgb, var(--accent-bright) 60%, transparent); color: #eceded;
  pointer-events: none;
}
.nm-tag svg { color: var(--nm-sel); }
.nm-tag-sel { border-color: #ffffff; }

.nm-side {
  position: absolute; top: 16px; right: 16px; bottom: 16px; width: 340px; z-index: 3;
  box-sizing: border-box; display: flex; flex-direction: column; gap: 12px; padding: 18px;
  background: rgba(20, 21, 25, 0.97); border: 1px solid var(--border-strong); border-radius: 14px;
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.5); color: var(--text-primary);
}
.nm-side[hidden] { display: none; }
.nm-grab { display: none; }
.nm-side-head { display: flex; align-items: flex-start; gap: 10px; }
.nm-side-words { min-width: 0; }
.nm-side-k { font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.07em; color: var(--text-muted); font-weight: 600; }
.nm-side-title { font-size: 1.25rem; font-weight: 700; line-height: 1.3; }
.nm-side-sub, .nm-muted { color: var(--text-muted); font-size: 0.84rem; }
.nm-side-badges { display: flex; align-items: center; gap: 8px; margin-top: 4px; }
.nm-side-badges .nm-muted { color: var(--text-secondary); }
.nm-hub-badge {
  font-size: 0.75rem; font-weight: 600; padding: 2px 9px; border-radius: 999px;
  color: var(--nm-sel); background: color-mix(in srgb, var(--accent) 20%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent-bright) 40%, transparent);
}
.nm-x {
  margin-left: auto; border: none; background: transparent; color: var(--text-muted);
  font: inherit; font-size: 22px; line-height: 1; cursor: pointer; padding: 0 2px;
}
.nm-x:hover { color: var(--text-primary); }
.nm-side-body { display: flex; flex-direction: column; gap: 12px; overflow-y: auto; min-height: 0; flex: 1 1 auto; }
.nm-side-note { margin: auto 0 0; font-size: 0.78rem; color: var(--text-muted); }
.nm-about { margin-top: auto; font-size: 0.84rem; font-weight: 600; }

.nm-dirs { display: flex; flex-direction: column; gap: 10px; }
.nm-dir {
  display: flex; flex-direction: column; gap: 8px; padding: 12px 14px;
  border: 1px solid var(--border); border-radius: 12px; background: var(--surface-2);
}
.nm-dir-on { border-color: color-mix(in srgb, var(--accent-bright) 60%, transparent); background: color-mix(in srgb, var(--accent) 10%, transparent); }
.nm-dir-head {
  display: flex; align-items: center; gap: 8px; width: 100%; padding: 0;
  border: none; background: transparent; color: var(--text-primary); font: inherit; font-size: 0.97rem; text-align: left; cursor: pointer;
}
.nm-dir-head .nm-n { margin-left: auto; font-size: 0.84rem; color: var(--text-secondary); font-weight: 600; white-space: nowrap; }
.nm-dir-head svg { color: var(--text-muted); flex-shrink: 0; }
.nm-st { display: inline-flex; gap: 6px; align-items: center; font-weight: 600; font-size: 0.8rem; }
.nm-st-ok { color: var(--success); }
.nm-st-warn { color: var(--warning); }
.nm-flts { display: flex; flex-direction: column; gap: 8px; }
.nm-flts .nm-muted { margin: 0; }
.nm-flt {
  display: flex; align-items: center; gap: 10px; padding: 9px 12px; width: 100%; box-sizing: border-box;
  border-radius: 9px; background: var(--surface-1); border: 1px solid #25262c;
  font: inherit; font-size: 0.875rem; color: inherit; text-align: left; cursor: pointer; text-decoration: none;
}
.nm-flt:hover { border-color: var(--border-strong); text-decoration: none; }
.nm-fn { font-weight: 700; }
.nm-m { color: var(--text-muted); font-size: 0.8rem; }
.nm-d { margin-left: auto; font-weight: 600; }
.nm-flt svg { color: var(--text-muted); flex-shrink: 0; }
.nm-all { font-size: 0.84rem; font-weight: 600; }
.nm-open { display: inline-block; margin-top: 2px; font-size: 0.84rem; font-weight: 600; }
.nm-retry { align-self: flex-start; border: 1px solid var(--border-strong); background: transparent; color: var(--text-primary); border-radius: 8px; padding: 5px 12px; font: inherit; font-size: 0.84rem; cursor: pointer; }

.nm-seg { display: inline-flex; align-self: flex-start; border: 1px solid var(--border-strong); border-radius: 8px; overflow: hidden; flex-shrink: 0; }
.nm-seg button { border: none; background: transparent; color: var(--text-secondary); font: inherit; font-size: 0.8rem; font-weight: 600; padding: 6px 12px; cursor: pointer; }
.nm-seg button.on { background: var(--surface-3); color: var(--text-primary); }
.nm-prows { display: flex; flex-direction: column; }
.nm-prow { display: flex; align-items: center; gap: 8px; min-height: 33px; border-top: 1px solid #25262c; font-size: 0.875rem; color: inherit; }
.nm-prow:first-child { border-top: none; }
.nm-prow:hover { text-decoration: none; color: var(--accent-bright); }
.nm-prow .nm-n { margin-left: auto; color: var(--text-muted); font-size: 0.8rem; }
.nm-empty { margin: 0; }

/* The public page: a narrower panel, and the toolbar's own gap above the map. */
.ps-page .fd-map-note, .ps-page .nm-map { margin-top: 16px; }
.ps-map .nm-side { top: 12px; right: 12px; bottom: 12px; width: 300px; padding: 16px; gap: 10px; }
.ps-map.nm-has-side .nm-attr { right: 324px; }

/* The phone: the map fills what the screen has left, the legend folds behind a button, and the
   panel becomes a bottom sheet over the map's foot. */
@media (max-width: 640px) {
  /* The phone's heading row: words only, beside the title. */
  .fd-view { align-self: center; }
  .fd-view.fd-seg button { height: 32px; padding: 0 12px; font-size: 0.8rem; }
  .fd-view.fd-seg button .icon { display: none; }
  .nm-map { height: max(440px, calc(100dvh - 300px)); margin: 0 -24px; border-radius: 0; border-left: none; border-right: none; }
  .nm-chips, .nm-zoom { display: none; }
  .nm-legend { left: auto; right: 10px; top: 48px; bottom: auto; flex-direction: column; align-items: flex-start; gap: 8px; display: none; }
  .nm-legend-open .nm-legend { display: flex; }
  .nm-legend-btn {
    display: inline-flex; position: absolute; right: 10px; top: 10px; z-index: 2;
    padding: 6px 11px; font: inherit; font-size: 0.78rem; font-weight: 600; color: var(--text-primary);
    background: rgba(20, 21, 25, 0.94); border: 1px solid var(--border-strong); border-radius: 10px; cursor: pointer;
  }
  .nm-side, .ps-map .nm-side {
    top: auto; left: 0; right: 0; bottom: 0; width: auto; max-height: 62%;
    padding: 0 16px 16px; gap: 8px; border-radius: 18px 18px 0 0; border: none; border-top: 1px solid var(--border-strong);
    background: var(--surface-1); box-shadow: 0 -12px 34px rgba(0, 0, 0, 0.5);
  }
  .nm-grab { display: block; width: 40px; height: 4px; border-radius: 2px; background: var(--border-strong); margin: 10px auto 0; flex-shrink: 0; }
  .nm-side-k, .nm-side-note { display: none; }
  .nm-side-head { align-items: center; }
  .nm-side-title { font-size: 1.06rem; }
  .nm-x { width: 44px; height: 40px; text-align: right; }
  .nm-dir { padding: 10px 12px; gap: 6px; }
  .nm-dir:not(.nm-dir-on) .nm-st { display: none; }
  .nm-flt { padding: 7px 12px; }
  .nm-has-side .nm-attr, .ps-map.nm-has-side .nm-attr { display: none; }
  .nm-tag { font-size: 0.75rem; }
  .nm-tag-sel .nm-tag-words { display: none; }
}

/* ---- the Airport Profile ----------------------------
   The page is Flight Detail's own suite (.fdd-hero, .fdd-kfacts, .fdd-panel, .fdd-sec-head...) plus three
   shared primitives, each named for what it is and reused wherever it appears:
     .airport-link / .airport-ref - the airport link: mono, the text colour, a dotted underline
       that turns solid and accent on hover and focus; .airport-ref is the same code as plain text at the
       size of the words around it, where a link cannot go (signed out, inside a card that is itself a
       link, a hero's route graphic, a form field). .airport-code stays the cards' big display code.
     .section-nav - the sticky section nav: real links, aria-current, sideways on a phone.
     .ap-as-assumed - the dashed "assumed" aircraft badge. */

.airport-ref { font-family: var(--font-mono); font-weight: 700; color: inherit; text-transform: uppercase; }
.airport-link {
  font-family: var(--font-mono);
  font-weight: 700;
  color: inherit;
  text-decoration: none;
  border-bottom: 1px dotted var(--border-strong);
}
.airport-link:hover, .airport-link:focus-visible { color: var(--accent-bright); border-bottom: 1px solid var(--accent-bright); }
.airport-link:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 2px; border-radius: 2px; }
/* A row that opens as a whole while its airport codes stay their own links (a link may not sit
   inside a link). The row's one link stretches over it with ::after; the codes sit above that
   layer. The focus ring is drawn round the row, where the click lands. */
.has-row-link { position: relative; }
.has-row-link .row-link { color: inherit; text-decoration: none; }
.has-row-link .row-link::after { content: ""; position: absolute; inset: 0; border-radius: inherit; }
.has-row-link:hover .row-link { color: var(--accent-bright); }
.has-row-link .row-link:focus-visible { outline: none; }
.has-row-link:has(.row-link:focus-visible) { outline: 2px solid var(--accent-bright); outline-offset: 2px; }
/* Every OTHER link in the row - an airport, the pilot, the aircraft - sits above the stretch. */
.has-row-link a:not(.row-link) { position: relative; z-index: 1; }
.fdd-ap-open { display: inline-block; margin-top: 8px; font-size: 0.86rem; font-weight: 600; }
@media (pointer: coarse) {
  /* A 44 px hit area on a touch screen, without moving the text. */
  .airport-link { position: relative; }
  .airport-link::after { content: ""; position: absolute; left: -6px; right: -6px; top: 50%; height: 44px; transform: translateY(-50%); }
}

.section-nav {
  position: sticky;
  top: 64px;
  z-index: 40;
  padding: 6px;
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
  background: color-mix(in srgb, var(--surface-1) 96%, transparent);
  backdrop-filter: blur(14px);
}
/* More entries than fit (a tablet, or an airline with a long name) scroll sideways rather than
   pushing the page wider. */
.section-nav { overflow-x: auto; scrollbar-width: none; }
.section-nav::-webkit-scrollbar { display: none; }
.section-nav-list { display: flex; align-items: center; gap: 4px; margin: 0; padding: 0; list-style: none; }
.section-nav-list { flex-wrap: nowrap; }
.section-nav-link {
  display: inline-flex;
  align-items: center;
  min-height: 34px;
  padding: 0 14px;
  border-radius: var(--radius-sm);
  color: var(--text-secondary);
  font-size: 0.875rem;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}
.section-nav-link:hover { color: var(--text-primary); background: var(--surface-3); }
/* The current section sits on a light accent TINT of the page, not on the accent itself, so it takes the
   page's text colour: the on-accent ink would be white on a pale tint in the light theme, and
   near-black on a dark one with a bright accent. */
.section-nav-link[aria-current="true"] { color: var(--text-primary); background: color-mix(in srgb, var(--accent) 28%, transparent); }
.section-nav-link:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 2px; }
.ap-page [id^="ap-"] { scroll-margin-top: 132px; }
@media (prefers-reduced-motion: no-preference) { .ap-page { scroll-behavior: smooth; } }

/* Band 1: the hero - the ICAO leads; conditions and the airline's footprint sit beside it. */
.ap-hero { gap: 20px; }
.ap-hero-loading { min-height: 220px; }
.ap-hero-top { display: flex; align-items: flex-start; gap: 24px; }
.ap-hero-who { min-width: 0; flex: 1; display: flex; flex-direction: column; gap: 4px; }
.ap-place { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; color: var(--text-secondary); font-size: 0.9rem; }
.ap-flag { width: 20px; height: 14px; border-radius: 2px; object-fit: cover; }
.ap-hub { text-decoration: none; }
.ap-hub:hover { text-decoration: underline; }
.ap-title-row { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-top: 6px; }
.ap-code { margin: 0; font-size: clamp(3rem, 6vw, 4.25rem); line-height: 1; }
.ap-iata { font-family: var(--font-mono); }
.ap-hero-pill[hidden] { display: none; }
.ap-name { font-size: 1.3rem; font-weight: 600; }
.ap-town { color: var(--text-secondary); }
.ap-glance[hidden] { display: none; }
.ap-kfacts { gap: 38px; }
.ap-abbr { color: var(--text-secondary); font-weight: 600; }
.ap-mono { font-family: var(--font-mono); }
.ap-hero-action .fdd-acts .btn { white-space: nowrap; }
.ap-strap { margin: 0; }

/* Band 2: where the pilot is. Green here, amber elsewhere, accent travelling here, plain otherwise;
   every state also says so in words and carries its own icon - never colour alone. */
.ap-band {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 16px 20px;
  border-radius: var(--radius-lg);
  border: 1px solid var(--border);
  background: var(--surface-1);
}
.ap-band-icon {
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-md);
  background: var(--surface-3);
  color: var(--text-muted);
}
.ap-band-icon .icon { width: 22px; height: 22px; }
.ap-band-ok { border-color: color-mix(in srgb, var(--success) 40%, transparent);
  background: linear-gradient(90deg, color-mix(in srgb, var(--success) 14%, transparent), color-mix(in srgb, var(--success) 4%, transparent) 55%, var(--surface-1)); }
.ap-band-ok .ap-band-icon { background: color-mix(in srgb, var(--success) 20%, transparent); color: var(--success); }
.ap-band-warn { border-color: color-mix(in srgb, var(--warning) 50%, transparent);
  background: linear-gradient(90deg, color-mix(in srgb, var(--warning) 13%, transparent), color-mix(in srgb, var(--warning) 4%, transparent) 55%, var(--surface-1)); }
.ap-band-warn .ap-band-icon { background: color-mix(in srgb, var(--warning) 18%, transparent); color: var(--warning); }
.ap-band-accent { border-color: color-mix(in srgb, var(--accent-bright) 35%, transparent);
  background: linear-gradient(90deg, color-mix(in srgb, var(--accent) 20%, transparent), color-mix(in srgb, var(--accent) 5%, transparent) 60%, var(--surface-1)); }
.ap-band-accent .ap-band-icon { background: color-mix(in srgb, var(--accent) 30%, transparent); color: var(--accent-bright); }
.ap-band-words { min-width: 0; flex: 1; }
.ap-band-key { font-size: 0.75rem; font-weight: 600; letter-spacing: 0.07em; text-transform: uppercase; color: var(--text-secondary); }
.ap-band-main { margin-top: 2px; font-size: 1.12rem; font-weight: 600; }
.ap-band-aside { font-size: 0.82rem; font-weight: 400; }
.ap-band-sub { margin-top: 2px; font-size: 0.9rem; color: var(--text-secondary); }
.ap-band-side { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; flex-shrink: 0; }
.ap-band-counts { display: flex; gap: 18px; align-items: center; }
.ap-band-count { font-size: 0.95rem; white-space: nowrap; }
.ap-band-acts { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; justify-content: flex-end; }
.ap-band-side:has(.ap-band-counts) { flex-direction: row; align-items: center; gap: 18px; }
.ap-band-note { font-size: 0.84rem; color: var(--text-muted); }

/* Band 3: operate - the network and the flights; the flights beside the ways here when elsewhere. */
#ap-body { display: flex; flex-direction: column; gap: 16px; }
.ap-sections { display: flex; flex-direction: column; gap: 18px; }
.ap-row-operate { grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); }
.ap-row-elsewhere { grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr); }
.ap-panel { display: flex; flex-direction: column; min-width: 0; }
.ap-sec-head { flex-wrap: wrap; margin-bottom: 14px; }
.ap-sec-head .fdd-section-title { margin: 0; }
.ap-sec-count { font-size: 0.84rem; margin-left: auto; }
.ap-sec-all { display: none; margin-left: auto; font-size: 0.86rem; font-weight: 600; }
.ap-panel-body { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.ap-seg { flex-shrink: 0; }
.ap-seg button { min-height: 32px; padding: 0 12px; font-size: 0.8rem; }
.ap-seg button:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: -2px; }
.ap-sec-head .ap-seg:first-of-type { margin-left: auto; }

.ap-map-wrap { position: relative; margin-bottom: 8px; }
.ap-map { height: 372px; }
/* Over the map's top-left corner. */
.ap-map-legend {
  position: absolute; left: 12px; top: 10px; z-index: 1;
  display: flex; align-items: center; flex-wrap: wrap; gap: 12px;
  padding: 4px 10px; border: 1px solid var(--border); border-radius: 8px;
  background: var(--surface-3); font-size: 0.78rem; color: var(--text-secondary);
}
.ap-leg { display: inline-flex; align-items: center; gap: 6px; }
.ap-leg::before { content: ""; width: 16px; height: 3px; border-radius: 2px; background: var(--accent-bright); }
.ap-leg-cargo::before { background: var(--info); }
.ap-net-foot { font-size: 0.84rem; }
.ap-map-pop .maplibregl-popup-content {
  padding: 12px 14px;
  border-radius: 10px;
  border: 1px solid var(--border-strong);
  background: var(--surface-3);
  color: var(--text-primary);
  box-shadow: var(--shadow-2);
}
.ap-map-pop .maplibregl-popup-tip { display: none; }
.ap-tip { display: flex; flex-direction: column; gap: 3px; min-width: 200px; font-size: 0.84rem; }
.ap-tip-head { display: flex; gap: 8px; font-weight: 600; }
.ap-tip-line { color: var(--text-secondary); }
.ap-tip-links { display: flex; gap: 14px; margin-top: 6px; font-weight: 600; }

.ap-table-scroll { overflow-x: auto; }
.ap-table { width: 100%; border-collapse: collapse; font-size: 0.92rem; }
.ap-table th { text-align: left; font-size: 0.75rem; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-muted); padding: 0 12px 8px 0; }
.ap-table td { padding: 8px 12px 8px 0; border-top: 1px solid var(--border); vertical-align: middle; }
.ap-table td:last-child { white-space: nowrap; font-weight: 600; }
.ap-td-name { font-size: 0.86rem; }

.ap-frows { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.ap-frows li + li .ap-frow { border-top: 1px solid var(--border); }
.ap-frow {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 2px 12px;
  padding: 11px 0;
  color: inherit;
  text-decoration: none;
  font-size: 0.93rem;
}
.ap-frows li:first-child .ap-frow { padding-top: 0; }
.ap-frow:hover .ap-frow-top strong { color: var(--accent-bright); }
.ap-frow:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 2px; border-radius: 6px; }
.ap-frow-cue { justify-self: end; align-self: start; margin-left: 0; }
.ap-frow-sub { color: var(--text-secondary); font-size: 0.86rem; }
.ap-frow-st { justify-self: end; font-size: 0.82rem; }
.ap-frow-btn { width: 100%; text-align: left; border: none; border-bottom: 1px solid var(--border); background: none; font: inherit; cursor: pointer; }
.ap-frow-btn:disabled { cursor: default; }
.ap-frows-foot { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-top: 4px; font-size: 0.9rem; font-weight: 600; }
.ap-frows-foot .fd-sg-btn { margin-left: auto; }
.ap-sg-note { margin-left: auto; font-weight: 400; font-size: 0.86rem; }
.ap-inline-link { margin-left: 0; font-size: inherit; }
.ap-ways-line { color: var(--text-secondary); font-size: 0.9rem; }
.ap-ways-link { font-size: 0.9rem; font-weight: 600; }

/* A section's own states: quiet empty sentences, and an error with its own Try again. */
.ap-quiet-block { display: flex; flex-direction: column; gap: 4px; }
.ap-quiet { font-size: 1.02rem; font-weight: 600; }
.ap-quiet-text { color: var(--text-secondary); font-size: 0.9rem; }
.ap-quiet-acts { margin-top: 8px; }
.ap-err {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  border-radius: var(--radius-sm);
  border: 1px solid color-mix(in srgb, var(--danger) 40%, transparent);
  background: color-mix(in srgb, var(--danger) 8%, transparent);
  font-size: 0.92rem;
}
.ap-err > .icon { width: 20px; height: 20px; color: var(--danger); flex-shrink: 0; }
.ap-err .btn { margin-left: auto; }

/* The page-level states. */
.ap-page-state { margin-top: 12px; padding: 36px 24px; }
.ap-state-title { margin: 0; font-size: 1.3rem; letter-spacing: -0.01em; }
.ap-search { position: relative; width: min(420px, 100%); display: flex; align-items: center; gap: 8px;
  padding: 0 12px; border: 1px solid var(--border-strong); border-radius: var(--radius-sm); background: var(--surface-1); }
.ap-search > .icon { width: 17px; height: 17px; color: var(--text-muted); }
.ap-search-input { flex: 1; min-height: 42px; border: none; background: transparent; color: var(--text-primary); font: inherit; }
.ap-search-input:focus { outline: none; }
.ap-search:focus-within { border-color: var(--accent-bright); }
.ap-search-results { position: absolute; left: 0; right: 0; top: calc(100% + 4px); z-index: 20; margin: 0; padding: 4px;
  list-style: none; border: 1px solid var(--border-strong); border-radius: var(--radius-sm); background: var(--surface-2); box-shadow: var(--shadow-2); text-align: left; }
.ap-search-results[hidden] { display: none; }
.ap-search-hit { display: block; padding: 8px 10px; border-radius: 6px; color: var(--text-primary); text-decoration: none; }
.ap-search-hit:hover, .ap-search-hit:focus-visible { background: var(--surface-3); outline: none; }

.ap-sticky { display: none; }

/* Band 4: conditions beside the runway. The drawings are the shared weather models'
   (airport-weather.js); the category is always a word in its pill, never a colour alone. */
.ap-glance {
  flex: 0 0 330px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 14px 16px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface-1);
  color: inherit;
  text-decoration: none;
}
.ap-glance:hover { border-color: var(--border-strong); }
.ap-glance:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 2px; }
.ap-glance-top { display: flex; align-items: center; gap: 10px; }
.ap-glance-top .fdd-wx-pill { margin-left: auto; }
.ap-glance-wind { margin-top: 4px; font-size: 1.1rem; font-weight: 600; }
.ap-glance-details { font-size: 0.9rem; color: var(--text-secondary); }
.ap-glance-seen { font-size: 0.8rem; }
.ap-glance-seen.is-stale, .ap-sec-count.is-stale { color: var(--warning); }
.ap-hero-pill { display: none; }
.ap-hero-wx { display: none; }
.fdd-wx-pill.ap-wx-pill { margin-left: 0; }

.ap-stack { display: flex; flex-direction: column; gap: 18px; min-width: 0; }
.ap-row-conditions { grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr); }
.ap-wx-neighbour { margin: 0 0 12px; color: var(--text-secondary); font-size: 0.92rem; }
.ap-wx-tiles { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 18px; }
.ap-wx-tile { min-width: 0; }
.ap-wx-tile-v { margin-top: 4px; font-size: 1.12rem; font-weight: 600; white-space: nowrap; }
.ap-inline-facts { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 18px; margin-top: 14px; font-size: 0.9rem; }
.ap-inline-fact strong { font-weight: 600; }
.ap-wx-forecast { margin-top: 18px; }
.ap-wx-forecast-head { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 8px; }
.ap-wx-legend { margin-left: auto; display: flex; gap: 12px; font-size: 0.78rem; color: var(--text-secondary); }
.ap-wx-legend-item { display: inline-flex; align-items: center; gap: 5px; }
.ap-wx-legend-item::before { content: ""; width: 10px; height: 10px; border-radius: 2px; background: var(--text-muted); }
.ap-wx-legend-item[data-cat="vfr"]::before { background: var(--wx-vfr); }
.ap-wx-legend-item[data-cat="mvfr"]::before { background: var(--wx-mvfr); }
.ap-wx-legend-item[data-cat="ifr"]::before { background: var(--wx-ifr); }
.ap-wx-legend-item[data-cat="lifr"]::before { background: var(--wx-lifr); }
.ap-wx-forecast-line { display: none; font-size: 0.9rem; color: var(--text-secondary); }
.ap-wx-raw { margin-top: 12px; }
.ap-wx-raw-btn { margin-left: 0; font-size: 0.86rem; }
.ap-wx-raw-text {
  margin-top: 8px;
  padding: 10px 12px;
  border-radius: 8px;
  background: var(--surface-1);
  font-family: var(--font-mono);
  font-size: 0.8rem;
  line-height: 1.6;
  overflow-wrap: anywhere;
}
.ap-wx-raw-text[hidden] { display: none; }

/* The TAF timeline, in the layout's own 1100-unit drawing scaled to the panel. */
.ap-tl { display: block; width: 100%; height: auto; }
.ap-tl-tag { font-size: 10px; font-weight: 700; letter-spacing: 0.06em; }
.ap-tl-muted { fill: var(--text-muted); }
.ap-tl-hour { fill: var(--text-muted); font-size: 11px; }
.ap-tl-axis { stroke: var(--border); }
.ap-tl-now { stroke: var(--text-primary); stroke-dasharray: 3 3; }
.ap-tl-band { opacity: 0.88; }
.ap-tl-fill-vfr { fill: var(--wx-vfr); }
.ap-tl-fill-mvfr { fill: var(--wx-mvfr); }
.ap-tl-fill-ifr { fill: var(--wx-ifr); }
.ap-tl-fill-lifr { fill: var(--wx-lifr); }
.ap-tl-fill-unknown { fill: var(--text-muted); }
.ap-tl-on-vfr, .ap-tl-on-mvfr, .ap-tl-on-ifr, .ap-tl-on-lifr, .ap-tl-on-unknown { fill: #0b0c0e; }
.ap-tl-hatch-vfr { fill: var(--wx-vfr); }
.ap-tl-hatch-mvfr { fill: var(--wx-mvfr); }
.ap-tl-hatch-ifr { fill: var(--wx-ifr); }
.ap-tl-hatch-lifr { fill: var(--wx-lifr); }
.ap-tl-hatch-bg-vfr { fill: color-mix(in srgb, var(--wx-vfr) 20%, transparent); }
.ap-tl-hatch-bg-mvfr { fill: color-mix(in srgb, var(--wx-mvfr) 20%, transparent); }
.ap-tl-hatch-bg-ifr { fill: color-mix(in srgb, var(--wx-ifr) 20%, transparent); }
.ap-tl-hatch-bg-lifr { fill: color-mix(in srgb, var(--wx-lifr) 20%, transparent); }
.ap-tl-edge-vfr { stroke: var(--wx-vfr); }
.ap-tl-edge-mvfr { stroke: var(--wx-mvfr); }
.ap-tl-edge-ifr { stroke: var(--wx-ifr); }
.ap-tl-edge-lifr { stroke: var(--wx-lifr); }
.ap-tl-on-hatch-vfr, .ap-tl-on-hatch-mvfr, .ap-tl-on-hatch-ifr, .ap-tl-on-hatch-lifr, .ap-tl-on-hatch-unknown { fill: var(--text-primary); }
.ap-tl-stop-vfr { stop-color: var(--wx-vfr); }
.ap-tl-stop-mvfr { stop-color: var(--wx-mvfr); }
.ap-tl-stop-ifr { stop-color: var(--wx-ifr); }
.ap-tl-stop-lifr { stop-color: var(--wx-lifr); }
.ap-tl-stop-unknown { stop-color: var(--text-muted); }

/* The runway, turned to its true heading; green marks the landing end. */
.ap-rwy-draw { display: flex; flex-direction: column; align-items: center; gap: 4px; }
.ap-rwy { display: block; width: 100%; max-width: 360px; height: auto; }
.ap-rwy-wind { fill: var(--text-primary); font-family: var(--font-mono); font-size: 12px; font-weight: 700; }
.ap-rwy-strip { fill: var(--surface-3); stroke: var(--border-strong); }
.ap-rwy-centre { stroke: var(--text-muted); stroke-width: 2; stroke-dasharray: 14 12; }
.ap-rwy-centre-small { stroke-width: 1.5; stroke-dasharray: 9 8; }
.ap-rwy-threshold { fill: var(--success); }
.ap-rwy-ident { fill: var(--text-primary); font-family: var(--font-mono); font-size: 12px; font-weight: 700; }
.ap-rwy-ident-small { font-size: 10px; }
.ap-rwy-shaft { stroke: var(--warning); stroke-width: 3; stroke-linecap: round; }
.ap-rwy-head { fill: var(--warning); }
.ap-rwy-caption { font-size: 0.8rem; text-align: center; }
.ap-rwy-facts .ap-inline-facts { margin-top: 12px; }
.ap-rwy-rows { display: flex; flex-direction: column; gap: 8px; margin-top: 14px; }
.ap-rwy-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 9px 12px;
  border: 1px solid var(--border);
  border-radius: 10px;
  font-size: 0.9rem;
}
.ap-rwy-row.is-favourite { border-color: color-mix(in srgb, var(--success) 55%, transparent); background: color-mix(in srgb, var(--success) 8%, transparent); }
.ap-rwy-pill { margin-left: auto; white-space: nowrap; }
.ap-rwy-pill.is-ok { color: var(--success); border-color: color-mix(in srgb, var(--success) 55%, transparent); }
.ap-rwy-gusts { margin: -2px 0 0 12px; font-size: 0.82rem; }
.ap-rwy-note { margin-top: 12px; font-size: 0.82rem; }

/* Bands 5 to 7: the airline and your history, aircraft and activity, airport information. */
.ap-row-data { grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr); }
.ap-row-one { grid-template-columns: minmax(0, 1fr); }
.ap-panel-note { margin-top: 14px; font-size: 0.8rem; }
.ap-sec-link { margin-left: auto; font-size: 0.86rem; font-weight: 600; }
.ap-stat-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 18px 16px; }
.ap-stat-grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.ap-stat { min-width: 0; }
.ap-stat-v { font-size: 1.45rem; font-weight: 700; letter-spacing: -0.01em; line-height: 1.2; font-variant-numeric: tabular-nums; white-space: nowrap; }
.ap-stat-k { margin-top: 2px; font-size: 0.8rem; color: var(--text-secondary); }
.ap-ranks { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px; margin-top: 22px; }
.ap-rank-col { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ap-rank-col .fdd-kf-k { margin-bottom: 6px; }
.ap-rank {
  display: grid;
  border-top: 1px solid var(--border);
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 2px 10px;
  padding: 6px 0;
  color: inherit;
  text-decoration: none;
  font-size: 0.9rem;
}
.ap-rank:hover .ap-rank-name, .ap-rank:focus-visible .ap-rank-name { color: var(--accent-bright); }
.ap-rank:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 2px; border-radius: 6px; }
.ap-rank-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ap-rank-n { font-variant-numeric: tabular-nums; white-space: nowrap; }
.ap-rank-bar { grid-column: 1 / -1; height: 4px; border-radius: 2px; background: var(--surface-3); overflow: hidden; }
.ap-rank-bar i { display: block; height: 100%; border-radius: 2px; background: var(--accent-bright); }
.ap-history-line { display: none; }
/* align-content: a facts list is a grid ITEM of the airport-information grid, so without this its rows
   stretch to the height of the tallest column beside it - seven 80 px rows for seven lines of text. */
.ap-dl { display: grid; grid-template-columns: minmax(96px, 150px) minmax(0, 1fr); align-content: start; gap: 7px 14px; margin: 16px 0 0; font-size: 0.9rem; }
.ap-dl dt { color: var(--text-secondary); }
.ap-dl dd { margin: 0; }
.ap-history-latest { margin-top: 18px; }
.ap-history-latest .fdd-kf-k { margin-bottom: 4px; }


.ap-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-left: auto; }
.ap-chips .chip { min-height: 32px; }
.ap-ac-group { display: flex; flex-direction: column; }
.ap-ac-head { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; font-size: 0.86rem; font-weight: 600; }
.ap-ac-head svg { width: 16px; height: 16px; flex: none; }
.ap-ac-text { margin-bottom: 6px; font-size: 0.84rem; }
.ap-ac-row { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 12px; padding: 9px 0; font-size: 0.9rem; }
.ap-ac-row + .ap-ac-row { border-top: 1px solid var(--border); }
.ap-ac-reg {
  font-family: var(--font-mono);
  font-weight: 700;
  text-transform: uppercase;
  font-size: 0.9rem;
}
/* An assumed row is muted, and its link is muted with it. */
.ap-ac-row.is-assumed .ap-ac-reg { color: var(--text-muted); }
.ap-ac-what { min-width: 0; }
.ap-ac-state { padding: 2px 9px; border: 1px solid var(--border-strong); border-radius: 999px; font-size: 0.76rem; font-weight: 600; white-space: nowrap; }
.ap-ac-available { color: var(--success); border-color: color-mix(in srgb, var(--success) 55%, transparent); }
.ap-ac-reserved, .ap-ac-reserved_by_you, .ap-ac-departing { color: var(--info); border-color: color-mix(in srgb, var(--info) 55%, transparent); }
.ap-ac-maintenance { color: var(--warning); border-color: color-mix(in srgb, var(--warning) 55%, transparent); }
/* The assumed badge: dashed and muted, never the confirmed shape. */
.ap-as-assumed {
  margin-top: 14px;
  padding: 12px 14px;
  border: 1px dashed var(--border-strong);
  border-radius: 12px;
}
.ap-ac-row.is-assumed { color: var(--text-secondary); }
.ap-ac-assumed { color: var(--text-secondary); border-style: dashed; }

.ap-act { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: start; gap: 12px; padding: 10px 0; border-top: 1px solid var(--border); font-size: 0.9rem; color: inherit; text-decoration: none; }
.ap-act > svg { width: 17px; height: 17px; margin-top: 3px; color: var(--text-secondary); }
.ap-act > .ap-act-in { color: var(--success); }
.ap-act > .ap-act-out { color: var(--accent-bright); }
.ap-act-live { padding: 10px 12px; border: 1px solid color-mix(in srgb, var(--info) 45%, transparent); border-radius: 10px; background: color-mix(in srgb, var(--info) 8%, transparent); }
.ap-act-live > svg { color: var(--info); }
.ap-act-live:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 2px; }
.ap-act-words { display: flex; flex-direction: column; min-width: 0; }
.ap-act-tag { font-size: 0.72rem; font-weight: 700; letter-spacing: 0.07em; color: var(--info); }
.ap-act-main { color: inherit; text-decoration: none; }
a.ap-act-main:hover { color: var(--accent-bright); }
.ap-act-sub { font-size: 0.82rem; }
.ap-act-t { font-size: 0.8rem; text-align: right; white-space: nowrap; }

/* 1.1fr 1fr 1fr with a 34px gutter, and a 120px label column, so a fact never wraps. */
.ap-info-grid { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr) minmax(0, 1fr); gap: 34px; }
.ap-info-grid > * { align-self: start; }
.ap-info-grid .ap-dl { grid-template-columns: 120px minmax(0, 1fr); }
.ap-info-grid .ap-dl { margin-top: 0; }
.ap-info-grid .fdd-kf-k { margin-bottom: 6px; }
.ap-table-plain td { padding: 7px 12px 7px 0; border-top: 1px solid var(--border); }
/* A long list of frequencies (Heathrow has fourteen) scrolls rather than stretching the panel and
   leaving the facts beside it in a hole. Same thin, quiet bar as the map overlays. */
.ap-scroll { max-height: 300px; overflow-y: auto; padding-right: 12px; }
/* Recent activity is as long as the airline is old, so it scrolls too - under the flights in the air,
   which stay in view. The first row keeps its rule against the card above it. */
.ap-act-list { max-height: 430px; }

.ap-fold { display: none; }



@media (prefers-reduced-motion: reduce) {
  .ap-page, .ap-page * { scroll-behavior: auto !important; }
}

@media (max-width: 900px) {
  .ap-row-operate, .ap-row-elsewhere, .ap-row-conditions, .ap-row-data { grid-template-columns: minmax(0, 1fr); }
  .ap-info-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .ap-glance { flex-basis: auto; align-self: stretch; }
  .ap-hero-top { flex-direction: column; }
}

/* The phone: the rows open up into the phone order, the section nav scrolls sideways, and the one
   contextual action sits in a bar at the bottom of the screen. */
@media (max-width: 640px) {
  .ap-page { padding-bottom: 120px; }
  .ap-hero { padding: 18px; gap: 14px; }
  .ap-code { font-size: 2.6rem; }
  .ap-name { font-size: 1.1rem; }
  .ap-kfacts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
  .ap-kfacts .fdd-kf:not(.ap-kf-time):not(.ap-kf-runway) { display: none; }
  .ap-hero-action { display: none; }
  .ap-band { padding: 12px 14px; align-items: flex-start; }
  .ap-band-icon { width: 36px; height: 36px; }
  .ap-band-key { display: none; }
  .ap-band-main { font-size: 1rem; }
  .ap-band { flex-wrap: wrap; row-gap: 0; }
  .ap-band-side { flex-basis: 100%; align-items: flex-start; padding-left: 52px; margin-top: -14px; }
  .ap-band-side:not(:has(.ap-band-counts)) { display: none; }
  .ap-band-acts, .ap-band-note { display: none; }
  .ap-band-counts { gap: 12px; flex-wrap: wrap; }
  .ap-band-count { font-size: 0.86rem; }
  .ap-hub-name { display: none; }
  #ap-flights-count { display: none; }
  .ap-glance { display: none; }
  .ap-hero-pill:not([hidden]) { display: inline-flex; margin-left: auto; }
  .ap-hero-wx:not([hidden]) { display: block; margin-top: 8px; font-size: 0.9rem; color: var(--text-secondary); }
  .ap-wx-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
  .ap-wx-forecast .ap-tl, .ap-wx-legend { display: none; }
  .ap-wx-forecast-line { display: block; }
  /* No scroll inside a scroll on a phone: these sections already fold, so an opened one runs in full
     rather than trapping the page under a finger. */
  .ap-scroll { max-height: none; overflow: visible; padding-right: 0; }
  /* On a phone the later sections fold to one line each; history shows its figures and one line. */
  .ap-fold { display: flex; align-items: center; gap: 8px; margin-left: auto; min-height: 44px; padding: 0; border: 0; background: none; color: inherit; font: inherit; cursor: pointer; }
  .ap-fold svg { width: 18px; height: 18px; transform: rotate(90deg); transition: transform 0.15s; color: var(--text-muted); }
  .ap-fold[aria-expanded="true"] svg { transform: rotate(-90deg); }
  .ap-fold-summary { font-size: 0.82rem; font-weight: 400; }
  .ap-foldable:not(.is-open) > .ap-panel-body { display: none; }
  .ap-foldable:not(.is-open) .ap-sec-head { margin-bottom: 0; }
  .ap-foldable:not(.is-open) .ap-sec-head > :not(h2):not(.ap-fold) { display: none; }
  .ap-foldable .ap-sec-head > .ap-seg, .ap-foldable .ap-sec-head > .ap-chips { flex-basis: 100%; margin-left: 0; order: 3; }
  .ap-foldable .ap-sec-head > .ap-sec-count { display: none; }
  .ap-history-line:not(:empty) { display: block; margin-top: 10px; font-size: 0.86rem; }
  .ap-history-facts, .ap-history-latest { display: none; }
  .ap-stat-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ap-stat-grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .ap-ranks { grid-template-columns: minmax(0, 1fr); }
  .ap-info-grid { grid-template-columns: minmax(0, 1fr); }
  .ap-ac-row { grid-template-columns: auto minmax(0, 1fr); }
  .ap-ac-state { grid-column: 2; justify-self: start; }
  .ap-sec-all:not([hidden]) { display: inline; }
  .section-nav { top: 64px; margin: 0 -16px; border-radius: 0; border-left: none; border-right: none; overflow-x: auto; scrollbar-width: none; }
  .section-nav::-webkit-scrollbar { display: none; }
  .section-nav-link { min-height: 44px; }
  .ap-row-operate { display: flex; flex-direction: column-reverse; }
  /* On a phone the flights come first, whether the pilot is here or elsewhere; the ways to get
     here ride under them, and the map follows (the row holds [network, [flights, ways]]). */
  .ap-row-elsewhere { display: flex; flex-direction: column-reverse; }
  .ap-map { height: 260px; }
  .ap-seg button { min-height: 44px; }
  .ap-frow { min-height: 44px; }
  .ap-frow-sub, .ap-frow-st { grid-column: 1 / -1; }
  .ap-frow-st { justify-self: start; }
  .ap-sticky {
    display: flex;
    flex-direction: column;
    gap: 8px;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 45;
    padding: 12px 16px calc(12px + env(safe-area-inset-bottom));
    border-top: 1px solid var(--border);
    background: color-mix(in srgb, var(--surface-1) 96%, transparent);
    backdrop-filter: blur(14px);
  }
  .ap-sticky-warn { border-top-color: color-mix(in srgb, var(--warning) 50%, transparent); }
  .ap-sticky-note { display: flex; justify-content: space-between; gap: 12px; font-size: 0.84rem; color: var(--text-secondary); }
  .ap-sticky-link { font-weight: 600; }
  .ap-sticky-btn { width: 100%; justify-content: center; min-height: 48px; }
}

/* The one way forward from a rank-locked flight card. A link, not a button - it navigates to
   the ranks page - and it sits under the reason so the card reads status, why, what to do about
   it. */
.fd-rank-link { font-weight: 600; font-size: 0.8rem; color: var(--accent-bright); }
.fd-rank-link:hover { text-decoration: underline; }

/* ---- a staff assignment the airline's rank rule has made unstartable ----
   Amber, never error red: the airline changed a rule, the pilot did nothing wrong. It carries
   the way forward as well as the bad news, and it says that the assignment has stopped blocking
   their other flying - otherwise a pilot who can neither start it nor fly anything else has no
   explanation at all. */
.assignment-blocked,
.next-flight-blocked {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  align-items: flex-start;
  margin-top: 0.75rem;
  padding: 0.7rem 0.9rem;
  border: 1px solid rgba(217, 161, 60, 0.45);
  border-radius: var(--radius-sm);
  background: rgba(217, 161, 60, 0.12);
}
.assignment-blocked .fd-rank-link,
.next-flight-blocked .fd-rank-link { margin-top: 0.35rem; }

/* ---- the Ranks page ----
   Depth follows distance: a passed rung is one line, the current and next rungs are cards, a
   later rung is quieter again. And a state is always a word beside its shape. */

.ranks-page { padding-bottom: 3rem; }
.ranks-heading { margin: var(--page-top) 0 1.1rem; }
.ranks-heading h1 { margin: 0; font-size: var(--page-title-size); letter-spacing: -0.02em; }
.ranks-heading p { margin: 2px 0 0; font-size: 0.94rem; }
#ranks-body { display: flex; flex-direction: column; gap: 18px; }

/* 1 · the current-rank band. */
.ranks-current {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 1.1rem 1.4rem;
  border-radius: var(--radius-lg);
  border: 1px solid var(--accent-glow);
  background: linear-gradient(90deg, var(--accent-soft), transparent 55%, var(--surface-2));
}
.ranks-emblem {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  flex-shrink: 0;
  border-radius: var(--radius-md);
  background: var(--accent-soft);
  border: 1px solid var(--accent-glow);
  color: var(--accent-bright);
}
.ranks-current-who { min-width: 0; }
.ranks-current-key {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--text-secondary);
}
.ranks-current-name { margin: 0; font-size: 1.9rem; font-weight: 700; line-height: 1.15; }
/* The no-rank sentence is a sentence, not a name, so it is not set like one. */
.ranks-current-none { font-size: 1.15rem; font-weight: 600; }
.ranks-current-note { margin-top: 4px; font-size: 0.9rem; color: var(--text-secondary); }
.ranks-current-totals { margin-left: auto; text-align: right; }
.ranks-figures { font-size: 0.96rem; color: var(--text-secondary); }
.ranks-figures strong { color: var(--text-primary); font-variant-numeric: tabular-nums; }
.ranks-figure-sep { color: var(--text-muted); }
.ranks-figures-note { font-size: 0.8rem; margin-top: 4px; }

/* 2 + 3 · the ladder, and what sits beside it. */
.ranks-columns {
  display: grid;
  grid-template-columns: minmax(0, 1.75fr) minmax(0, 1fr);
  gap: 26px;
  align-items: start;
}
.ranks-ladder-column { min-width: 0; }
.ranks-ladder-head { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; }
.ranks-key {
  display: flex;
  gap: 16px;
  margin: 0 0 0 auto;
  font-size: 0.78rem;
  flex-wrap: wrap;
}
.ranks-key span { display: inline-flex; align-items: center; gap: 5px; }
.rank-key-tick { color: var(--success); }
.rank-key-lock { color: var(--warning); font-size: 0.7rem; }

.ranks-aside { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.ranks-panel:hover { transform: none; border-color: var(--border); }
.ranks-panel h2 { margin: 0 0 10px; }
.ranks-panel-head { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.ranks-panel-head h2 { margin: 0; }
.ranks-panel-aside { margin-left: auto; font-size: 0.78rem; }
.ranks-panel-text { margin: 0 0 12px; font-size: 0.88rem; color: var(--text-secondary); }
/* Recognition is a different kind of thing, so it gets its own frame. */
.ranks-honorary-frame { border-top: 1px solid var(--border); padding-top: 18px; margin-top: 4px; }
.ranks-honorary-frame .card { background: var(--surface-1); }
.rank-honorary-row { display: flex; align-items: center; gap: 12px; }
.rank-honorary-emblem {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  flex-shrink: 0;
  border-radius: 10px;
  background: var(--surface-3);
  border: 1px solid var(--border);
  color: var(--text-secondary);
}
.rank-honorary-name { font-weight: 600; font-size: 0.98rem; }
.rank-honorary-by { font-size: 0.8rem; }
.ranks-honorary-note {
  margin: 14px 0 0;
  padding-top: 12px;
  border-top: 1px solid var(--border);
  font-size: 0.88rem;
  color: var(--text-secondary);
}

/* The ladder. An ordered list with a rail; the node's shape is decoration beside the word. */
.rank-ladder { list-style: none; margin: 0; padding: 0; }
.rank-rung { display: grid; grid-template-columns: 30px minmax(0, 1fr); gap: 0 14px; }
.rank-rail { display: flex; flex-direction: column; align-items: center; }
.rank-node {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  flex-shrink: 0;
  margin-top: 4px;
  border-radius: 50%;
  border: 2px solid var(--border-strong);
  background: var(--surface-1);
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--text-muted);
}
.rank-node-reached { border-color: var(--success); color: var(--success); }
.rank-node-current {
  width: 30px;
  height: 30px;
  margin-top: 8px;
  border-color: var(--accent-bright);
  background: var(--accent-soft);
  color: var(--accent-bright);
  box-shadow: 0 0 0 4px var(--accent-soft);
}
.rank-node-next { border-color: var(--info); color: var(--info); }
.rank-rail-line { flex: 1; width: 2px; background: var(--border); margin: 4px 0; }
.rank-rail-done { background: color-mix(in srgb, var(--success) 45%, transparent); }
.rank-rung-body { min-width: 0; padding-bottom: 14px; }

.rank-rung-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.rank-rung-name { font-weight: 600; font-size: 1rem; }
.rank-rung-asks { font-size: 0.88rem; }
.rank-rung-state { margin-left: auto; font-size: 0.85rem; white-space: nowrap; }
.rank-state-ok { color: var(--success); font-weight: 600; }
/* A passed rung is history: one line, and history does not need bars. */
.rank-rung-passed { padding: 0.45rem 0; }

.rank-card {
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
  background: var(--surface-2);
  padding: 1rem 1.15rem;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.rank-card-current { border-color: var(--accent-glow); background: var(--surface-3); }
.rank-card-next { border-color: color-mix(in srgb, var(--info) 35%, transparent); }
.rank-card-later { background: transparent; }
.rank-card-name { font-size: 1.32rem; font-weight: 700; letter-spacing: -0.01em; }
.rank-card-name-later { font-size: 1.02rem; font-weight: 600; color: var(--text-secondary); }
.rank-later-figures { font-size: 0.88rem; margin-top: -4px; }
.rank-rung-remaining { margin: 0; font-size: 0.88rem; color: var(--text-secondary); }
/* Arrived here from Fleet with ?rank=CODE: the same ring keyboard focus uses. */
.rank-card-focus { outline: 2px solid var(--accent-bright); outline-offset: 3px; }
/* The rung the link named: the card carries the ring, and the list item scrolls to it. */
.rank-rung-focus { scroll-margin-top: 5rem; }

/* One requirement. A thin bar, its own figures, and its own shortfall - never merged. */
.rank-req {
  display: grid;
  grid-template-columns: 7rem 6rem minmax(3rem, 1fr) 8rem;
  align-items: center;
  gap: 0 12px;
  padding: 8px 0;
  border-top: 1px solid var(--border);
  font-size: 0.86rem;
}
.rank-req:first-of-type { border-top: none; }
.rank-req-label { color: var(--text-secondary); }
.rank-req-figures { font-variant-numeric: tabular-nums; }
.rank-req-bar { height: 4px; border-radius: 2px; background: var(--surface-3); overflow: hidden; }
.rank-req-fill { display: block; height: 4px; border-radius: 2px; background: var(--accent-bright); }
.rank-req-fill-met { background: var(--success); }
.rank-req-remaining { text-align: right; font-weight: 600; }
.rank-req-met { text-align: right; font-weight: 600; color: var(--success); }

/* What a rung unlocks. The tick or the padlock always travels with the words. */
.rank-unlocks-row { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.rank-unlocks-label {
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.rank-unlocks { display: flex; gap: 8px; flex-wrap: wrap; }
.rank-unlock-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 11px;
  border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--success) 40%, transparent);
  background: color-mix(in srgb, var(--success) 10%, transparent);
  color: var(--text-primary);
  font-size: 0.8rem;
  text-decoration: none;
}
.rank-unlock-chip:hover { border-color: var(--success); }
.rank-unlock-chip .mono { font-weight: 700; }
.rank-unlock-name { color: var(--text-secondary); }
.rank-unlock-locked {
  border-color: color-mix(in srgb, var(--warning) 40%, transparent);
  background: color-mix(in srgb, var(--warning) 10%, transparent);
}
.rank-unlock-locked:hover { border-color: var(--warning); }

/* Tablet and phone: one column, and the band stacks rather than squeezing the totals against
   the rank. */
@media (max-width: 1024px) {
  .ranks-columns { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 720px) {
  .ranks-current { flex-wrap: wrap; }
  .ranks-current-totals { margin-left: 0; text-align: left; flex-basis: 100%; }
  .ranks-current-name { font-size: 1.55rem; }
  .ranks-ladder-head { flex-wrap: wrap; }
  .ranks-key { margin-left: 0; flex-basis: 100%; }
  .rank-rung-state { margin-left: 0; flex-basis: 100%; }
  .rank-req { grid-template-columns: minmax(0, 1fr) auto; gap: 2px 10px; }
  .rank-req-bar { grid-column: 1 / -1; margin: 4px 0; }
  .rank-req-figures { text-align: right; }
}
/* ---- Shared page primitives ----
   Shared by the Aircraft Profile, the Fleet page and the Events, Tours and Tour Leg pages, so
   they build with the same pieces rather than a copy of them. Anything that belongs to one page
   alone (the registration, the qualification line, a type card's pilot half) keeps its page's
   name. */

/* The detail hero: the airline's own image with the identity over it under a bottom shade,
   then the key facts. With no image it is the gradient header and nothing else - never a
   placeholder, never an icon, never a map. */
.detail-hero {
  border-radius: var(--radius-lg);
  border: 1px solid var(--border);
  background: var(--surface-1);
  overflow: hidden;
}
.detail-hero-media { position: relative; min-height: 9rem; }
.detail-hero-media img { display: block; width: 100%; height: 400px; object-fit: cover; }
.detail-hero-plain {
  background:
    radial-gradient(900px 300px at 15% 0%, var(--accent-soft), transparent 70%),
    var(--surface-1);
}
.detail-hero-plain .detail-hero-shade { display: none; }
.detail-hero-shade {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, transparent 45%, rgba(12, 13, 15, 0.88) 100%);
}
.detail-hero-ident {
  position: relative;
  display: flex;
  align-items: flex-end;
  gap: 24px;
  padding: 1.6rem 2rem;
}
.detail-hero-media:not(.detail-hero-plain) .detail-hero-ident {
  position: absolute;
  inset: auto 0 0 0;
}
.detail-hero-badges { display: flex; gap: 8px; margin-bottom: 12px; }
.detail-hero-body {
  padding: 1.4rem 2rem 1.5rem;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* Key facts: a small uppercase key over a value, and an optional quiet line under it. */
.kfacts { display: flex; flex-wrap: wrap; gap: 14px 38px; }
.kfact { min-width: 0; }
.kfact-key {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.kfact-value { font-size: 1.12rem; font-weight: 600; }
.kfact-sub { font-size: 0.78rem; color: var(--text-muted); }
.kfact-sub[hidden] { display: none; }

/* The pilot's status band: the page's own questions in halves split by a rule, and one action
   at the end. The halves share a band and never a sentence. */
.status-band {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 1px minmax(0, 1.25fr) auto;
  gap: 0 26px;
  align-items: stretch;
  padding: 1.25rem 1.5rem;
  border-radius: var(--radius-lg);
  border: 1px solid var(--accent-glow);
  background: linear-gradient(90deg, var(--accent-soft), transparent 60%, var(--surface-2));
}
.status-band[hidden] { display: none; }
.status-band-div { background: var(--border-strong); }
.status-band-half { min-width: 0; }
.status-band-key {
  margin: 0 0 6px;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--text-secondary);
}
.status-band-detail {
  margin: 6px 0 0;
  font-size: 0.9rem;
  color: var(--text-secondary);
}
.status-band-note { margin: 2px 0 0; font-size: 0.82rem; color: var(--text-muted); }
.status-band-note-line { margin: 2px 0 0; }
.status-band-action {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  justify-content: center;
  gap: 6px;
}
.status-band-action-note { font-size: 0.82rem; text-align: right; }

/* The thin progress bar: 4px, with its numbers in words beside it wherever it is used. No
   giant bars, and no gamification. */
.thin-bar {
  height: 4px;
  border-radius: 2px;
  background: var(--surface-3);
  overflow: hidden;
}
.thin-bar-fill {
  display: block;
  height: 4px;
  border-radius: 2px;
  background: var(--accent-bright);
}

/* State pills. Status is words plus shape, never colour alone: every pill carries its own
   state word. The tone names what the colour means, not which page uses it. */
.state-pill {
  font-size: 0.8rem;
  font-weight: 600;
  padding: 3px 12px;
  border-radius: 999px;
  white-space: nowrap;
  border: 1px solid var(--border-strong);
  background: var(--surface-3);
  color: var(--text-secondary);
}
.state-pill-success {
  color: var(--success);
  background: color-mix(in srgb, var(--success) 14%, transparent);
  border-color: color-mix(in srgb, var(--success) 40%, transparent);
}
.state-pill-warning {
  color: var(--warning);
  background: color-mix(in srgb, var(--warning) 14%, transparent);
  border-color: color-mix(in srgb, var(--warning) 45%, transparent);
}
.state-pill-info {
  color: var(--info);
  background: color-mix(in srgb, var(--info) 12%, transparent);
  border-color: color-mix(in srgb, var(--info) 40%, transparent);
}
/* A fallback rather than a fact (the airport profile's "assumed" shape): dashed and quiet. */
.state-pill-dashed {
  color: var(--text-muted);
  background: transparent;
  border: 1px dashed var(--border-strong);
}

/* The stat row: a few figures, each a value over its own word, never a row of tiles. */
.stat-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px; }
.stat-row-item { min-width: 0; }
.stat-row-empty { display: block; color: var(--text-secondary); }
.stat-row-value {
  font-size: 1.6rem;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
}
.stat-row-label { font-size: 0.82rem; color: var(--text-muted); }

/* The journey: a vertical chain of stops, oldest first, with the current one marked. */
.journey {
  display: grid;
  grid-template-columns: 18px minmax(0, 1fr);
  gap: 0 12px;
  font-size: 0.9rem;
}
.journey-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  border: 2px solid var(--text-muted);
  background: var(--surface-2);
  margin: 6px 0 0 3px;
}
.journey-dot-now {
  border-color: var(--success);
  background: var(--success);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--success) 18%, transparent);
}
.journey-line { width: 2px; background: var(--border-strong); margin-left: 7px; }
.journey-leg { font-size: 0.8rem; color: var(--text-muted); padding: 3px 0 9px; }
.journey-stop { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

/* The list card and its grid: a head (the airline's image, or a plain band) carrying the
   badges, then a body with the name and a few small facts. The card is not a link. */
.list-card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
  gap: 16px;
}
.list-card {
  display: flex;
  flex-direction: column;
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
  background: var(--surface-2);
  overflow: hidden;
  transition: border-color 0.15s ease, transform 0.15s ease;
}
/* The site's standard card lift (Fleet, Events and Tours cards alike). */
.list-card:hover { border-color: var(--border-strong); transform: translateY(-2px); }
@media (prefers-reduced-motion: reduce) {
  .list-card { transition: none; }
}
.list-card-head { position: relative; height: 104px; background: var(--surface-3); }
.list-card-head img { display: block; width: 100%; height: 100%; object-fit: cover; }
.list-card-head-plain {
  height: auto;
  background: transparent;
  border-bottom: 1px solid var(--border);
}
.list-card-shade {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(12, 13, 15, 0.55) 0%, transparent 55%);
}
.list-card-badges { display: flex; gap: 8px; padding: 12px 14px; }
.list-card-head:not(.list-card-head-plain) .list-card-badges { position: absolute; inset: auto auto 0 0; }
/* On a photograph, a badge needs its own ground. A badge over an image - a card head, or the
   banner of a detail page (an aircraft, a hub, a tour, an event) - sits where the shade has
   faded, and as a 16% tint it vanishes into a bright photo. Over a photo it is a dark glass chip
   with its own colour word, in both themes: the photo and its shade are the same whatever the
   page theme (the homepage hero figures' rule), so page tokens would put dark text on it in
   light. */
.list-card-head:not(.list-card-head-plain) .list-card-badges .badge {
  background-color: rgba(16, 17, 21, 0.78);
  color: #eceded;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.35);
  backdrop-filter: blur(4px);
}
.list-card-head:not(.list-card-head-plain) .list-card-badges .badge-info {
  color: #58a6ff;
  background-image: linear-gradient(rgba(88, 166, 255, 0.16), rgba(88, 166, 255, 0.16));
}
.list-card-head:not(.list-card-head-plain) .list-card-badges .badge-warning {
  color: #d9a13c;
  background-image: linear-gradient(rgba(217, 161, 60, 0.16), rgba(217, 161, 60, 0.16));
}
.list-card-head:not(.list-card-head-plain) .list-card-badges .badge-muted { color: #b4b6bc; }
.list-card-head:not(.list-card-head-plain) .list-card-badges .badge-accent {
  color: var(--accent-bright);
  background-image: linear-gradient(var(--accent-soft), var(--accent-soft));
}
/* The banner's own words, while they sit over the photograph (above 720px; on a phone they move
   under it onto the page): the photo's light-on-dark text in both themes, through the text tokens,
   so every line in the banner - title, name, place, type - follows without naming each one. The
   badges above set their own colours and are not affected. */
@media (min-width: 721px) {
  /* The banner's badges: the card heads' dark glass chips, only while they sit on the photo. */
  .detail-hero-media:not(.detail-hero-plain) .detail-hero-badges .badge {
    background-color: rgba(16, 17, 21, 0.78);
    color: #eceded;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.35);
    backdrop-filter: blur(4px);
  }
  .detail-hero-media:not(.detail-hero-plain) .detail-hero-badges .badge-info {
    color: #58a6ff;
    background-image: linear-gradient(rgba(88, 166, 255, 0.16), rgba(88, 166, 255, 0.16));
  }
  .detail-hero-media:not(.detail-hero-plain) .detail-hero-badges .badge-warning {
    color: #d9a13c;
    background-image: linear-gradient(rgba(217, 161, 60, 0.16), rgba(217, 161, 60, 0.16));
  }
  .detail-hero-media:not(.detail-hero-plain) .detail-hero-badges .badge-muted { color: #b4b6bc; }
  .detail-hero-media:not(.detail-hero-plain) .detail-hero-badges .badge-accent {
    color: var(--accent-bright);
    background-image: linear-gradient(var(--accent-soft), var(--accent-soft));
  }
  .detail-hero-media:not(.detail-hero-plain) .detail-hero-ident {
    --text-primary: #eceded;
    --text-secondary: #b4b6bc;
    --text-muted: #979aa1;
    color: var(--text-primary);
  }
}
.list-card-body {
  padding: 0.9rem 1.1rem 1.1rem;
  display: flex;
  flex-direction: column;
  gap: 14px;
  flex: 1;
}
.list-card-name { margin: 0; font-size: 1.08rem; }
.list-card-facts { display: flex; flex-wrap: wrap; gap: 10px 22px; }
.list-card-fact { min-width: 0; }
.list-card-fact-key {
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.list-card-fact-value { font-size: 0.95rem; font-weight: 600; }

/* Tablet: the status band stacks rather than squeezing four things into a row that cannot
   hold them. */
@media (max-width: 1024px) {
  .status-band { grid-template-columns: minmax(0, 1fr); gap: 18px; }
  .status-band-div { display: none; }
  .status-band-action { align-items: flex-start; }
  .status-band-action-note { text-align: left; }
}

/* Phone: the identity leaves the image and sits under it, and nothing is a squeezed grid. */
@media (max-width: 720px) {
  .detail-hero-media img { height: 220px; }
  .detail-hero-media:not(.detail-hero-plain) .detail-hero-ident { position: static; }
  .detail-hero-media:not(.detail-hero-plain) .detail-hero-shade { display: none; }
  .detail-hero-ident { flex-wrap: wrap; padding: 1.1rem 1.25rem; }
  .detail-hero-body { padding: 1.1rem 1.25rem 1.25rem; }
  .kfacts { gap: 12px 24px; }
  .stat-row { grid-template-columns: repeat(2, 1fr); gap: 14px; }
  .list-card-grid { grid-template-columns: minmax(0, 1fr); }
}

/* ---- the Fleet page ----
   The type, never the airframe: a card's qualification is about the type, so every airframe of
   it reads the same. Depth follows distance: bars only one rank away. */

.fleet-page { padding-bottom: 3rem; }
.fleet-section { padding: 2.25rem 0 0; }
.fleet-section-head { flex-wrap: wrap; }

/* 1 · the intro: the Statistics page's (.page-intro, with it below) - no card and no
   photograph; the aircraft are pictured just below it. */
.fleet-rank-line { margin: 12px 0 0; font-size: 0.9rem; color: var(--text-muted); }
.fleet-rank-line strong { color: var(--text-primary); font-weight: 600; }
.fleet-rank-line[hidden] { display: none; }

/* 2 · "Coming next": one band, not a card. The nearest locked type and what it asks. */
.fleet-next {
  display: flex;
  align-items: center;
  gap: 34px;
  margin-top: 18px;
  padding: 1rem 1.4rem;
  border-radius: var(--radius-md);
  border: 1px solid var(--accent-glow);
  background: var(--surface-2);
}
.fleet-next[hidden] { display: none; }
.fleet-next-who { flex-shrink: 0; }
.fleet-next-who h2 { margin: 0; }
.fleet-next-type {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 6px 0 0;
  font-size: 1.12rem;
  font-weight: 600;
}
.fleet-next-unlocks { margin: 2px 0 0; font-size: 0.88rem; color: var(--text-secondary); }
.fleet-next-unlocks strong { color: var(--text-primary); }
.fleet-next-also { margin: 2px 0 0; font-size: 0.82rem; }
.fleet-next-also[hidden] { display: none; }
.fleet-next-requirements {
  flex: 1;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  gap: 26px;
  min-width: 0;
}
.fleet-next-link { flex-shrink: 0; }

/* One requirement, shared by the band and the cards: its name, its figures, its OWN
   shortfall, and a thin bar. career-wording.js words it. */
.fleet-req {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 3px 10px;
  font-size: 0.84rem;
}
.fleet-req-label { color: var(--text-secondary); }
.fleet-req-figures {
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
  text-align: right;
}
.fleet-req .thin-bar { grid-column: 1 / -1; }
.fleet-req-remaining { grid-column: 1 / -1; color: var(--text-secondary); }
.fleet-req-met { grid-column: 1 / -1; color: var(--success); font-weight: 600; }

/* 3 · the type cards. */
.fleet-show { display: flex; align-items: center; gap: 10px; margin-left: auto; }
.fleet-show .muted { font-size: 0.82rem; }
/* Further off: the whole card is quieter. A bar at 46% is noise, not motivation. */
.fleet-type-far { background: transparent; }

.fleet-type-maker { font-size: 0.84rem; }

/* The pilot half of a card. WORDS always - the tick or the padlock is decoration. */
.fleet-type-status {
  margin-top: auto;
  padding-top: 12px;
  border-top: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.fleet-type-qualification {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font-size: 0.9rem;
}
.fleet-type-qualified .fleet-type-qualification { color: var(--success); }
.fleet-type-locked .fleet-type-qualification { color: var(--warning); }
.fleet-type-status .muted { margin: 0; font-size: 0.8rem; }
.fleet-type-remaining { font-size: 0.8rem; }
.fleet-type-foot { display: flex; flex-wrap: wrap; gap: 0.35rem; margin: 0; font-size: 0.8rem; }
.fleet-figure-sep { color: var(--text-muted); }

/* 4 · the aircraft list. Identity only: no state pills, no locations, no per-row loading. */
.fleet-filter { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.fleet-filter input[type="search"] { max-width: 28rem; }
.table-scroll { overflow-x: auto; }
.fleet-table-card { padding: 1.1rem 1.35rem 0.5rem; }
.fleet-table-card:hover { transform: none; border-color: var(--border); }
.fleet-table { width: 100%; border-collapse: collapse; font-size: 0.88rem; }
.fleet-table th {
  text-align: left;
  padding: 0 0.7rem 0.6rem;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--text-muted);
  white-space: nowrap;
}
.fleet-table td { padding: 0.6rem 0.7rem; border-top: 1px solid var(--border); vertical-align: middle; }
.fleet-table tr:first-child td { border-top: none; }
.fleet-aircraft-cell { display: flex; align-items: center; gap: 10px; }
.fleet-aircraft-cell .aircraft-link, .fleet-aircraft-cell .mono { white-space: nowrap; }
.fleet-thumb {
  width: 42px;
  height: 28px;
  flex-shrink: 0;
  border-radius: 5px;
  overflow: hidden;
  background: var(--surface-3);
  border: 1px solid var(--border);
}
.fleet-thumb img { display: block; width: 100%; height: 100%; object-fit: cover; }
/* No photograph is a quiet empty slot, never a placeholder graphic. */
.fleet-thumb-empty { background: var(--surface-1); }
.fleet-cell-type { margin-left: 0.5rem; }
.fleet-cell-hub { margin-left: 0.4rem; }
.fleet-cell-action { white-space: nowrap; text-align: right; }
/* The rows are dense; only the NAME column is allowed to wrap, because a name can be long. */
.fleet-table td { white-space: nowrap; }
.fleet-table td:nth-child(3) { white-space: normal; }
.fleet-you { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
.fleet-you-qualified { color: var(--success); }
.fleet-you-locked { color: var(--warning); }
.fleet-empty { padding: 1.25rem 0.7rem; color: var(--text-muted); }

/* Tablet: Coming next wraps rather than squeezing three things onto a row that cannot hold
   them. */
@media (max-width: 1024px) {
  .fleet-next { flex-wrap: wrap; gap: 16px; }
  .fleet-next-requirements { flex-basis: 100%; }
}

/* Phone: never a squeezed table - each aircraft becomes a card. */
@media (max-width: 720px) {
  .fleet-show { margin-left: 0; flex-basis: 100%; flex-wrap: wrap; }
  .fleet-table-card { padding: 0.9rem 1rem; }
  .fleet-table, .fleet-table tbody, .fleet-table tr, .fleet-table td { display: block; width: auto; }
  .fleet-table thead { display: none; }
  .fleet-table tr {
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 0.7rem 0.85rem;
    margin-bottom: 10px;
  }
  .fleet-table td { border-top: none; padding: 0.15rem 0; }
  .fleet-table td, .fleet-table td:nth-child(3) { white-space: normal; }
  .fleet-table tr:first-child td { border-top: none; }
  .fleet-cell-action { text-align: left; padding-top: 0.5rem; }
  /* 44 px touch targets on every control. */
  .fleet-filter .chip { min-height: 44px; }
  .fleet-cell-action .section-link { display: inline-block; min-height: 44px; line-height: 44px; }
}
/* ---- the Aircraft Profile ----
   The hero is the airline's own photograph, or the gradient header and nothing else - never a
   placeholder, never an icon, never a stock photo. */

.aircraft-page { padding-bottom: 3rem; }
.aircraft-back { margin: 1.25rem 0 0.9rem; }
#aircraft-body { display: flex; flex-direction: column; gap: 18px; }

/* 1 · the hero card (the shared .detail-hero): the photograph, the identity over it, then the
   key facts. The registration and the name are this page's own. */
.aircraft-ident-who { min-width: 0; }
.aircraft-reg {
  margin: 0;
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 3.75rem;
  line-height: 1;
  letter-spacing: 0.01em;
}
.aircraft-ident-name {
  margin-top: 8px;
  font-size: 1.55rem;
  font-weight: 600;
  letter-spacing: -0.01em;
}
.aircraft-ident-type { color: var(--text-secondary); font-size: 1rem; }
.aircraft-photo-count { margin-left: auto; background: rgba(12, 13, 15, 0.7); }

.aircraft-description { margin: 0; max-width: 64ch; color: var(--text-secondary); }

/* An airport beside its name: the shared link (or plain text), then a quiet name. */
.aircraft-airport { display: inline-flex; align-items: baseline; gap: 0.4rem; }
.aircraft-airport-name {
  font-weight: 400;
  font-size: 0.94rem;
  color: var(--text-secondary);
}

/* 2 · the pilot status band (the shared .status-band). Two questions, two halves, never
   merged - they share a band and never a sentence. */

/* The qualification half: a tick or a padlock, ALWAYS with the words beside it. */
.aircraft-q { display: flex; align-items: center; gap: 8px; margin: 0; font-size: 1.18rem; }
.aircraft-q strong { font-weight: 600; }
.aircraft-q-mark { font-size: 1.05rem; line-height: 1; }
.aircraft-q-ok { color: var(--success); }
.aircraft-q-lock { color: var(--warning); }

/* Compact progress: a thin bar with its numbers in words beside it. No giant bars, and no
   gamification - this is a requirement, not a game. */
.aircraft-req {
  display: grid;
  grid-template-columns: 6.5rem minmax(3rem, 1fr) auto auto;
  align-items: center;
  gap: 0 10px;
  margin-top: 8px;
  font-size: 0.82rem;
}
.aircraft-req-label { color: var(--text-secondary); }
.aircraft-req-figures { font-variant-numeric: tabular-nums; color: var(--text-secondary); }
.aircraft-req-left { color: var(--text-primary); font-weight: 600; }
.aircraft-req-met { color: var(--success); font-weight: 600; }
.aircraft-progress:not(:empty) { margin-top: 10px; }
.aircraft-remaining { margin: 10px 0 0; font-size: 0.85rem; color: var(--text-secondary); }
.aircraft-rank-link { margin-left: 0.4rem; }

/* The airframe half. Status is words plus shape, never colour alone: every pill carries its
   own state word, and an assumed location is dashed and says "assumed" out loud. */
.aircraft-state-line {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin: 0;
}
.aircraft-at { font-size: 1.18rem; }
/* An assumed location is framed as the fallback it is - dashed, quiet, and never dressed up as
   a fact the way a confirmed one is. */
.aircraft-assumed .aircraft-state-line,
.aircraft-assumed .status-band-detail,
.aircraft-assumed .status-band-note {
  padding-left: 12px;
}
.aircraft-assumed {
  border-left: 1px dashed var(--border-strong);
  margin-left: -12px;
  padding-left: 12px;
}
.aircraft-assumed .status-band-detail { font-weight: 600; color: var(--text-primary); }
.aircraft-assumed .status-band-note-line:last-child {
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px dashed var(--border-strong);
  color: var(--text-secondary);
}

/* 3 to 5 · history and operations lead; specifications, the journey and downloads support. */
.aircraft-columns {
  display: grid;
  grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr);
  gap: 18px;
  align-items: start;
}
.aircraft-column { display: flex; flex-direction: column; gap: 18px; }
.aircraft-panel { display: flex; flex-direction: column; }
.aircraft-panel:hover { transform: none; border-color: var(--border); }
.aircraft-panel-head {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 14px;
}
.aircraft-panel-aside { margin-left: auto; font-size: 0.82rem; }
.aircraft-seg { margin-left: auto; }
.aircraft-seg button { height: 32px; padding: 0 12px; font-size: 0.8rem; }

.aircraft-first-last {
  display: flex;
  gap: 26px;
  flex-wrap: wrap;
  margin: 16px 0 0;
  padding-top: 14px;
  border-top: 1px solid var(--border);
  font-size: 0.88rem;
  color: var(--text-secondary);
}
.aircraft-first-last-item { white-space: nowrap; }
.aircraft-first-last:empty { display: none; }

.aircraft-flight {
  display: grid;
  grid-template-columns: 5.25rem minmax(0, 1fr) auto;
  align-items: center;
  gap: 14px;
  padding: 10px 0;
  border-top: 1px solid var(--border);
  font-size: 0.9rem;
}
.aircraft-flight:first-child { border-top: none; padding-top: 0; }
.aircraft-flight-route { min-width: 0; }
.aircraft-flight-meta { margin-left: 0.6rem; font-size: 0.8rem; color: var(--text-muted); }
.aircraft-flight-when {
  display: flex;
  gap: 0.7rem;
  align-items: baseline;
  white-space: nowrap;
  font-size: 0.8rem;
  color: var(--text-muted);
}

.aircraft-specs {
  display: grid;
  grid-template-columns: 9rem minmax(0, 1fr);
  gap: 7px 14px;
  margin: 0;
  font-size: 0.9rem;
}
.aircraft-specs dt { color: var(--text-muted); }
.aircraft-specs dd { margin: 0; }
.aircraft-spec-code { margin-left: 0.35rem; }

.aircraft-download { display: flex; align-items: center; gap: 14px; }
.aircraft-livery-name { font-weight: 600; }
.aircraft-download-sub { font-size: 0.8rem; }
/* The label and its arrow are one thing: wrapped, the arrow would sit alone on a second line and
   the button would read as broken. It never shrinks - the sentence beside it wraps. */
.aircraft-download .btn { margin-left: auto; white-space: nowrap; flex-shrink: 0; }

/* 6 · the gallery. Restrained: the aircraft stays the subject. */
.aircraft-gallery { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
.aircraft-thumb {
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  overflow: hidden;
  background: var(--surface-3);
  cursor: pointer;
}
.aircraft-thumb img { display: block; width: 100%; height: 150px; object-fit: cover; }
.aircraft-thumb:hover { border-color: var(--border-strong); }
.aircraft-thumb:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 2px; }
.aircraft-gallery-note { margin: 12px 0 0; font-size: 0.8rem; }

/* The lightbox fills the viewport over a near-black dim, and the photograph sits centred with
   its caption and counter beneath it. The dialog itself is the whole screen and transparent, so
   the three buttons can sit at the screen's edges. */
.aircraft-lightbox {
  width: 100vw;
  height: 100vh;
  max-width: none;
  max-height: none;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--text-primary);
}
.aircraft-lightbox[open] { display: flex; align-items: center; justify-content: center; }
.aircraft-lightbox::backdrop { background: rgba(6, 7, 9, 0.9); }
.aircraft-lightbox-stage {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 14px;
  /* Clear of the side buttons: 48px each plus their gutter. */
  max-width: min(900px, calc(100vw - 176px));
}
.aircraft-lightbox-stage img {
  display: block;
  width: 100%;
  max-height: calc(100vh - 160px);
  object-fit: contain;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
}
.aircraft-lightbox-bar { display: flex; align-items: baseline; gap: 16px; font-size: 0.97rem; }
.aircraft-lightbox-count { margin-left: auto; font-size: 0.875rem; font-variant-numeric: tabular-nums; white-space: nowrap; }
/* 48px round buttons, named "Previous photo", "Next photo", "Close photos". */
.aircraft-lightbox-btn {
  position: fixed;
  width: 48px;
  height: 48px;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  border: 1px solid var(--border-strong);
  background: color-mix(in srgb, var(--surface-2) 92%, transparent);
  color: var(--text-primary);
  cursor: pointer;
}
.aircraft-lightbox-btn:hover { border-color: var(--text-muted); }
/* 2px accent outline, 2px offset, on every control. */
.aircraft-lightbox-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.aircraft-lightbox-btn[hidden] { display: none; }
.aircraft-lightbox-prev { left: 44px; top: 50%; transform: translateY(-50%); }
.aircraft-lightbox-next { right: 44px; top: 50%; transform: translateY(-50%); }
.aircraft-lightbox-close { right: 44px; top: 24px; }
/* The page behind does not scroll while the dialog is open. */
body.aircraft-lightbox-open { overflow: hidden; }
/* On a phone the photograph needs the width, so Previous and Next move under it, either side
   of the caption bar; they stay 48px, over the 44px touch minimum. */
@media (max-width: 640px) {
  .aircraft-lightbox-stage { max-width: calc(100vw - 32px); padding-bottom: 72px; }
  .aircraft-lightbox-prev, .aircraft-lightbox-next { top: auto; bottom: 20px; transform: none; }
  .aircraft-lightbox-prev { left: 16px; }
  .aircraft-lightbox-next { right: 16px; }
  .aircraft-lightbox-close { right: 16px; top: 16px; }
}

/* Tablet: the two columns become one, and the status band stacks rather than squeezing four
   things into a row that cannot hold them. */
@media (max-width: 1024px) {
  .aircraft-columns { grid-template-columns: minmax(0, 1fr); }
  .aircraft-gallery { grid-template-columns: repeat(3, 1fr); }
}

/* Phone: identity/image, qualification, location/state, specifications, activity, gallery,
   downloads - and never a squeezed grid. */
@media (max-width: 720px) {
  .aircraft-photo-count { margin-left: 0; }
  .aircraft-reg { font-size: 2.4rem; }
  .aircraft-ident-name { font-size: 1.2rem; }
  .aircraft-flight { grid-template-columns: minmax(0, 1fr); gap: 4px; }
  .aircraft-flight-meta { display: block; margin-left: 0; }
  .aircraft-specs { grid-template-columns: minmax(0, 1fr); gap: 2px; }
  .aircraft-specs dd { margin-bottom: 8px; }
  .aircraft-gallery { grid-template-columns: repeat(2, 1fr); }
  .aircraft-req { grid-template-columns: minmax(0, 1fr) auto; }
  .aircraft-req .thin-bar { grid-column: 1 / -1; margin: 4px 0; }
  /* The period control gets its own row rather than squeezing beside the title. */
  .aircraft-panel-head { flex-wrap: wrap; }
  .aircraft-seg { margin-left: 0; flex-basis: 100%; }
  .aircraft-seg button { flex: 1; }
  /* 44 px touch targets on every control. */
  .aircraft-seg button { min-height: 44px; }
  .aircraft-thumb img { height: 120px; }
}

@media (prefers-reduced-motion: reduce) {
  .aircraft-thumb, .aircraft-panel { transition: none; }
}

/* A visitor's one quiet line where the status band would be. */
.aircraft-signin {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0;
  padding: 0.85rem 1.25rem;
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
  background: var(--surface-2);
  font-size: 0.9rem;
  color: var(--text-secondary);
}
.aircraft-signin[hidden] { display: none; }
.aircraft-signin strong { color: var(--text-primary); font-weight: 600; }
.aircraft-signin .btn { margin-left: auto; white-space: nowrap; }

@media (max-width: 720px) {
  .aircraft-signin { flex-wrap: wrap; }
  .aircraft-signin .btn { margin-left: 0; }
}

/* A retired profile: historical, and never dressed up as an operational page. */
.aircraft-retired-note { margin-top: 6px; font-size: 0.88rem; color: var(--text-muted); }
.aircraft-retired-note[hidden] { display: none; }
.aircraft-retired-line {
  margin: 0;
  padding: 0.85rem 1.25rem;
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
  background: var(--surface-2);
  font-size: 0.9rem;
  color: var(--text-secondary);
}
.aircraft-retired-line[hidden] { display: none; }

/* The live-map sidebar's aircraft. The airline's own Primary image leads the sidebar; with no
   image there is no image area and no placeholder, and nothing below moves. */
.live-side-photo {
  margin: -2px -2px 10px;
  border-radius: var(--radius-sm);
  overflow: hidden;
  aspect-ratio: 16 / 9;
  background: var(--surface-3);
}
.live-side-photo img { display: block; width: 100%; height: 100%; object-fit: cover; }
.live-side-factsub { font-size: 0.78rem; color: var(--text-muted); }
/* The aircraft's link. Focus and Follow stay actions on the map, so this sits on its own row. */
.live-action-link { text-decoration: none; text-align: center; }

/* The Connected accounts card. One row per service: a mark, the service and its state, and the
   one action. The action drops under the text on a phone rather than squeezing beside it, as a
   full-width button at 44px. */
.acct-row {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px 0;
  border-top: 1px solid var(--border);
}
/* The first row in a card sits under the card's own heading, so it needs no rule above it. */
.acct-row:first-of-type { border-top: 0; padding-top: 0; }
.acct-row-body { flex: 1; min-width: 0; }
.acct-row-state { font-size: 0.93rem; }
.acct-row-since { color: var(--text-muted); }
/* The service's mark: Discord's own blurple where the account is not linked yet, and the pilot's
   Discord initial once it is - vaBase never FETCHES the avatar, so an unreachable picture leaves
   the initial rather than a broken image. */
.acct-mark {
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: #ffffff;
  font-weight: 800;
  background: #5865f2;
  overflow: hidden;
}
.acct-mark img { width: 100%; height: 100%; object-fit: cover; }
.acct-mark-pending { opacity: 0.6; }
.acct-row-actions { display: flex; flex-wrap: wrap; gap: 8px; }
@media (max-width: 560px) {
  .acct-row { flex-wrap: wrap; }
  .acct-row-actions { width: 100%; }
  .acct-row-actions .btn { flex: 1; justify-content: center; min-height: 44px; }
}

/* ---- Events, Tours and Tour Legs ----
   Built on the shared page primitives (detail hero, key facts, status band, thin bar, state
   pills, stat row, journey, list card); only what those pages alone need is here. */

/* Conditions inside an airport panel: the figures, then one observed line - amber and worded
   when stale - or one quiet line when there is no report. */
.act-wx { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--border); }
.act-wx-figs { display: flex; flex-wrap: wrap; gap: 10px 30px; }
.act-wx-figs .kfact-key { font-size: 0.69rem; }
.act-wx-figs .kfact-value { font-size: 0.97rem; white-space: nowrap; font-variant-numeric: tabular-nums; }
.act-wx-obs { margin: 6px 0 0; font-size: 0.78rem; color: var(--text-muted); }
.act-wx-obs.is-stale { color: var(--warning); }
.act-wx-none { margin: 0; font-size: 0.88rem; color: var(--text-secondary); }
/* While loading, the panel keeps its shape: two lines of skeleton where the figures will be. */
.act-wx-skel { height: 14px; margin: 0 0 8px; max-width: 70%; }
.act-wx-skel-short { max-width: 40%; }

/* The route map: a content section, never a hero. It rides .route-map for the dark popup and
   attribution chrome, and sets its own height (MapLibre needs a laid-out box). */
.act-map {
  height: 360px;
  margin-top: 0;
  background: linear-gradient(180deg, #10151c, #0d1117);
}
.act-map-event { height: 300px; }
.act-map:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 2px; }
.act-map-fallback {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  padding: 12px 14px;
  border-radius: var(--radius-sm);
  border: 1px dashed var(--border-strong);
  font-size: 0.84rem;
  color: var(--text-muted);
}
.act-map-fallback[hidden] { display: none; }
.act-map-fallback .icon { width: 18px; height: 18px; flex-shrink: 0; }
/* The airport code under its dot. A button, so a click (or Enter from the map's own keys) opens
   the airport's card; it keeps the map's concrete dark colours in both themes. */
.activity-map-label {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: #f0ecff;
  background: rgba(20, 20, 26, 0.85);
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 6px;
  padding: 1px 5px;
  white-space: nowrap;
  cursor: pointer;
}
.activity-map-label:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 2px; }
.act-map-popup { display: flex; flex-direction: column; gap: 2px; color: #eceded; font-size: 0.84rem; }
.act-map-popup-head { display: flex; align-items: baseline; gap: 8px; }
.act-map-popup-code { font-weight: 700; }
.act-map-popup-detail { font-size: 0.76rem; color: #979aa1; }
.act-map-popup-link { margin-top: 2px; font-size: 0.8rem; font-weight: 600; }

@media (max-width: 720px) {
  .act-map { height: 240px; }
}

/* The page head: a title, one line, and one strip of quiet figures - a figure that would be zero
   is absent. */
.act-page { padding-bottom: 3rem; }
.act-head { display: flex; align-items: flex-end; gap: 24px; flex-wrap: wrap; padding-top: var(--page-top); }
.act-title { margin: 0; font-size: var(--page-title-size); font-weight: 700; letter-spacing: -0.02em; line-height: 1.1; }
.act-lede { margin: 8px 0 0; font-size: 1.03rem; color: var(--text-secondary); }
.act-figs { display: flex; align-items: baseline; flex-wrap: wrap; margin: 0 0 0 auto; padding: 0; list-style: none; font-size: 0.91rem; color: var(--text-secondary); }
.act-figs li { padding: 0 22px; border-left: 1px solid var(--border-strong); white-space: nowrap; }
.act-figs li:first-child { padding-left: 0; border-left: none; }
.act-figs strong { margin-right: 7px; font-size: 1.38rem; font-weight: 600; color: var(--text-primary); font-variant-numeric: tabular-nums; }
.act-groups { display: flex; flex-direction: column; gap: 18px; margin-top: 18px; }
.act-group-head { display: flex; align-items: baseline; gap: 12px; margin-top: 10px; }
.act-group-head h2 { margin: 0; font-size: 1.38rem; font-weight: 600; letter-spacing: -0.01em; }
.act-group-head span { font-size: 0.88rem; color: var(--text-muted); }

/* State pills beyond the airframe tones: "Live now" carries a dot so it is never colour alone,
   "Next" and "In progress" are the accent, and the large size sits on a hero. */
.state-pill-live::before {
  content: "";
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: currentColor;
  margin-right: 6px;
  vertical-align: 1px;
}
.state-pill-accent {
  color: var(--accent-bright);
  background: var(--accent-soft);
  border-color: var(--accent-glow);
}
.state-pill-lg { font-size: 0.84rem; padding: 3px 12px; }

/* The list card (the Fleet type card) as the events and tours lists draw it: a taller head with
   the pill at its foot, the airline's artwork under a bottom shade, or the gradient head alone.
   Three to a row, then two, then one. */
.act-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 18px; }
.act-card-head { height: 120px; flex-shrink: 0; overflow: hidden; }
.act-card-head-plain {
  background:
    radial-gradient(420px 140px at 12% 0%, var(--accent-soft), transparent 72%),
    var(--surface-1);
  border-bottom: 1px solid var(--border);
}
.act-card-shade {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, transparent 38%, rgba(12, 13, 15, 0.82) 100%);
}
/* Out-specifies the list card's own corner placement: the pill sits 18px in, 12px up. */
.list-card-head.act-card-head .list-card-badges { position: absolute; inset: auto auto 12px 18px; padding: 0; z-index: 1; }
.act-card-past { background: transparent; }
.act-card-past:hover { border-color: var(--border); }
.act-card-where { margin-top: 2px; font-size: 0.91rem; color: var(--text-secondary); }
.act-card-where .muted { font-size: 0.91rem; }
.act-card-when { font-size: 0.94rem; }
.act-card-when strong { font-weight: 600; }
.act-card-when .muted { font-size: 0.84rem; }
.act-card-foot {
  margin-top: auto;
  padding-top: 12px;
  border-top: 1px solid var(--border);
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 36px;
  font-size: 0.84rem;
}
.act-card-foot .btn { margin-left: auto; white-space: nowrap; }
/* The wide card for the one thing that matters now (happening now, the tour you are on). */
.act-feature {
  display: grid;
  grid-template-columns: 460px minmax(0, 1fr);
  border-radius: var(--radius-lg);
  border: 1px solid var(--accent-glow);
  background: linear-gradient(90deg, color-mix(in srgb, var(--accent) 10%, transparent), transparent 70%), var(--surface-2);
  overflow: hidden;
}
.act-feature:hover { border-color: var(--accent-glow); }
.act-feature .act-card-head { height: auto; min-height: 236px; }
.act-feature .list-card-body { padding: 1.5rem 1.75rem; gap: 14px; }
.act-feature .list-card-name { font-size: 1.62rem; letter-spacing: -0.015em; }
.act-feature .list-card-facts { gap: 12px 38px; }
.act-feature .act-card-when { font-size: 1.06rem; }
.act-feature .act-card-foot .btn { padding: 12px 22px; font-size: 1rem; }
/* The pilot's own state on a card: the only colour on it is about them. */
.act-own { display: inline-flex; align-items: center; gap: 6px; font-weight: 600; }
.act-own .icon { width: 15px; height: 15px; }
.act-own-ok { color: var(--success); }
.act-own-warn { color: var(--warning); }
.act-own-muted { color: var(--text-muted); font-weight: 400; }

/* An empty state with a way out - the template's .fd-empty. */
.act-empty-actions { display: flex; gap: 10px; margin-top: 8px; }

/* The detail hero (the Aircraft hero): the title takes the registration's place. */
.act-hero .detail-hero-media img { height: 340px; }
.act-hero .detail-hero-plain { border-bottom: 1px solid var(--border); }
.act-hero .detail-hero-plain .detail-hero-ident { padding: 2.5rem 2rem 1.9rem; }
.act-hero-title { margin: 0; font-size: 3rem; font-weight: 700; letter-spacing: -0.02em; line-height: 1.05; }
.act-hero-sub { margin-top: 8px; font-size: 1.06rem; color: var(--text-secondary); }
.act-hero-sub .mono { font-weight: 700; color: var(--text-primary); }
.act-back { margin: 1.4rem 0 1.1rem; font-size: 0.91rem; }
.act-body { display: flex; flex-direction: column; gap: 18px; }
.act-kfact-code { font-weight: 400; font-size: 0.94rem; color: var(--text-secondary); }

/* The status band as these pages use it: one half beside the action, or two halves. Its title
   is words and a mark - a tick, a padlock - never colour alone. */
.status-band-single { grid-template-columns: minmax(0, 1fr) auto; }
.act-band-title { display: flex; align-items: center; gap: 8px; margin: 0; font-size: 1.18rem; font-weight: 600; }
.act-band-title .icon { width: 18px; height: 18px; }
.act-band-ok { color: var(--success); }
.act-band-warn { color: var(--warning); }
.act-band-line { margin: 6px 0 0; font-size: 0.91rem; color: var(--text-secondary); }
.act-band-line strong { color: var(--text-primary); font-weight: 600; }
.act-band-note { margin: 2px 0 0; font-size: 0.81rem; color: var(--text-muted); }
.act-band-lead { margin: 0; font-size: 1.18rem; }
.act-band-actions { display: flex; gap: 10px; align-items: center; }
.act-band-skel { height: 16px; margin: 6px 0 0; max-width: 60%; }
/* The quiet text action (Withdraw, Leave tour): never a button beside the primary one. */
.act-quiet {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  font-size: 0.84rem;
  color: var(--text-muted);
  border-bottom: 1px dotted var(--border-strong);
  cursor: pointer;
}
.act-quiet:hover { color: var(--text-secondary); }
.act-quiet:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 3px; border-radius: 2px; }
.act-refusal { margin: 10px 0 0; }

/* The page's columns: what supports the decision on the left, conditions and the map on the
   right; on a phone one column, in reading order. */
.act-columns {
  display: grid;
  grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr);
  grid-template-areas: "summary side" "about side" "counts side" "people side";
  grid-template-rows: auto auto auto 1fr;
  gap: 18px;
  align-items: start;
}
.act-area-summary { grid-area: summary; }
.act-area-about { grid-area: about; }
.act-area-counts { grid-area: counts; }
.act-area-people { grid-area: people; }
.act-area-side { grid-area: side; display: flex; flex-direction: column; gap: 18px; }
.act-panel { display: flex; flex-direction: column; }
.act-panel:hover { transform: none; border-color: var(--border); }
.act-panel-head { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; }
.act-panel-head h2 { margin: 0; }
.act-panel-aside { margin-left: auto; font-size: 0.81rem; color: var(--text-muted); }
.act-panel-foot { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border); font-size: 0.84rem; }
.act-panel-foot a { font-weight: 600; }
.act-stats { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.act-prose { font-size: 0.97rem; color: var(--text-secondary); max-width: 680px; line-height: 1.6; }

/* "What counts": the rule's name, then the rule in words. */
.act-rules { display: grid; grid-template-columns: 170px minmax(0, 1fr); margin: 0; font-size: 0.91rem; }
.act-rules dt { color: var(--text-muted); padding: 10px 0; border-top: 1px solid var(--border); }
.act-rules dd { margin: 0; padding: 10px 0; border-top: 1px solid var(--border); }
.act-rules dt:first-of-type, .act-rules dt:first-of-type + dd { border-top: none; padding-top: 0; }
.act-rules .act-own { margin-left: 8px; font-size: 0.84rem; }
.act-rule-note { font-size: 0.81rem; color: var(--text-muted); }

/* People (the pilot identity primitive in the Aircraft activity row). */
.act-person {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr) auto;
  align-items: center;
  gap: 14px;
  padding: 10px 0;
  border-top: 1px solid var(--border);
  font-size: 0.91rem;
}
.act-person:first-child { border-top: none; padding-top: 0; }
.act-person-sub { font-size: 0.78rem; color: var(--text-muted); }
.act-person-flight strong { font-weight: 600; }
.act-person-you { font-weight: 400; color: var(--text-muted); }
.act-people-more { padding-top: 12px; border-top: 1px solid var(--border); font-size: 0.84rem; }
.act-people-more button { background: none; border: none; padding: 0; font: inherit; font-weight: 600; color: var(--accent-bright); cursor: pointer; }
.act-view { font-size: 0.84rem; font-weight: 600; white-space: nowrap; }

/* Conditions for one airport, compact (an event's "Current conditions"). */
.act-station-head { display: flex; align-items: center; gap: 10px; font-size: 0.94rem; }
.act-station-name { color: var(--text-secondary); }
.act-station .act-wx { margin-top: 8px; padding-top: 0; border-top: none; }
.act-station .act-wx-figs { gap: 10px 22px; }
.act-station + .act-station { margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--border); }

/* The confirmation (Leave tour, Withdraw): the safe choice is the default. */
.confirm-panel { padding: 26px 28px 22px; }
.confirm-title { margin: 0 0 10px; font-size: 1.25rem; letter-spacing: -0.01em; }
.confirm-points { margin: 0 0 18px; padding-left: 20px; color: var(--text-secondary); font-size: 0.91rem; }
.confirm-points li { margin-bottom: 6px; }
.confirm-actions { display: flex; justify-content: flex-end; gap: 10px; }
.btn-destructive { color: var(--danger); border: 1px solid color-mix(in srgb, var(--danger) 50%, transparent); background: transparent; }
.btn-destructive:hover { background: color-mix(in srgb, var(--danger) 10%, transparent); }
.btn-safe { color: var(--text-primary); border: 1px solid var(--border-strong); background: var(--surface-2); }
.btn-safe:hover { border-color: var(--text-muted); }

@media (max-width: 1024px) {
  .act-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .act-feature { grid-template-columns: minmax(0, 1fr); }
  /* The single-half band stacks too: it is declared after the shared tablet rule. */
  .status-band-single { grid-template-columns: minmax(0, 1fr); gap: 18px; }
  .act-feature .act-card-head { min-height: 180px; }
  .act-columns {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "summary" "about" "counts" "side" "people";
    grid-template-rows: none;
  }
}

@media (max-width: 720px) {
  /* One quiet line on a phone: "1 happening now · 2 upcoming". */
  .act-figs { margin: 4px 0 0; font-size: 0.84rem; color: var(--text-muted); }
  .act-figs li { padding: 0; border-left: none; }
  .act-figs li + li::before { content: "·"; margin: 0 6px; }
  .act-figs strong { margin-right: 4px; font-size: inherit; font-weight: 400; color: inherit; }
  .act-grid { grid-template-columns: minmax(0, 1fr); }
  .act-group-head h2 { font-size: 1.12rem; }
  .act-feature .list-card-body { padding: 1rem 1.1rem 1.1rem; }
  .act-feature .list-card-name { font-size: 1.12rem; }
  .act-feature .list-card-facts { gap: 10px 22px; }
  .act-card-foot { flex-wrap: wrap; }
  .act-card-foot .btn, .act-feature .act-card-foot .btn { margin-left: 0; flex-basis: 100%; justify-content: center; min-height: 44px; }
  .act-hero .detail-hero-media img { height: 220px; }
  .act-hero .detail-hero-plain .detail-hero-ident { padding: 1.4rem 1rem 1rem; }
  .act-hero-title { font-size: 1.88rem; }
  .act-hero-sub { font-size: 0.91rem; margin-top: 5px; }
  /* Scoped to these pages: the band is shared with the Aircraft Profile, which must not change. */
  .act-page .status-band-action .btn { width: 100%; justify-content: center; min-height: 44px; }
  .act-band-actions { flex-direction: column-reverse; align-items: stretch; width: 100%; }
  .act-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .act-rules { grid-template-columns: minmax(0, 1fr); }
  .act-rules dd { padding-top: 0; border-top: none; }
  .act-person { grid-template-columns: minmax(0, 1fr); gap: 6px; }
  .act-panel-head { flex-wrap: wrap; }
  .act-panel-aside { margin-left: 0; flex-basis: 100%; }
  .act-quiet { padding: 12px 0; }
  /* 44 px touch targets: the small buttons and the roster's Show all. */
  .act-page .btn-sm { min-height: 44px; }
  .act-people-more button { min-height: 44px; }
  .confirm-actions { flex-direction: column-reverse; }
  .confirm-actions .btn { justify-content: center; min-height: 44px; }
}

/* ---- Tours ---- */

/* A progress figure with its thin bar beneath (cards, the band, the roster). */
.act-progress { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 1px 10px; align-items: baseline; font-size: 0.84rem; }
.act-progress .thin-bar { grid-column: 1 / -1; margin-top: 5px; }
.act-progress-figure { font-variant-numeric: tabular-nums; font-weight: 600; color: var(--text-primary); white-space: nowrap; }
.act-progress-lg { font-size: 0.94rem; }
.act-progress-lg .thin-bar, .act-progress-lg .thin-bar-fill { height: 6px; border-radius: 3px; }
.thin-bar-done .thin-bar-fill { background: var(--success); }
.thin-bar-muted .thin-bar-fill { background: var(--text-muted); }
.act-card-line { font-size: 0.88rem; color: var(--text-secondary); }
.act-card-line strong { color: var(--text-primary); font-weight: 600; }
.act-next-line { display: flex; align-items: center; flex-wrap: wrap; gap: 4px; font-size: 1rem; }
.act-next-key { margin-right: 8px; font-size: 0.75rem; font-weight: 600; letter-spacing: 0.07em; text-transform: uppercase; color: var(--text-muted); }
.act-next-line .muted { font-size: 0.91rem; }
/* The leg's number as a small mark ("03"), accent-framed: the next leg. */
.act-legno {
  margin-right: 10px;
  padding: 0 7px;
  border: 1px solid var(--accent-glow);
  border-radius: 6px;
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 0.94rem;
  color: var(--accent-bright);
}

/* The progress band: its big figure, its bar and the next leg beside it. */
.act-band-figure { margin: 0; font-size: 1.38rem; font-weight: 700; letter-spacing: -0.01em; }
.act-band-bar { max-width: 340px; margin: 10px 0 8px; }
.act-band-bar, .act-band-bar .thin-bar-fill { height: 6px; border-radius: 3px; }
.act-band-route { display: flex; align-items: center; flex-wrap: wrap; margin: 0; font-size: 1.38rem; font-weight: 700; }
.act-band-stack { display: flex; flex-direction: column; align-items: stretch; justify-content: center; gap: 8px; }
.act-band-stack .btn { justify-content: center; }
/* The band and the conditions strip are ONE object: a shared edge, no heading between. */
.status-band-joined { border-radius: var(--radius-lg) var(--radius-lg) 0 0; }
.act-cond {
  display: grid;
  grid-template-columns: 170px minmax(0, 1fr) 40px minmax(0, 1fr);
  gap: 0 22px;
  align-items: center;
  margin-top: -18px;
  padding: 16px 24px 18px;
  border: 1px solid var(--accent-glow);
  border-top: 1px solid var(--border);
  border-radius: 0 0 var(--radius-lg) var(--radius-lg);
  background: var(--surface-1);
}
.act-cond-caption { font-size: 0.78rem; line-height: 1.45; color: var(--text-muted); }
.act-cond-arrow { color: var(--text-muted); text-align: center; font-size: 1.25rem; }
.act-cond .act-wx { margin-top: 8px; padding-top: 0; border-top: none; }
.act-cond .act-wx-figs { gap: 10px 22px; }
.act-cond-none { margin: 8px 0 0; font-size: 0.84rem; color: var(--text-muted); }
.act-cond-compact { display: none; margin: 4px 0 0; font-size: 0.84rem; color: var(--text-secondary); }

/* The route map's legend: flown, next and to fly - told apart by more than colour (the next
   line is thicker, the to-fly line is dashed on the map). */
.act-legend { display: flex; gap: 18px; margin-left: auto; font-size: 0.81rem; color: var(--text-secondary); }
.act-legend i { display: inline-block; width: 18px; height: 3px; border-radius: 2px; margin-right: 6px; vertical-align: 3px; }
.act-legend-flown { background: var(--success); }
.act-legend-next { background: var(--accent-bright); height: 4px; }
.act-legend-tofly { background: var(--text-muted); }

/* About and the tour's figures, side by side in one panel. */
.act-split { display: grid; grid-template-columns: minmax(0, 1fr) 1px minmax(0, 1.1fr); gap: 0 28px; }
.act-split-rule { background: var(--border); }
.act-figures-line { display: flex; flex-wrap: wrap; gap: 8px 26px; margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--border); font-size: 0.88rem; color: var(--text-secondary); }
.act-figures-line strong { color: var(--text-primary); font-weight: 600; }
.act-columns-tour { grid-template-areas: "journey people"; grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr); grid-template-rows: none; }
.act-area-journey { grid-area: journey; }

/* The journey (the Aircraft chain): a numbered node per leg. Tick = flown, filled = next,
   ring = to fly, padlock = locked - shape first, colour second. */
.act-journey { display: grid; grid-template-columns: 34px minmax(0, 1fr) auto; gap: 0 14px; font-size: 0.91rem; }
.act-node {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  border: 2px solid var(--border-strong);
  background: var(--surface-2);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 0.78rem;
  color: var(--text-secondary);
}
.act-node .icon { width: 14px; height: 14px; }
.act-node-done { border-color: color-mix(in srgb, var(--success) 60%, transparent); color: var(--success); }
.act-node-next { border-color: var(--accent-bright); background: var(--accent); color: var(--text-on-accent); box-shadow: 0 0 0 4px var(--accent-soft); }
.act-node-lock { border-style: dashed; color: var(--text-muted); }
.act-link { width: 2px; min-height: 18px; margin-left: 14px; background: var(--border-strong); }
.act-link-done { background: color-mix(in srgb, var(--success) 45%, transparent); }
.act-leg { padding: 2px 0 4px; }
.act-leg-route { font-size: 1.06rem; font-weight: 600; }
.act-leg-route .state-pill { margin-left: 8px; vertical-align: 2px; }
.act-leg-names { font-size: 0.91rem; color: var(--text-secondary); }
.act-leg-sub { font-size: 0.84rem; color: var(--text-muted); }
.act-leg-locked .act-leg-route { font-weight: 500; color: var(--text-muted); }
.act-leg-actions { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; font-size: 0.84rem; text-align: right; }
.act-leg-actions-row { flex-direction: row; align-items: center; gap: 8px; }

/* Pilots on the tour: the filter chips, then the groups - placed finishers apart from pilots
   still flying, who carry a bar and never a place. */
.act-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 16px; }
.act-subhead { display: flex; align-items: baseline; gap: 10px; margin: 16px 0 10px; font-size: 0.75rem; font-weight: 600; letter-spacing: 0.07em; text-transform: uppercase; color: var(--text-muted); }
.act-subhead:first-child { margin-top: 0; }
.act-subhead span { text-transform: none; letter-spacing: 0; font-weight: 400; font-size: 0.78rem; }
.act-roster-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 12px; padding: 10px 0; border-top: 1px solid var(--border); font-size: 0.91rem; }
.act-roster-row:first-of-type { border-top: none; }
.act-roster-row-progress { grid-template-columns: minmax(0, 1fr) 130px; }
.act-roster-who { display: flex; align-items: center; gap: 10px; min-width: 0; }
.act-place { width: 18px; flex-shrink: 0; text-align: right; font-family: var(--font-mono); font-weight: 700; font-size: 0.88rem; color: var(--text-secondary); }
.act-roster-days { font-size: 0.88rem; color: var(--text-secondary); white-space: nowrap; }

@media (max-width: 1024px) {
  .act-columns-tour { grid-template-columns: minmax(0, 1fr); grid-template-areas: "journey" "people"; }
  .act-cond { grid-template-columns: minmax(0, 1fr); gap: 12px; }
  .act-cond-arrow { display: none; }
  .act-split { grid-template-columns: minmax(0, 1fr); gap: 18px; }
  .act-split-rule { display: none; }
}

@media (max-width: 720px) {
  .act-cond { margin-top: -12px; padding: 14px 16px; }
  .act-band-route, .act-band-figure { font-size: 1.12rem; }
  .act-journey { grid-template-columns: 34px minmax(0, 1fr); }
  .act-link-pad { display: none; }
  .act-cond .act-wx { display: none; }
  .act-cond-compact { display: block; }
  .act-leg-actions { grid-column: 2; flex-direction: row; flex-wrap: wrap; align-items: center; justify-content: flex-start; gap: 10px 14px; padding-bottom: 6px; text-align: left; }
  .act-leg-actions .btn { min-height: 44px; flex: 1; justify-content: center; }
  .act-legend { margin-left: 0; flex-basis: 100%; }
  .act-roster-row-progress { grid-template-columns: minmax(0, 1fr); }
  .act-chips .chip { min-height: 44px; }
}

/* ---- Tour legs ---- */

/* The hero: always the gradient header (a leg has no artwork), with the route as the headline. */
.act-eyebrow { font-size: 0.78rem; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-secondary); }
.act-eyebrow a { color: inherit; border-bottom: 1px dotted var(--border-strong); }
.act-hero-row { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; margin-bottom: 14px; }
.act-route { display: flex; align-items: center; gap: 22px; margin-top: 18px; }
.act-route-code { font-family: var(--font-mono); font-weight: 700; font-size: 2.12rem; line-height: 1; }
.act-route-name { margin-top: 5px; font-size: 0.94rem; color: var(--text-secondary); }
.act-route-arrow { position: relative; flex: 0 0 120px; height: 2px; background: linear-gradient(90deg, var(--border-strong), var(--accent-bright)); }
.act-route-arrow::after {
  content: "";
  position: absolute;
  right: -1px;
  top: -4px;
  border-left: 8px solid var(--accent-bright);
  border-top: 5px solid transparent;
  border-bottom: 5px solid transparent;
}
.act-band-accent { color: var(--accent-bright); }
.act-band-muted { color: var(--text-secondary); }
.status-band-key .state-pill { margin-left: 6px; letter-spacing: 0; text-transform: none; }
/* The band's tint says what kind of answer it is: purple for what is next, green for what is
   done, amber for a rule in the way, grey for what cannot be done yet. The words and the icon
   say it too; the tint is never the only signal. */
.status-band-done { border-color: color-mix(in srgb, var(--success) 40%, transparent); background: linear-gradient(90deg, color-mix(in srgb, var(--success) 10%, transparent), transparent 60%, var(--surface-2)); }
.status-band-warn { border-color: color-mix(in srgb, var(--warning) 45%, transparent); background: linear-gradient(90deg, color-mix(in srgb, var(--warning) 9%, transparent), transparent 60%, var(--surface-2)); }
.status-band-quiet { border-color: var(--border); background: var(--surface-1); }

/* Departure and Arrival: one panel per airport, its conditions INSIDE it. */
.act-airports { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px; }
.act-airport-code { display: flex; align-items: baseline; gap: 12px; }
.act-airport-code .airport-link, .act-airport-code .airport-ref { font-size: 2.12rem; line-height: 1; }
.act-airport-iata { font-size: 0.88rem; color: var(--text-muted); }
.act-airport-name { margin-top: 8px; font-size: 1.12rem; font-weight: 600; }
.act-airport-place { font-size: 0.91rem; color: var(--text-secondary); }
.act-airport .act-panel-foot { border-top: none; padding-top: 0; }

/* About this leg beside where it sits in the tour. */
.act-columns-leg { grid-template-areas: "about context"; grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr); grid-template-rows: none; }
.act-area-context { grid-area: context; }
.act-rules-spaced { margin-top: 18px; }
.act-route-text { font-size: 0.84rem; word-break: break-word; }
/* The tour's legs in brief, this one marked (the Aircraft recent journey's chain). */
.act-context .journey { font-size: 0.91rem; }
.act-context .journey-dot-done { border-color: var(--success); background: var(--success); }
.act-context .journey-dot-here { border-color: var(--accent-bright); background: var(--accent-bright); box-shadow: 0 0 0 4px var(--accent-soft); }
.act-context .journey-stop a { color: inherit; }
.act-context .journey-stop .muted { font-size: 0.81rem; }
.act-context-nav { display: flex; gap: 8px; margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--border); }
.act-context-nav .act-context-back { margin-left: auto; }
/* Phone-only compact forms; the wide layout carries the same facts in full. */
.act-hero-line, .act-band-narrow, .act-airport-beside { display: none; }

@media (max-width: 1024px) {
  .act-columns-leg { grid-template-columns: minmax(0, 1fr); grid-template-areas: "about" "context"; }
}

@media (max-width: 720px) {
  .act-route { gap: 12px; margin-top: 12px; }
  .act-route-code { font-size: 1.62rem; }
  .act-route-arrow { flex-basis: 40px; }
  .act-route-name { font-size: 0.81rem; }
  .act-airports { grid-template-columns: minmax(0, 1fr); }
  .act-airport-code .airport-link, .act-airport-code .airport-ref { font-size: 1.62rem; }
  .act-context-nav .btn { min-height: 44px; }
  .act-hero-leg .detail-hero-body, .act-band-wide, .act-airport-iata, .act-airport .act-airport-name { display: none; }
  .act-hero-line { display: block; margin: 14px 0 0; font-size: 0.88rem; color: var(--text-secondary); }
  .act-band-narrow { display: block; }
  .act-airport-beside { display: inline; font-size: 1rem; font-weight: 600; }
  .act-airport-code { align-items: baseline; gap: 10px; flex-wrap: wrap; }
}
.act-inline-link { font-weight: 600; }

/* The page's shape while it loads (activity-view.js pageLoading). */
.act-loading { display: grid; gap: 18px; }
.act-loading .act-skel { margin: 0; }
.act-loading .act-skel-hero { display: grid; gap: 12px; align-content: end; min-height: 200px; padding: 28px 30px; }
.act-loading .act-skel-pill { width: 90px; height: 22px; border-radius: 999px; }
.act-loading .act-skel-title { width: 55%; height: 38px; }
.act-loading .act-skel-sub { width: 35%; height: 16px; }
.act-loading .detail-hero-body.act-skel-figs { display: flex; flex-direction: row; align-items: center; gap: 28px; }
.act-loading .act-skel-fig { width: 90px; height: 36px; }
.act-loading .act-skel-band { gap: 10px; }
.act-skel-band .status-band-half { display: grid; justify-items: start; gap: 10px; }
.act-loading .act-skel-key { width: 120px; height: 12px; }
.act-loading .act-skel-name { width: 45%; height: 22px; }
.act-loading .act-skel-code { width: 110px; height: 34px; }
.act-loading .act-skel-line { width: 75%; height: 14px; }
.act-loading .act-skel-short { width: 45%; }
.act-loading .act-panel { display: grid; justify-items: start; gap: 12px; }
.act-loading .act-skel-card { overflow: hidden; padding: 0; }
.act-skel-card-head { height: 150px; background: linear-gradient(135deg, var(--accent-soft), var(--surface-2)); }
.act-skel-card-body { display: grid; justify-items: start; gap: 10px; padding: 18px; }

/* ---- Hubs & bases ----
   The Hubs list and Hub Detail are built on the shared page primitives and the Events / Tours
   pieces above (the detail hero, key facts, status band and its conditions strip, panels, the
   list card, the thin bar, the map section, the loading shape). Only what these two pages alone
   need is here, and each rule names the shipped pattern it extends. The map is never a hero and
   never a card's head. */

/* List card (the Events / Tours card): the ICAO leads the body, the pilot's own marks sit beside
   it in words and an icon, and the description is clamped to two lines. */
.hub-card-ident { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 14px; }
.hub-icao { font-family: var(--font-mono); font-weight: 700; font-size: 1.38rem; line-height: 1.1; }
.hub-icao .airport-link, .hub-icao .airport-ref { font-size: inherit; }
.hub-mine { display: inline-flex; align-items: center; gap: 5px; font-size: 0.78rem; font-weight: 600; color: var(--accent-bright); }
.hub-mine .icon { width: 13px; height: 13px; }
.hub-card-title { display: flex; flex-direction: column; gap: 2px; }
.hub-card-title .list-card-name { margin-top: 6px; font-weight: 600; font-size: 1.12rem; letter-spacing: -0.01em; }
/* The three facts sit on one row; a phone gets them as one line. */
.hub-facts { flex-wrap: nowrap; gap: 8px 20px; }
.hub-facts-line { display: none; margin: 0; font-size: 0.91rem; color: var(--text-secondary); }
.hub-desc {
  margin: 0;
  font-size: 0.88rem;
  color: var(--text-secondary);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.hub-card-foot-figure { color: var(--text-secondary); }
.hub-card-foot-figure strong { color: var(--text-primary); font-weight: 700; }
.hubs-period { margin: 22px 0 0; font-size: 0.84rem; color: var(--text-muted); }

/* Search (the Library's field with the glyph inside it) at a fixed width beside its count, with
   Clear inside the field once something is typed. */
.hubs-toolbar { display: flex; align-items: center; flex-wrap: wrap; gap: 10px 16px; margin: 22px 0 18px; }
.hubs-search { flex: 0 1 400px; }
.hubs-search input { height: 44px; padding-right: 64px; }
.hubs-search input::-webkit-search-cancel-button { display: none; }
.hubs-search-clear {
  position: absolute;
  right: 6px;
  top: 50%;
  transform: translateY(-50%);
  min-height: 32px;
  padding: 0 8px;
  border: none;
  background: none;
  font: inherit;
  font-size: 0.84rem;
  color: var(--text-muted);
  cursor: pointer;
}
.hubs-search-clear:hover { color: var(--text-primary); }
.hubs-search-clear[hidden] { display: none; }
.hubs-count { font-size: 0.91rem; color: var(--text-muted); }
/* With nothing to search the box is not drawn, and the empty state keeps the head's spacing. */
.hubs-toolbar[hidden] + .hubs-list { margin-top: 22px; }

/* Hero (the Aircraft hero): the ICAO takes the registration's place and the hub's name the
   aircraft name's line. */
.hub-hero-code { margin: 0; font-family: var(--font-mono); font-weight: 700; font-size: 3.75rem; letter-spacing: 0.01em; line-height: 1; }
.hub-hero-code .airport-link, .hub-hero-code .airport-ref { font-size: inherit; line-height: inherit; }
.hub-hero-name { margin-top: 10px; font-size: 1.56rem; font-weight: 600; letter-spacing: -0.01em; }
.hub-hero-place { margin-top: 2px; font-size: 0.97rem; color: var(--text-secondary); }
.hub-hero-desc { margin: 0; font-size: 0.97rem; color: var(--text-secondary); max-width: 760px; }

/* Conditions, one station (the Tour conditions strip with one station instead of two), joined
   to the band, or standing alone as an ordinary panel when there is no band. */
.act-cond-1 { grid-template-columns: 170px minmax(0, 1fr) auto; }
.act-cond-alone { margin-top: 0; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--surface-2); }
.act-cond-view { font-size: 0.84rem; font-weight: 600; white-space: nowrap; }
.act-cond-key { margin: 0 0 4px; font-size: 0.75rem; font-weight: 600; letter-spacing: 0.07em; text-transform: uppercase; color: var(--text-secondary); }
.act-cond-caption.is-stale { color: var(--warning); }
.act-cond .act-station-head { flex-wrap: wrap; }
.hub-cond-keyrow { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.hub-cond-keyrow .act-cond-key { margin: 0 0 4px; }
.hub-cond-view-under { display: inline-block; margin-top: 8px; }
.hub-cond-foot { margin: 8px 0 0; font-size: 0.78rem; color: var(--text-muted); }
.hub-cond-foot.is-stale { color: var(--warning); }

/* The hero's streak figure keeps its denominator quiet beside it: "4 of 11 pilots". */
.hub-kfact-sub { font-size: 0.94rem; font-weight: 400; color: var(--text-secondary); }

/* You and this hub (the Aircraft status band): a title with its mark - a home for the base, a pin
   for where the pilot is - never colour alone. */
.hub-band .act-band-title { color: var(--text-primary); }
.hub-band-mark { display: inline-flex; color: var(--accent-bright); }
.hub-band-mark .icon { width: 16px; height: 16px; }
.hub-band .act-band-lead { font-size: 1.18rem; }
.hub-station-code { font-weight: 700; }
/* The category sits beside the station's name, not at the strip's end. */
.act-cond-1 .act-station-head .fdd-wx-pill { margin-left: 0; }

/* The network: its own section, a quiet note beside the heading and the legend at the end. */
.hub-network .act-panel-head { flex-wrap: wrap; }
.hub-panel-note { font-size: 0.81rem; color: var(--text-muted); }
.act-map.hub-map { height: 420px; }
/* A map that could not load has no legend to explain. */
.hub-network:has(.act-map-fallback:not([hidden])) .hub-legend { display: none; }
.activity-map-label-hub { border-color: var(--accent-bright); }
.act-map-popup-routes { margin-top: 3px; font-size: 0.8rem; color: #b4b6bc; }

/* About this hub: the description in paragraphs, as the airline wrote it. */
.hub-about .hub-prose p { margin: 0 0 10px; }
.hub-about .hub-prose p:last-child { margin: 0; }

/* The network map's legend: the hub is a larger filled ring, a destination a small ring - shape
   and size, not colour alone. */
.hub-legend { display: flex; gap: 18px; margin-left: auto; font-size: 0.81rem; color: var(--text-secondary); }
.hub-legend i { display: inline-block; width: 10px; height: 10px; margin-right: 6px; border-radius: 50%; vertical-align: -1px; border: 2px solid var(--text-muted); }
.hub-legend .hub-legend-hub { width: 12px; height: 12px; background: var(--accent-bright); border-color: #ffffff; }

/* The columns: what the hub does on the left, who is here on the right; one column in reading
   order below a laptop. */
.hub-columns { display: grid; grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr); gap: 18px; align-items: start; }
.hub-col { display: flex; flex-direction: column; gap: 18px; min-width: 0; }

/* Hub activity: five figures, the caption that says what they count, the monthly target on the
   thin bar, the chart, then the standing. */
.hub-figs { display: grid; grid-template-columns: repeat(5, minmax(0, auto)); justify-content: space-between; gap: 14px 18px; }
.hub-figs .stat-row-value { font-size: 1.56rem; }
.hub-caption { margin: 12px 0 0; font-size: 0.88rem; color: var(--text-secondary); }
.hub-caption strong { color: var(--text-primary); font-weight: 600; }
.hub-block { margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--border); }
.hub-goal-head { display: flex; align-items: baseline; gap: 10px; font-size: 0.88rem; color: var(--text-secondary); }
.hub-goal-head strong { color: var(--text-primary); font-weight: 600; }
.hub-goal-figure { margin-left: auto; white-space: nowrap; font-variant-numeric: tabular-nums; }
.hub-goal .thin-bar { margin-top: 8px; }
.hub-goal .thin-bar, .hub-goal .thin-bar-fill { height: 6px; border-radius: 3px; }
.hub-block-head { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
.hub-sub, .card h3.hub-sub {
  margin: 0;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.hub-sub span, .card h3.hub-sub span { margin-left: 8px; text-transform: none; letter-spacing: 0; font-weight: 400; font-size: 0.81rem; }
.hub-block-head .fd-seg, .act-panel-head .fd-seg { margin-left: auto; }
.hub-seg button { height: 32px; padding: 0 12px; font-size: 0.81rem; }
.hub-seg button[aria-pressed="true"] { background: var(--surface-3); color: var(--text-primary); }

/* Flights by day (the hub trend, redrawn as bars in a grid): one bar per bucket, a quiet mark
   where a bucket is zero, the axis under it. The figures are also in a hidden table. */
.hub-bars { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: 5px; align-items: end; height: 120px; border-bottom: 1px solid var(--border-strong); }
.hub-bars-sparse { grid-auto-columns: minmax(0, 48px); justify-content: center; }
.hub-bar { display: block; border-radius: 3px 3px 0 0; background: var(--accent-bright); }
.hub-bar-zero { height: 2px; border-radius: 0; background: var(--border-strong); }
.hub-bar-future { height: 0; }
.hub-bars-x { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: 5px; margin-top: 6px; font-size: 0.72rem; color: var(--text-muted); text-align: center; font-variant-numeric: tabular-nums; }
.hub-bars-sparse + .hub-bars-x { grid-auto-columns: minmax(0, 48px); justify-content: center; }
.hub-bars-x span { min-width: 0; white-space: nowrap; }
.hub-chart-note { margin: 8px 0 0; font-size: 0.81rem; color: var(--text-muted); }

/* The standing (the Aircraft activity row as a five-figure row). The hub on the page is marked
   in words ("this hub") as well as tint. */
.hub-standing-line { display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 16px; margin: 0 0 12px; }
.hub-standing-place { margin: 0; font-size: 1.25rem; font-weight: 700; letter-spacing: -0.01em; }
.hub-standing-metrics { font-size: 0.88rem; color: var(--text-secondary); }
.hub-standing-metrics strong { color: var(--text-primary); font-weight: 600; }
.hub-cmp {
  display: grid;
  grid-template-columns: 30px minmax(0, 1.5fr) repeat(4, minmax(0, 1fr));
  gap: 0 14px;
  align-items: center;
  padding: 9px 10px;
  border-top: 1px solid var(--border);
  font-size: 0.88rem;
  font-variant-numeric: tabular-nums;
}
.hub-cmp-head { border-top: none; padding-top: 0; padding-bottom: 6px; font-size: 0.69rem; font-weight: 600; letter-spacing: 0.07em; text-transform: uppercase; color: var(--text-muted); }
.hub-cmp-pos { text-align: center; font-weight: 600; }
.hub-cmp-me { border-radius: var(--radius-sm); border-top-color: transparent; background: var(--accent-soft); }
.hub-cmp-me + .hub-cmp { border-top-color: transparent; }
.hub-cmp-me .hub-cmp-name strong { font-weight: 700; }
.hub-cmp-this { font-weight: 400; font-size: 0.78rem; color: var(--text-muted); }
.hub-cmp-name { min-width: 0; overflow-wrap: anywhere; }
.hub-cmp-narrow { display: none; }
.hub-note { margin: 12px 0 0; font-size: 0.81rem; color: var(--text-muted); }

/* Routes & destinations: Most flown as a route line with the next four beside it, then the
   scheduled routes as rows (the Aircraft activity row: number, pair, planned figures, one
   action). */
.hub-most { display: grid; grid-template-columns: minmax(0, 1fr) 1px minmax(0, 1.25fr); gap: 0 22px; align-items: start; }
.hub-most-rule { align-self: stretch; background: var(--border); }
.hub-top-route { display: flex; align-items: flex-start; gap: 16px; }
.hub-top-code { font-family: var(--font-mono); font-weight: 700; font-size: 1.38rem; line-height: 1.1; }
.hub-top-code .airport-link, .hub-top-code .airport-ref { font-size: inherit; }
.hub-top-name { margin-top: 3px; font-size: 0.84rem; color: var(--text-secondary); }
.hub-top-route .act-route-arrow { flex: 1 1 60px; min-width: 40px; margin-top: 13px; }
.hub-top-figure { margin: 12px 0 0; font-size: 0.88rem; color: var(--text-secondary); }
.hub-top-figure strong { color: var(--text-primary); font-weight: 600; }
.hub-most-list { margin: 0; padding: 0; list-style: none; }
.hub-most-row { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 10px; align-items: baseline; padding: 5px 0; font-size: 0.88rem; }
.hub-most-row .mono { font-weight: 700; }
.hub-most-name { color: var(--text-secondary); overflow-wrap: anywhere; }
.hub-most-count { white-space: nowrap; font-variant-numeric: tabular-nums; }
.hub-rows { margin-top: 4px; }
.hub-rrow, .hub-orow {
  display: grid;
  grid-template-columns: 84px minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 4px 14px;
  padding: 10px 0;
  border-top: 1px solid var(--border);
  font-size: 0.91rem;
}
.hub-orow { grid-template-columns: 84px minmax(0, 1fr) auto; }
.hub-row-no { font-weight: 700; white-space: nowrap; }
.hub-row-pair { display: flex; align-items: baseline; flex-wrap: wrap; gap: 2px 10px; min-width: 0; }
.hub-row-codes { font-family: var(--font-mono); font-weight: 700; white-space: nowrap; }
.hub-row-codes .airport-link, .hub-row-codes .airport-ref { font-size: inherit; }
.hub-row-sub { font-size: 0.81rem; color: var(--text-muted); overflow-wrap: anywhere; }
.hub-row-sub .mono { font-weight: 700; }
.hub-row-meta { font-size: 0.81rem; color: var(--text-muted); white-space: nowrap; text-align: right; }
.hub-row-meta .mono { font-weight: 700; }
.hub-orow-end { display: flex; align-items: baseline; gap: 10px; white-space: nowrap; font-size: 0.81rem; color: var(--text-muted); }
.hub-more { background: none; border: none; padding: 0; font: inherit; font-size: 0.84rem; color: var(--text-muted); border-bottom: 1px dotted var(--border-strong); cursor: pointer; }
.hub-more:hover { color: var(--text-secondary); }
.hub-more:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 3px; border-radius: 2px; }
.hub-foot { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 16px; margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--border); font-size: 0.84rem; }
.hub-foot-end { margin-left: auto; display: flex; align-items: center; gap: 16px; }
.hub-foot a { font-weight: 600; }

/* Pilots at this hub: the board (place, the pilot, the figure) then the roster (the pilot, their
   lifetime figures and last flight). */
.hub-prow { display: grid; grid-template-columns: 18px minmax(0, 1fr) auto; align-items: center; gap: 12px; padding: 10px 0; border-top: 1px solid var(--border); font-size: 0.91rem; }
.hub-prow-roster { grid-template-columns: minmax(0, 1fr) auto; }
.hub-prow-figure { text-align: right; white-space: nowrap; font-size: 0.88rem; }
.hub-prow-figure .muted { display: block; font-size: 0.78rem; }
.hub-prow-you { font-weight: 400; color: var(--text-muted); }
.hub-board-caption-row { display: flex; align-items: flex-start; gap: 12px; margin-top: 12px; }
.hub-board-caption { margin: 0; font-size: 0.81rem; color: var(--text-muted); }
.hub-board-caption-row a { margin-left: auto; white-space: nowrap; font-size: 0.84rem; font-weight: 600; }
.hub-pilots-block + .hub-pilots-block { margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--border); }
.hub-pilots-block .hub-sub { margin-bottom: 12px; }
.hub-pilots-block .hubs-search { width: 100%; flex: none; margin-bottom: 6px; }
.hub-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 12px; }
.hub-chips .chip { padding: 5px 12px; font-size: 0.81rem; }

/* Hub records (a definition list with a second line under each value). */
.hub-recs { margin: 0; }
.hub-rec { display: grid; grid-template-columns: 150px minmax(0, 1fr); gap: 0 14px; padding: 10px 0; border-top: 1px solid var(--border); font-size: 0.91rem; }
.hub-rec:first-child { border-top: none; padding-top: 0; }
.hub-rec dt { color: var(--text-muted); }
.hub-rec dd { margin: 0; min-width: 0; }
.hub-rec-sub { display: block; font-size: 0.78rem; color: var(--text-muted); }
.hub-rec .mono { font-weight: 700; }

/* The activity panel while its period loads: three figures and a chart's worth of skeleton, so
   the panel keeps its shape. */
.hub-activity-skel { display: grid; gap: 14px; }
.hub-skel-figs { display: flex; gap: 22px; }
.hub-skel-fig { width: 80px; height: 40px; }
.hub-skel-chart { height: 80px; }

/* The standing's comparison is a table to a screen reader; on a phone each row keeps its
   flights beside the name, with a unit. */
.hub-cmp-table { margin-top: 4px; }
.hub-cmp-unit { display: none; }

/* Routes & destinations: Most flown above the scheduled routes. */
.hub-most-block { margin-bottom: 20px; }
.hub-most-block .hub-block-head { margin-bottom: 14px; }
.hub-dir-chips { margin: 0 0 0 auto; }
.hub-most-lead { min-width: 0; }
.hub-top-end { min-width: 0; }
.hub-routes-block .hub-routes-sub { margin-bottom: 4px; }

/* A quiet foot (Show 5 more, Show all 11 pilots): no rule above it. */
.hub-foot-quiet { border-top: none; padding-top: 0; margin-top: 12px; }
.hub-board-empty { padding: 10px 0; }
.hub-roster-empty { display: grid; justify-items: start; gap: 8px; padding: 10px 0; }

/* Words a phone drops or adds; the wide page carries the same facts. */
.hub-narrow-inline { display: none; }

/* A section's own failure, inside its panel: the words and Try again. */
.hub-section-error { display: flex; align-items: center; gap: 12px; padding: 12px 14px; border-radius: var(--radius-sm); border: 1px solid color-mix(in srgb, var(--danger) 40%, transparent); background: color-mix(in srgb, var(--danger) 8%, transparent); font-weight: 600; font-size: 0.91rem; }
.hub-section-error .btn { margin-left: auto; }
.hub-empty-line { margin: 0; font-size: 0.97rem; color: var(--text-secondary); }

@media (max-width: 1024px) {
  .hub-columns { grid-template-columns: minmax(0, 1fr); }
  .act-cond-1 { grid-template-columns: minmax(0, 1fr); }
  .hub-figs { grid-template-columns: repeat(3, minmax(0, 1fr)); justify-content: stretch; }
}

@media (max-width: 720px) {
  .hub-hero-code { font-size: 2.5rem; }
  .hub-hero-name { font-size: 1.19rem; margin-top: 4px; }
  .hub-hero-place { font-size: 0.84rem; }
  .hubs-search { flex-basis: 100%; }
  .hubs-toolbar { margin: 14px 0 12px; }
  /* The head is the title and its figures; a card is its identity, one line of facts, the
     flown figure and a full-width View hub. The count stays for screen readers. */
  .hub-page .act-head .act-lede, .hub-desc, .hub-facts { display: none; }
  .hubs-count { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .hub-facts-line { display: block; font-size: 0.8rem; }
  .hub-page .act-head { row-gap: 6px; }
  .hub-page .act-head .act-figs { flex-basis: 100%; }
  .hub-page .act-card-foot { border-top: none; padding-top: 0; }
  .hub-legend { margin-left: 0; flex-basis: 100%; }
  .act-map.hub-map { height: 240px; }
  /* The conditions keep three figures (the Tour strip's phone line is not this one), the network
     drops its legend and keeps its count at the right. */
  .act-cond-1 .act-wx { display: block; }
  .hub-cond-view-under { display: none; }
  .hub-legend { display: none; }
  .hub-panel-note { margin-left: auto; }
  .hub-figs { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .hub-cmp { grid-template-columns: 26px minmax(0, 1fr) auto; gap: 2px 12px; }
  .hub-cmp-head, .hub-cmp-wide { display: none; }
  .hub-cmp-unit { display: inline; }
  .hub-cmp-narrow { display: block; font-size: 0.78rem; color: var(--text-muted); }
  .hub-most { grid-template-columns: minmax(0, 1fr); gap: 14px; }
  .hub-most-rule { display: none; }
  /* A row is two lines - the number and the pair, then the rest - with its one action on the
     right, 44 px tall. */
  .hub-rrow, .hub-orow { grid-template-columns: auto minmax(0, 1fr) auto; gap: 2px 10px; }
  .hub-rrow { grid-template-areas: "no codes act" "meta meta act"; }
  .hub-orow { grid-template-areas: "no codes end" "sub sub end"; }
  .hub-rrow .hub-row-pair, .hub-orow .hub-row-pair { display: contents; }
  .hub-row-no { grid-area: no; }
  .hub-row-codes { grid-area: codes; }
  .hub-orow .hub-row-sub { grid-area: sub; }
  .hub-row-meta { grid-area: meta; text-align: left; white-space: normal; }
  .hub-rrow > :last-child { grid-area: act; }
  .hub-orow-end { grid-area: end; }
  .hub-rrow .btn { min-height: 44px; display: inline-flex; align-items: center; }
  .hub-orow .act-view { display: inline-flex; align-items: center; min-height: 44px; }
  /* The phone keeps the top pair of Most flown, worded. */
  .hub-dir-chips, .hub-most-rule, .hub-most-list, .hub-top-name { display: none; }
  .hub-wide, .hub-wide-inline { display: none; }
  /* 44 px targets: the segmented controls, and View airport through padding. */
  .hub-seg button { height: 44px; }
  .act-panel-head .hub-period { margin-left: 0; flex-basis: 100%; display: flex; }
  .hub-period button { flex: 1; }
  .act-cond-view { display: inline-block; padding: 13px 0; margin: -13px 0; }
  .hub-page .act-panel-aside { margin-left: auto; flex-basis: auto; }
  .hub-narrow-inline { display: inline; }
  .hub-rec { grid-template-columns: minmax(0, 1fr); gap: 2px; }
  .hub-more { padding: 12px 0; }
  .hub-chips { flex-wrap: nowrap; overflow-x: auto; }
  .hub-chips .chip { min-height: 44px; flex-shrink: 0; }
  .hub-page .btn-sm { min-height: 44px; }
}

/* ==========================================================================
   The map chrome on the light theme
   The basemap follows the theme (map-theme.js: positron on the light theme), so the chrome that
   sits on the map in concrete dark colours takes a light variant here: the zoom buttons, the
   attribution, the popups and hover card, the airport labels, the weather button and chip, the
   activity and network maps' backgrounds and panels. Scoped by [data-theme="light"], so the
   dark theme is untouched. The Live Map's flight sidebar is a panel beside the planes rather
   than chrome on the map, and keeps its dark colours.
   ========================================================================== */
[data-theme="light"] .live-shell { background: #eef0ec; }
[data-theme="light"] .act-map,
[data-theme="light"] .nm-map { background: linear-gradient(180deg, #f4f5f2, #eceee9); }

[data-theme="light"] .maplibregl-map .maplibregl-ctrl-group {
  background: rgba(255, 255, 255, 0.6);
  border-color: rgba(16, 17, 20, 0.08);
}
[data-theme="light"] .maplibregl-map .maplibregl-ctrl-group button:not(:disabled):hover { background-color: rgba(16, 17, 20, 0.05); }
[data-theme="light"] .maplibregl-map .maplibregl-ctrl-group button + button { border-top-color: rgba(16, 17, 20, 0.08); }
[data-theme="light"] .maplibregl-map .maplibregl-ctrl button .maplibregl-ctrl-icon { filter: none; }
[data-theme="light"] .maplibregl-map .maplibregl-ctrl-attrib,
[data-theme="light"] .maplibregl-map .maplibregl-ctrl-attrib.maplibregl-compact,
[data-theme="light"] .maplibregl-map .maplibregl-ctrl-attrib.maplibregl-compact-show {
  background: rgba(255, 255, 255, 0.45);
  color: #6b6f7a;
}
[data-theme="light"] .maplibregl-map .maplibregl-ctrl-attrib-button { filter: none; opacity: 0.45; }

[data-theme="light"] #live-map .maplibregl-popup-content,
[data-theme="light"] .route-map .maplibregl-popup-content {
  background: #ffffff;
  border-color: #d9dbe1;
  box-shadow: 0 8px 22px rgba(16, 17, 20, 0.16);
}
[data-theme="light"] #live-map .maplibregl-popup-anchor-bottom .maplibregl-popup-tip,
[data-theme="light"] .route-map .maplibregl-popup-anchor-bottom .maplibregl-popup-tip { border-top-color: #d9dbe1; }
[data-theme="light"] #live-map .maplibregl-popup-anchor-top .maplibregl-popup-tip,
[data-theme="light"] .route-map .maplibregl-popup-anchor-top .maplibregl-popup-tip { border-bottom-color: #d9dbe1; }
[data-theme="light"] #live-map .maplibregl-popup-anchor-left .maplibregl-popup-tip,
[data-theme="light"] .route-map .maplibregl-popup-anchor-left .maplibregl-popup-tip { border-right-color: #d9dbe1; }
[data-theme="light"] #live-map .maplibregl-popup-anchor-right .maplibregl-popup-tip,
[data-theme="light"] .route-map .maplibregl-popup-anchor-right .maplibregl-popup-tip { border-left-color: #d9dbe1; }
/* What those popups hold: the Live Map's hover card and the activity maps' airport card. */
[data-theme="light"] .live-hover-callsign,
[data-theme="light"] .act-map-popup { color: #1f2128; }
[data-theme="light"] .live-hover-route,
[data-theme="light"] .live-hover-meta,
[data-theme="light"] .live-hover-wind,
[data-theme="light"] .act-map-popup-detail { color: #5c606b; }
[data-theme="light"] .live-hover-age,
[data-theme="light"] .act-map-popup-routes { color: #6b6f7a; }
[data-theme="light"] .live-bar { background: #e2e4ea; }

/* The airport codes drawn on the maps. */
[data-theme="light"] .activity-map-label,
[data-theme="light"] .live-map-airport {
  color: #1f2128;
  background: rgba(255, 255, 255, 0.9);
  border-color: rgba(16, 17, 20, 0.16);
}
[data-theme="light"] .live-map-airport { color: #4a4e58; }

/* The Live Map's weather button and the chip saying what the map shows. */
[data-theme="light"] .live-wx-btn {
  color: #1f2128;
  background: rgba(255, 255, 255, 0.94);
  border-color: rgba(16, 17, 20, 0.16);
}
[data-theme="light"] .live-wx-btn[aria-expanded="true"] { border-color: var(--accent); }
[data-theme="light"] .live-wx-chip {
  color: #3a3d46;
  background: rgba(255, 255, 255, 0.9);
  border-color: rgba(16, 17, 20, 0.12);
}
[data-theme="light"] .live-wx-chip-muted { color: #6b6f7a; }

/* The route network map (Flights, Schedules): its own drawing colours, read by
   network-map-view.js from these properties, and its panels. The panels' text already follows the
   theme's tokens, so their backgrounds follow it too. */
[data-theme="light"] .nm-map {
  --nm-other: #a4a7b0;
  --nm-dot: #3a3d46;
  --nm-edge: #ffffff;
  --nm-label: #2a2c33;
}
[data-theme="light"] .nm-chip,
[data-theme="light"] .nm-zoom,
[data-theme="light"] .nm-legend { background: rgba(255, 255, 255, 0.94); }
[data-theme="light"] .nm-tag { background: rgba(255, 255, 255, 0.94); color: #1f2128; }
[data-theme="light"] .nm-tag-sel { border-color: #1f2128; }
[data-theme="light"] .nm-side {
  background: rgba(255, 255, 255, 0.97);
  box-shadow: 0 18px 40px rgba(16, 17, 20, 0.18);
}
[data-theme="light"] .nm-flt,
[data-theme="light"] .nm-prow { border-color: var(--border); }

/* ==========================================================================
   Homepage. Breakpoints follow the newer pages: 1024px and 720px.
   ========================================================================== */

/* ---- the unresolved state: the neutral shell (site-boot.js) ----
   Until the airline is identified and its look applied, every page shows ONE
   flat tone and the outline of the header bar. No text, no accent, no logo,
   no image. The tone is html[data-va-tone]: the tone this browser last
   painted, never an airline's setting. */
html[data-va-boot="pending"] body > * { visibility: hidden; }
/* The body's own background is the THEME's; while pending the shell's tone shows through it. */
html[data-va-boot="pending"] body { background: transparent; }
html[data-va-boot="pending"] body::before {
  content: "";
  display: block;
  height: 64px;
  border-bottom: 1px solid var(--border);
}
html[data-va-boot="pending"][data-va-tone="light"] { background: #f4f4f6; --border: #dcdee3; color-scheme: light; }
html[data-va-boot="pending"][data-va-tone="dark"] { background: #0c0d0f; --border: #292a30; color-scheme: dark; }
/* The reveal: content fades in once, with the airline's theme already applied. */
html[data-va-boot="ready"] body { animation: va-reveal 0.15s ease-out; }
@keyframes va-reveal { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  html[data-va-boot="ready"] body { animation: none; }
}

/* ---- the hero image: its own layer ----
   It fades in once decoded; the hero's surface and gradient are the
   placeholder underneath, and what a dead image leaves behind. */
.hero-media {
  position: absolute;
  inset: 0;
  z-index: 0;
  background-size: cover;
  background-position: center;
  opacity: 0;
  transition: opacity 0.3s ease;
}
.hero-media.is-loaded { opacity: 1; }
.hero::before { z-index: 1; }
.hero .container { z-index: 2; }
@media (prefers-reduced-motion: reduce) { .hero-media { transition: none; } }

/* ---- the section heading: one pattern for every homepage section ----
   Title, an optional one-line sub, an optional link. Wraps instead of
   overflowing; on a phone the link stays beside the title and the sub drops. */
.home-head {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px 16px;
  margin-bottom: 22px;
}
.home-head h2 { margin: 0; font-size: 1.6rem; letter-spacing: -0.01em; }
.home-head-sub { color: var(--text-muted); font-size: 0.95rem; }
.home-head-link { margin-left: auto; font-size: 0.92rem; font-weight: 600; white-space: nowrap; }
.home-head-link:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 3px; border-radius: 4px; }

/* ---- Flying now ----
   The right-hand column is ALWAYS there on a wide screen, and the layout
   reserves the card's full height, so the card arriving moves nothing.
   (The card itself stays [hidden] until somebody is airborne; the grid keeps
   its empty column.) */
@media (min-width: 1025px) {
  .hero-layout,
  .hero-layout.has-live {
    grid-template-columns: minmax(0, 1fr) 380px;
    /* The card's measured height with its three rows. */
    min-height: 320px;
  }
}
.hero-live { transition: opacity 0.15s ease; }
a.hero-live-row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 5px 12px;
  color: inherit;
}
a.hero-live-row:hover { text-decoration: none; background: var(--surface-3); }
a.hero-live-row:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: -2px; }
.hero-live-row .badge { margin-left: 0; }
.hero-live-progress {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 0.76rem;
  color: var(--text-muted);
}
.hero-live-progress .thin-bar { flex: 1; }
.hero-live-progress .mono { color: var(--text-secondary); }
.hero-live-link:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: -2px; }

/* Narrow screens: no card. One compact line sits INSIDE the gap that already
   separates the buttons from the figures, so it too arrives without a shift. */
.hero-live-slot { display: none; }
@media (max-width: 1024px) {
  .hero-layout, .hero-layout.has-live { grid-template-columns: minmax(0, 1fr); }
  .hero-live { display: none; }
  .hero-live-slot { display: block; min-height: 44px; margin-top: 18px; }
  .hero-stats { margin-top: 18px; }
  a.hero-live-strip {
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 44px;
    padding: 0 14px;
    border: 1px solid color-mix(in srgb, #ffffff 16%, transparent);
    border-radius: var(--radius-md);
    background: color-mix(in srgb, #070808 45%, transparent);
    color: #ffffff;
    font-size: 0.9rem;
  }
  a.hero-live-strip:hover { text-decoration: none; }
  a.hero-live-strip:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 2px; }
  .hero-live-strip strong { white-space: nowrap; }
  .hero-live-strip-flight { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: rgba(236, 237, 237, 0.82); }
  .hero-live-strip-go { margin-left: auto; white-space: nowrap; font-weight: 600; }
}

/* The hero is dark in BOTH themes, so its figures use the hero's own colours
   rather than the page's text tokens (which would be dark on dark in the light theme). */
.hero-stats .stat-tile .stat-value { color: #ffffff; }
.hero-stats .stat-tile .stat-label { color: rgba(236, 237, 237, 0.72); }

/* The figures. The row keeps its height while they load; the placeholders are
   the size of a figure and its label. Translucent white, because they sit on
   the hero image rather than on a surface. */
.hero-stats { min-height: 86px; }
.stat-skel-value, .stat-skel-label {
  border-radius: 6px;
  background: linear-gradient(90deg, rgba(255,255,255,0.10) 25%, rgba(255,255,255,0.20) 50%, rgba(255,255,255,0.10) 75%);
  background-size: 200% 100%;
  animation: shimmer 1.4s infinite;
}
.stat-skel-value { width: 72px; height: 29px; margin: 5px 0 8px; }
.stat-skel-label { width: 104px; height: 12px; margin: 0 0 5px; }
@media (prefers-reduced-motion: reduce) {
  .stat-skel-value, .stat-skel-label { animation: none; background: rgba(255,255,255,0.14); }
}
/* Tablet: six figures in one row of equal columns, never five and an orphan. */
@media (min-width: 721px) and (max-width: 1024px) {
  .hero-stats .stat-grid { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 12px; }
  .hero-stats .stat-tile .stat-label { font-size: 0.72rem; }
  /* A label may wrap to two lines at this width; the row reserves for it. */
  .hero-stats { min-height: 103px; }
}
@media (max-width: 720px) {
  .hero .container { padding-top: 44px; padding-bottom: 32px; }
  .hero-stats .stat-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px 10px; }
  .hero-stats .stat-tile .stat-value { font-size: 1.45rem; }
  .hero-stats .stat-tile .stat-label { font-size: 0.68rem; letter-spacing: 0.04em; }
  .stat-skel-value { width: 54px; height: 23px; margin: 4px 0 8px; }
  .stat-skel-label { width: 76px; height: 10px; margin: 0 0 5px; }
  .hero-stats { min-height: 155px; }
  .hero-actions .btn { flex: 1 1 0; justify-content: center; min-height: 44px; padding: 11px 10px; white-space: nowrap; }
}

/* ---- the latest notice: one line, in a slot that is always reserved ----
   The slot lives in the whitespace between the hero and About, so a notice
   that arrives (or does not) changes nothing below it. */
.home-notice-slot { min-height: 46px; margin-top: 22px; }
.home-notice-slot + .section { padding-top: 26px; }
a.home-notice {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 46px;
  padding: 8px 16px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--info);
  border-radius: var(--radius-md);
  background: var(--surface-2);
  color: inherit;
  font-size: 0.92rem;
}
a.home-notice:hover { text-decoration: none; border-color: var(--border-strong); border-left-color: var(--info); }
a.home-notice:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 2px; }
a.home-notice[data-severity="warning"], a.home-notice[data-severity="warning"]:hover { border-left-color: var(--warning); }
a.home-notice[data-severity="critical"], a.home-notice[data-severity="critical"]:hover { border-left-color: var(--danger); }
.home-notice-key { font-size: 0.7rem; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase; color: var(--text-muted); white-space: nowrap; }
.home-notice-title { flex: 1; min-width: 0; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.home-notice-date { color: var(--text-muted); font-size: 0.84rem; white-space: nowrap; }
.home-notice-go { color: var(--accent-bright); font-weight: 600; white-space: nowrap; }
@media (max-width: 720px) {
  .home-notice-slot { min-height: 70px; margin-top: 16px; }
  a.home-notice { flex-wrap: wrap; gap: 2px 10px; min-height: 70px; padding: 10px 14px; }
  .home-notice-title { flex-basis: 100%; order: 3; }
  .home-notice-date { margin-left: auto; }
  .home-notice-go { display: none; }
}

/* ---- About / At a glance ---- */
/* The facts card is not a link: it does not lift. */
.about-facts:hover { transform: none; border-color: var(--border); }
.fact-row .fact-value a { color: inherit; border-bottom: 1px dotted var(--border-strong); }
.fact-row .fact-value a:hover { color: var(--accent-bright); text-decoration: none; border-bottom-color: var(--accent-bright); }
.fact-row .fact-value a:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 2px; border-radius: 2px; }
.fact-skel { display: inline-block; width: 128px; height: 14px; margin: 0; vertical-align: middle; }
.fact-row:nth-child(even) .fact-skel { width: 96px; }

@media (max-width: 720px) {
  /* Homepage only: not written on .section, which every page shares. */
  .home-main > .section { padding-top: 44px; }
  .home-main > .home-notice-slot + .section { padding-top: 26px; }
  .home-head h2 { font-size: 1.35rem; }
  .home-head-sub { flex-basis: 100%; order: 3; font-size: 0.88rem; }
}

/* ---- Community highlights -------------------------------------------- */
.home-highlights { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px; }
.home-highlights .act-card-head { height: 150px; }
.home-highlights .act-feature { grid-column: 1 / -1; }
.home-highlights .act-feature .act-card-head { height: auto; }
/* What kind of thing the card is, in words, above its name. */
.home-kind { font-size: 0.7rem; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase; color: var(--text-muted); margin-bottom: 3px; }
/* The award: a supporting line under the cards, not a third card. */
.home-award {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-top: 18px;
  padding: 12px 18px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  font-size: 0.92rem;
}
.home-award-emblem { width: 40px; height: 40px; flex-shrink: 0; }
.home-award-text { min-width: 0; }
.home-award-name { font-weight: 600; }
.home-award .avatar-stack { margin-left: auto; }
.home-award-go { font-weight: 600; white-space: nowrap; }
/* The award promoted into a card slot when there is no event and no second tour: the tour card's
   shape, with the award's emblem large on the gradient head so it never reads as an empty card. */
.home-award-head { display: flex; align-items: center; justify-content: center; }
.home-award-head .home-award-head-emblem {
  width: 104px; height: 104px; object-fit: contain;
  filter: drop-shadow(0 6px 14px rgba(0, 0, 0, 0.35));
}
.home-award-head-mark {
  width: 72px; height: 72px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--accent-soft); color: var(--accent-bright);
}
.home-award-head-mark .icon { width: 34px; height: 34px; }
@media (max-width: 1024px) {
  .home-highlights .act-feature { grid-template-columns: minmax(0, 1fr); }
  .home-highlights .act-feature .act-card-head { min-height: 170px; }
}
@media (max-width: 720px) {
  .home-highlights { grid-template-columns: minmax(0, 1fr); }
  .home-highlights .act-card-head { height: 128px; }
  .home-award-head .home-award-head-emblem { width: 88px; height: 88px; }
  .home-highlights .act-card-foot .btn { min-height: 44px; }
  .home-award { flex-wrap: wrap; }
  .home-award .avatar-stack { display: none; }
  .home-award-go { margin-left: auto; }
}

/* ---- One flight row (flight-row.js): the homepage's Latest flights, Recent flights, My PIREPs ----
   A list is ONE grid and each row a subgrid of it, so the flight numbers, routes, badges and dates
   of every row share the same columns and the arrival codes stand in line. The flight number is
   the accent colour on every list. */
.flight-rows {
  display: grid;
  /* The route never gets less than its two 112px ends, the 40px line and the gaps - otherwise a
     long pilot name can take the badges column wide enough to run the arrival under it; the
     badges column gives way instead, wrapping onto a second line. */
  grid-template-columns: max-content minmax(292px, 1fr) minmax(0, max-content) max-content;
  column-gap: 18px;
  row-gap: 10px;
}
.flight-rows > .flight-row { grid-column: 1 / -1; display: grid; grid-template-columns: subgrid; align-items: center; }
.flight-row .flight-no { color: var(--accent-bright); }
.flight-row .route { min-width: 0; }
.flight-row .route .airport-link { font-size: inherit; }
.flight-row .activity-meta { min-width: 0; margin-left: 0; flex-wrap: wrap; justify-content: flex-end; }
.flight-row .when { min-width: 0; }
.home-flight-skel { height: 74px; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--surface-2); display: flex; align-items: center; gap: 18px; padding: 0 18px; }
.home-flight-skel .skeleton { margin: 0; height: 14px; }
@media (max-width: 820px) {
  .flight-rows { display: flex; flex-direction: column; gap: 10px; }
  .flight-rows > .flight-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px 12px; padding: 12px 14px; }
  .flight-row .flight-no { min-width: 0; }
  .flight-row .when { grid-row: 1; grid-column: 2; align-self: center; }
  .flight-row .route { grid-column: 1 / -1; gap: 10px; }
  .flight-row .route .route-end { width: auto; min-width: 0; }
  .flight-row .route .route-end .airport-code { font-size: 1.12rem; }
  .flight-row .route .route-end:last-child { text-align: right; }
  .flight-row .activity-meta { grid-column: 1 / -1; flex-wrap: wrap; justify-content: flex-start; }
  .home-flight-skel { height: 150px; }
}

/* ---- Hubs and fleet: a full-width row each ---------------------------- */
.home-row { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 18px; }
.home-row[data-count="2"] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.home-row[data-count="1"] { grid-template-columns: minmax(0, 1fr); }
/* One hub or one type: the wide form, quiet (no accent wash - it is not "the thing that matters now"). */
.home-row .act-feature { border-color: var(--border); background: var(--surface-2); grid-template-columns: 420px minmax(0, 1fr); }
.home-row .act-feature:hover { border-color: var(--border-strong); }
.home-row .act-feature .act-card-head, .home-row .act-feature .list-card-head { height: auto; min-height: 200px; }
.home-row .list-card-head img { transition: opacity 0.2s ease; }
.home-fleet-foot { font-size: 0.84rem; }
/* Card-shaped placeholders: the real head height, no lift. */
.home-skel-card { pointer-events: none; }
.home-skel-card:hover { transform: none; border-color: var(--border); }
.home-skel-card .list-card-head { background: var(--surface-3); }
.home-skel-card .skeleton { margin: 0; }
.home-highlights .home-skel-card { min-height: 414px; }
.home-row-hubs .home-skel-card { min-height: 384px; }
.home-row-fleet .home-skel-card { min-height: 306px; }
.home-award-skel { height: 70px; margin-top: 18px; border: 1px solid var(--border); border-radius: var(--radius-md); }
.home-skel-card .sk-code { width: 72px; height: 22px; }
.home-skel-card .sk-name { width: 62%; height: 16px; }
.home-skel-card .sk-line { width: 84%; height: 12px; }
.home-skel-card .sk-foot { width: 44%; height: 12px; margin-top: 18px; }

/* Tablet portrait and phones: the cards become compact rows - image at the
   side, one line of facts, one action. Not the desktop card squeezed. */
@media (max-width: 900px) {
  .home-row, .home-row[data-count="2"] { grid-template-columns: minmax(0, 1fr); gap: 12px; }
  .home-row .list-card, .home-row .act-feature {
    position: relative;
    display: grid;
    grid-template-columns: 92px minmax(0, 1fr);
    border-radius: var(--radius-md);
  }
  .home-row-hubs .home-skel-card { min-height: 134px; }
  .home-row-fleet .home-skel-card { min-height: 109px; }
  .home-row .home-skel-card .sk-foot, .home-row .home-skel-card .sk-line { display: none; }
  .home-row .home-skel-card .list-card-head { height: auto !important; }
  /* A type with no photo has no side panel at this size. */
  .home-row-fleet .list-card:has(> .list-card-head-plain) { grid-template-columns: minmax(0, 1fr); }
  .home-row-fleet .list-card > .list-card-head-plain { display: none; }
  .home-row .list-card:hover { transform: none; }
  .home-row .list-card-head,
  .home-row .act-card-head,
  .home-row .act-feature .act-card-head,
  .home-row .act-feature .list-card-head { height: auto; min-height: 100%; border-bottom: none; border-right: 1px solid var(--border); }
  .home-row .list-card-head .list-card-badges,
  .home-row .list-card-head.act-card-head .list-card-badges { display: none; }
  .home-row .list-card-body, .home-row .act-feature .list-card-body { padding: 12px 56px 12px 14px; gap: 6px; }
  .home-row .act-feature .list-card-name, .home-row .hub-card-title .list-card-name { font-size: 1.02rem; margin-top: 2px; }
  .home-row .hub-icao { font-size: 1.12rem; }
  .home-row .act-card-where { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: 0.84rem; }
  .home-row .list-card-facts, .home-row .hub-desc { display: none; }
  .home-row .hub-facts-line { display: block; font-size: 0.82rem; }
  .home-row .hub-card-foot-figure, .home-row .home-fleet-foot { display: none; }
  /* The card's one action becomes a 44px chevron at the right, and its target covers the row. */
  .home-row .act-card-foot { position: static; border: none; padding: 0; margin: 0; min-height: 0; }
  .home-row .act-card-foot .btn,
  .home-row .act-feature .act-card-foot .btn {
    position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
    width: 44px; height: 44px; min-height: 44px; padding: 0; margin: 0;
    border: none; background: none; font-size: 0; justify-content: center;
  }
  .home-row .act-card-foot .btn::before { content: "›"; font-size: 1.7rem; line-height: 1; color: var(--text-muted); }
  .home-row .act-card-foot .btn::after { content: ""; position: absolute; inset: -300px -10px -300px -900px; }
  .home-row .act-card-foot .btn:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: -2px; }
  /* The main hub says so in words, since the pill on the image is gone at this size. */
  .home-row .home-main-mark { display: inline; }
}
.home-main-mark { display: none; font-size: 0.74rem; font-weight: 600; color: var(--accent-bright); }


@media (max-width: 720px) {
  .home-highlights .home-skel-card { min-height: 431px; }
  .home-award-skel { height: 108px; }
  .home-row-hubs .home-skel-card { min-height: 155px; }
  .home-row-fleet .home-skel-card { min-height: 130px; }
}

/* The Fleet page's type cards are linked from the homepage (fleet.html#type-<CODE>): land below the sticky header. */
#fleet-types .list-card { scroll-margin-top: 84px; }

/* ==========================================================================
   The Join page
   ==========================================================================
   The recruitment hero, then ONE application sheet - sections divided by headings, spacing and
   hairlines, never a card per section - beside a quiet, borderless aside. Every colour is a theme
   token except the hero's NEUTRAL shade, which matches the homepage hero's on purpose. */

/* Accent as TEXT. --accent-bright is tuned for dark surfaces; on the light theme it washes out,
   so the Join page's small accent text darkens the airline's colour instead. The terms dialog sits
   outside the page, so it carries the same ink. */
.join-page,
.join-terms-dialog { --join-ink: var(--accent-bright); }
[data-theme="light"] .join-page,
[data-theme="light"] .join-terms-dialog { --join-ink: color-mix(in srgb, var(--accent) 72%, #000000); }

/* ---- the recruitment hero ---- */
.join-hero {
  position: relative;
  min-height: 320px;
  display: flex;
  align-items: flex-end;
  background-color: #14161b;
  overflow: hidden;
}
/* NEUTRAL shade, as on the homepage hero: never tinted by the accent, so the words keep their
   contrast over any image, any accent and either theme. */
.join-hero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(180deg,
    color-mix(in srgb, #070808 50%, transparent) 0%,
    color-mix(in srgb, #070808 42%, transparent) 40%,
    color-mix(in srgb, #070808 86%, transparent) 100%);
}
/* No image, or none that loaded (vabase.js marks it): the designed plain hero. */
.join-hero.is-plain {
  background:
    radial-gradient(1100px 380px at 12% 0%, color-mix(in srgb, var(--accent) 34%, transparent), transparent 70%),
    #14161b;
}
.join-hero .container {
  position: relative;
  z-index: 2;
  width: 100%;
  padding-top: 72px;
  padding-bottom: 38px;
}
/* Shown only while applications are closed. */
.join-hero-status {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 0.8rem;
  font-weight: 600;
  color: #ffffff;
  background: color-mix(in srgb, #070808 50%, transparent);
  border: 1px solid rgba(236, 237, 237, 0.3);
  border-radius: 999px;
  padding: 4px 12px;
  margin-bottom: 16px;
}
.join-hero-status::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--text-muted);
}
.join-hero h1 {
  margin: 0 0 8px;
  font-size: clamp(2rem, 4.6vw, 3.2rem);
  line-height: 1.08;
  letter-spacing: -0.02em;
  color: #ffffff;
  text-wrap: balance;
  overflow-wrap: anywhere;
}
.join-hero .tagline {
  max-width: 640px;
  margin: 0;
  font-size: clamp(1rem, 2vw, 1.2rem);
  color: rgba(236, 237, 237, 0.88);
}
.join-hero .tagline:empty { display: none; }

/* ---- the page under the hero ---- */
.join-page { padding: 40px 0 80px; }
.join-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 300px;
  gap: 48px;
  align-items: start;
}
/* Closed, sent, or failed to load: one centred column, no aside. */
.join-grid.is-single { grid-template-columns: minmax(0, 720px); justify-content: center; }

/* ---- the application sheet: ONE surface ---- */
.join-sheet {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
  min-width: 0;
}
/* The airline's own introduction (plain text; line breaks kept). */
.join-lede {
  margin: 0;
  padding: 32px 40px 0;
  font-size: 1.08rem;
  line-height: 1.6;
  color: var(--text-secondary);
  white-space: pre-line;
  overflow-wrap: anywhere;
}
.join-section { padding: 34px 40px; }
.join-section + .join-section,
.join-lede:not([hidden]) + .join-section { border-top: 1px solid var(--border); }
.join-lede:not([hidden]) + .join-section { margin-top: 32px; }
.join-section-head { display: flex; align-items: baseline; gap: 14px; margin: 0 0 22px; }
.join-section-num {
  flex: none;
  font-family: var(--font-mono);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  color: var(--join-ink);
}
.join-section h2 { margin: 0; font-size: 1.25rem; letter-spacing: -0.01em; }
.join-section-sub { margin: 3px 0 0; font-size: 0.92rem; color: var(--text-muted); }
.join-section-sub:empty { display: none; }

/* The airline's own questions are a section like any other: same heading, no wash, no commentary. */

/* ---- fields ---- */
.join-fields { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px 22px; align-items: start; }
.join-fields > .is-wide { grid-column: 1 / -1; }
.join-field { min-width: 0; margin: 0; }
.join-field > label:not(.check-row) {
  display: block;
  margin: 0 0 7px;
  font-size: 0.88rem;
  font-weight: 600;
  line-height: 1.4;
  color: var(--text-primary);
  overflow-wrap: anywhere;
}
.join-optional { margin-left: 6px; font-size: 0.78rem; font-weight: 500; color: var(--text-muted); }
.join-required { margin-left: 3px; color: var(--join-ink); }
.join-field input:not([type="checkbox"]),
.join-field select,
.join-field textarea {
  width: 100%;
  background: var(--surface-1);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  font-family: inherit;
  font-size: 1rem; /* 16px: a phone does not zoom the page on focus */
  padding: 11px 14px;
}
.join-field textarea { min-height: 112px; resize: vertical; line-height: 1.5; }
.join-field input:focus,
.join-field select:focus,
.join-field textarea:focus { outline: 2px solid var(--accent); outline-offset: -1px; }
.join-field .field-hint { margin-top: 6px; font-size: 0.82rem; overflow-wrap: anywhere; }
.join-field label.check-row { margin: 0; font-weight: 500; }
/* Invalid: the border, and a sentence under the field that the field points at. */
.join-field.is-invalid input:not([type="checkbox"]),
.join-field.is-invalid select,
.join-field.is-invalid textarea { border-color: var(--danger); }
.join-field.is-invalid label.check-row input[type="checkbox"] { border-color: var(--danger); }
.join-field-error { margin: 6px 0 0; font-size: 0.84rem; font-weight: 500; color: var(--danger); }

/* Show / hide password: a button inside the field's right edge. */
.join-password { position: relative; }
.join-password input:not([type="checkbox"]) { padding-right: 46px; }
.join-password-toggle {
  position: absolute;
  top: 0;
  right: 0;
  width: 44px;
  height: 100%;
  display: grid;
  place-items: center;
  background: none;
  border: 0;
  border-radius: var(--radius-sm);
  color: var(--text-muted);
  cursor: pointer;
}
.join-password-toggle:hover,
.join-password-toggle[aria-pressed="true"] { color: var(--text-primary); }

/* ---- the last section: send ---- */
.join-submit {
  padding: 30px 40px 34px;
  border-top: 1px solid var(--border);
  background: var(--surface-1);
  border-radius: 0 0 var(--radius-lg) var(--radius-lg);
}
.join-submit .join-section-head { margin-bottom: 12px; }
.join-submit h2 { margin: 0; font-size: 1.25rem; letter-spacing: -0.01em; }
.join-submit-note { margin: 0 0 18px; font-size: 0.95rem; color: var(--text-secondary); }
.join-terms-row { margin: 0 0 22px; }
.join-terms-row label.check-row { margin: 0; }
/* "terms and conditions" inside the tick box's sentence opens the dialog; it is a button that
   reads as a link, and it never ticks the box. */
.join-terms-link {
  padding: 0;
  background: none;
  border: 0;
  font: inherit;
  font-weight: 600;
  color: var(--join-ink);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}
.join-error-summary { margin: 0 0 18px; }
.join-error-summary ul { margin: 6px 0 0; padding-left: 18px; }
.join-error-summary a { color: inherit; text-decoration: underline; }
.join-submit-row { display: flex; align-items: center; flex-wrap: wrap; gap: 14px 24px; }
.join-cta { min-width: 240px; justify-content: center; padding: 14px 28px; font-size: 1.02rem; }
.join-cta .join-spinner {
  width: 16px;
  height: 16px;
  border: 2px solid color-mix(in srgb, var(--text-on-accent) 35%, transparent);
  border-top-color: var(--text-on-accent);
  border-radius: 50%;
  animation: join-spin 0.7s linear infinite;
}
@keyframes join-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .join-cta .join-spinner { animation: none; } }
.join-signin { margin: 0; font-size: 0.92rem; color: var(--text-muted); }
.join-signin a { color: var(--join-ink); font-weight: 600; }

/* ---- the aside: borderless, not a card ---- */
.join-aside { position: sticky; top: 92px; min-width: 0; padding-top: 6px; }
.join-aside-ident { display: flex; align-items: center; gap: 12px; margin-bottom: 26px; }
.join-aside-logo {
  flex: none;
  width: 44px;
  height: 44px;
  border-radius: 12px;
  display: grid;
  place-items: center;
  background: var(--accent);
  color: var(--text-on-accent);
  object-fit: contain;
}
.join-aside-logo[hidden] { display: none; }
.join-aside-eyebrow { font-size: 0.78rem; color: var(--text-muted); }
.join-aside-name { font-weight: 700; line-height: 1.25; overflow-wrap: anywhere; }
.join-aside h2 {
  margin: 0 0 12px;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.join-steps { list-style: none; margin: 0 0 28px; padding: 0; counter-reset: join-step; }
.join-steps li {
  position: relative;
  counter-increment: join-step;
  padding: 0 0 16px 38px;
  font-size: 0.93rem;
  color: var(--text-secondary);
}
.join-steps li strong { display: block; color: var(--text-primary); font-weight: 600; }
.join-steps li::before {
  content: counter(join-step);
  position: absolute;
  left: 0;
  top: 0;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-size: 0.78rem;
  font-weight: 600;
  background: var(--surface-3);
  border: 1px solid var(--border-strong);
  color: var(--text-secondary);
}
.join-steps li:not(:last-child)::after {
  content: "";
  position: absolute;
  left: 12px;
  top: 28px;
  bottom: 2px;
  width: 1px;
  background: var(--border-strong);
}
.join-steps li:last-child { padding-bottom: 0; }
.join-aside-links { display: grid; gap: 8px; padding-top: 20px; border-top: 1px solid var(--border); font-size: 0.92rem; }
.join-aside-links p { margin: 0; color: var(--text-muted); }
.join-aside-terms { justify-self: start; text-align: left; }

/* ---- closed, sent, could not load: one calm block in the sheet's place ---- */
.join-outcome { padding: 56px 40px; text-align: center; }
.join-outcome-mark {
  width: 52px;
  height: 52px;
  margin: 0 auto 18px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--accent-soft);
  color: var(--join-ink);
}
/* One icon per state: sent (done), closed (paused) and could not load (error) - the last two quiet. */
.join-outcome-mark svg { display: none; }
.join-outcome-mark[data-mark="done"] .join-mark-done,
.join-outcome-mark[data-mark="closed"] .join-mark-closed,
.join-outcome-mark[data-mark="error"] .join-mark-error { display: block; }
.join-outcome-mark[data-mark="closed"],
.join-outcome-mark[data-mark="error"] { background: var(--surface-3); color: var(--text-muted); }
.join-outcome h2 { margin: 0 0 10px; font-size: 1.5rem; }
.join-outcome h2:focus { outline: none; }
.join-outcome p { max-width: 52ch; margin: 0 auto 8px; color: var(--text-secondary); overflow-wrap: anywhere; }
.join-outcome .join-outcome-quiet { font-size: 0.9rem; color: var(--text-muted); }
.join-outcome-id {
  display: inline-block;
  margin: 8px 0 4px;
  padding: 6px 16px;
  border-radius: var(--radius-sm);
  background: var(--surface-1);
  border: 1px solid var(--border);
  font-family: var(--font-mono);
  font-size: 1.15rem;
  font-weight: 600;
}
.join-outcome-id[hidden] { display: none; }
.join-outcome-actions { display: flex; justify-content: center; flex-wrap: wrap; gap: 12px; margin-top: 24px; }

/* ---- loading: the sheet's shape, held ---- */
.join-skel { padding: 34px 40px; display: grid; gap: 22px; }
.join-skel .skeleton { height: 16px; }
.join-skel .join-skel-line { width: 70%; }
.join-skel .join-skel-title { width: 38%; height: 22px; }
.join-skel .join-skel-title.is-short { width: 30%; }
.join-skel-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 22px; }
.join-skel-row .skeleton { height: 44px; width: 100%; }

/* ---- the terms dialog (native <dialog>, the .confirm-dialog family) ---- */
.join-terms-dialog {
  width: min(680px, calc(100vw - 32px));
  max-height: min(760px, calc(100vh - 48px));
  padding: 0;
  overflow: hidden;
}
.join-terms-dialog[open] { display: flex; flex-direction: column; }
.join-terms-head {
  flex: none;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  padding: 22px 26px 18px;
  border-bottom: 1px solid var(--border);
}
.join-terms-head h2 { margin: 0; font-size: 1.3rem; }
.join-terms-head p { margin: 2px 0 0; font-size: 0.9rem; color: var(--text-muted); overflow-wrap: anywhere; }
.join-terms-close {
  flex: none;
  width: 36px;
  height: 36px;
  display: grid;
  place-items: center;
  background: none;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text-secondary);
  cursor: pointer;
}
/* The airline's own sanitised markup. It scrolls here, inside the dialog, and is a focusable
   region so the keyboard can scroll it. */
.join-terms-text {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: 22px 26px;
  font-size: 0.96rem;
  line-height: 1.6;
  color: var(--text-secondary);
  overflow-wrap: anywhere;
}
.join-terms-text h3, .join-terms-text h4 { color: var(--text-primary); }
.join-terms-text h4 { font-size: 14px; font-weight: 600; margin: 14px 0 6px; }
.join-terms-text a { color: var(--join-ink); text-decoration: underline; }
.join-terms-foot {
  flex: none;
  display: flex;
  justify-content: flex-end;
  padding: 16px 26px;
  border-top: 1px solid var(--border);
  background: var(--surface-1);
}

/* ---- tablet: the aside becomes a strip above the sheet ----
   Only what helps the applicant continue: the steps in a row and the terms link. No airline mark
   or name - the hero has just said it - and no sign-in link, which the sheet carries beside its
   button. */
@media (max-width: 1024px) {
  .join-grid { grid-template-columns: minmax(0, 1fr); gap: 28px; }
  .join-aside { position: static; order: -1; padding-top: 0; }
  .join-aside-ident { display: none; }
  .join-aside h2 { margin-bottom: 10px; }
  .join-steps { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; margin: 0; }
  .join-steps li { padding: 0 0 0 34px; }
  .join-steps li::after { display: none; }
  .join-aside-links { margin-top: 16px; border-top: 0; padding-top: 0; }
  .join-aside-links .join-signin { display: none; }
  .join-aside-links:has(.join-aside-terms[hidden]) { display: none; }
}

/* ---- phone ---- */
@media (max-width: 720px) {
  .join-hero { min-height: 236px; }
  .join-hero .container { padding-top: 48px; padding-bottom: 26px; }
  .join-page { padding: 24px 0 56px; }
  .join-steps { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .join-steps li { padding: 0 0 12px 34px; }
  .join-steps li:not(:last-child)::after { display: block; }
  .join-aside-links { margin-top: 14px; }
  .join-sheet { border-radius: var(--radius-md); }
  .join-lede { padding: 22px 20px 0; font-size: 1rem; }
  .join-lede:not([hidden]) + .join-section { margin-top: 22px; }
  .join-section { padding: 26px 20px; }
  .join-section-head { margin-bottom: 18px; }
  .join-fields { grid-template-columns: minmax(0, 1fr); gap: 18px; }
  .join-submit { padding: 24px 20px 28px; border-radius: 0 0 var(--radius-md) var(--radius-md); }
  .join-submit-row { flex-direction: column; align-items: stretch; }
  .join-cta { width: 100%; min-width: 0; }
  .join-signin { text-align: center; }
  .join-outcome { padding: 40px 20px; }
  .join-skel { padding: 26px 20px; }
  .join-skel-row { grid-template-columns: minmax(0, 1fr); }
  /* The dialog is a full-height sheet. */
  .join-terms-dialog { width: 100vw; max-width: 100vw; height: 100dvh; max-height: 100dvh; margin: 0; border: 0; border-radius: 0; }
  .join-terms-head { padding: 18px 20px 14px; }
  .join-terms-text { padding: 18px 20px; }
  .join-terms-foot { padding: 14px 20px; }
  .join-terms-foot .btn { width: 100%; justify-content: center; }
}

/* ==========================================================================
   Statistics page. Every colour is a theme token; no rule names a hue.

   The page is editorial, not a dashboard: figures sit on the page divided by hairlines, and a
   bordered surface is used only where something is a single object (the 30-day band, the chart,
   the map, the closing call to action). Breakpoints are the newer pages' own: 1024 and 720.
   ========================================================================== */

.stx-page {
  padding-bottom: 72px;
  /* Small accent text and the chart fill. --accent-bright washes out on a light surface, so the
     light theme uses the accent itself, darkened for small text (the Join page's rule). */
  --stx-ink: var(--accent-bright);
  --stx-fill: var(--accent-bright);
  --stx-fill-soft: color-mix(in srgb, var(--accent-bright) 34%, var(--surface-3));
  --stx-up: var(--success);
}
[data-theme="light"] .stx-page,
[data-theme="light"] .page-intro {
  --stx-ink: color-mix(in srgb, var(--accent) 80%, #000000);
  --stx-fill: var(--accent);
  --stx-fill-soft: color-mix(in srgb, var(--accent) 30%, var(--surface-3));
  --stx-up: color-mix(in srgb, var(--success) 58%, #000000);
}

.stx-eyebrow {
  margin: 0 0 8px;
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--stx-ink);
}
.stx-quiet { color: var(--text-muted); font-size: 0.88rem; }
.stx-mono { font-family: var(--font-mono); font-size: 0.92em; text-transform: uppercase; }

/* ---- 1. identity and the lifetime figures ---- */

/* The glow behind the header is the site-wide one on body. */
.stx-intro {
  padding: var(--page-top) 0 0;
}
.stx-ident {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 28px 64px;
  align-items: end;
}
.stx-intro h1,
.page-intro h1 {
  margin: 0;
  font-size: var(--page-title-size);
  line-height: 1.1;
  letter-spacing: -0.02em;
  text-wrap: balance;
}
.stx-desc, .page-lede { margin: 14px 0 0; max-width: 58ch; color: var(--text-secondary); font-size: 1.05rem; }
.stx-facts { display: grid; grid-template-columns: repeat(2, auto); gap: 14px 40px; margin: 0; }
.stx-facts dt { font-size: 0.72rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-muted); }
.stx-facts dd { margin: 1px 0 0; font-weight: 600; }
.stx-hubs { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 22px; }
.stx-hubs-label { font-size: 0.72rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-muted); margin-right: 4px; }
.stx-hub {
  display: inline-flex; align-items: baseline; gap: 7px;
  padding: 3px 12px; border: 1px solid var(--border-strong); border-radius: 999px;
  font-size: 0.86rem; color: var(--text-secondary);
}
a.stx-hub:hover { text-decoration: none; border-color: var(--stx-ink); color: var(--text-primary); }
.stx-hub b { font-family: var(--font-mono); font-weight: 600; color: var(--text-primary); }

/* The three lifetime figures: the largest type on the site, on the page itself. */
.stx-lead {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  margin-top: 46px;
  border-top: 1px solid var(--border);
}
.stx-lead-fig { padding: 30px 32px 30px 0; min-width: 0; }
.stx-lead-fig + .stx-lead-fig { padding-left: 32px; border-left: 1px solid var(--border); }
.stx-lead-value {
  font-size: clamp(2.7rem, 6.3vw, 4.8rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.045em;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.stx-lead-unit { margin-left: 0.2em; font-size: 0.4em; font-weight: 600; letter-spacing: -0.01em; color: var(--text-secondary); }
.stx-lead-label { margin-top: 12px; font-weight: 600; }
.stx-lead-note { color: var(--text-muted); font-size: 0.9rem; }

.stx-second {
  display: grid;
  grid-template-columns: repeat(var(--stx-second-count, 5), minmax(0, 1fr));
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}
.stx-second-fig, .page-figs li { padding: 18px 16px 18px 0; min-width: 0; }
.stx-second-value, .page-figs strong { font-size: 1.55rem; font-weight: 700; letter-spacing: -0.02em; line-height: 1.15; font-variant-numeric: tabular-nums; }
.stx-second-label, .page-figs span { color: var(--text-muted); font-size: 0.88rem; }

/* The page intro, shared with Fleet. The Statistics intro's own rules are grouped with these
   above; the page's accent ink is the Statistics page's token. */
.page-intro { padding-top: var(--page-top); --stx-ink: var(--accent-bright); }
.page-figs {
  list-style: none;
  margin: 40px 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(var(--page-figs-count, 4), minmax(0, 1fr));
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}
/* Held at its final height while the figures load, so nothing below it moves. */
.page-figs:empty { min-height: 78px; }
.page-figs li { display: flex; flex-direction: column; }
.page-figs strong { display: block; }

/* ---- sections ---- */

.stx-section { padding-top: 68px; }
.stx-section > .home-head { margin-bottom: 24px; }

.stx-panel {
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 26px 28px;
}

/* ---- 2. the last 30 days ---- */

.stx-pulse { margin-top: 40px; }
.stx-pulse-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 14px; margin-bottom: 20px; }
.stx-pulse-head h2 { margin: 0; font-size: 1.2rem; letter-spacing: -0.01em; }
.stx-live {
  margin-left: auto;
  display: inline-flex; align-items: center; gap: 9px;
  font-size: 0.88rem; font-weight: 600; color: var(--text-primary);
}
a.stx-live:hover { text-decoration: none; color: var(--stx-ink); }
.stx-live::before {
  content: ""; width: 8px; height: 8px; border-radius: 50%;
  background: var(--success);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--success) 22%, transparent);
}
.stx-pulse-figs { display: grid; grid-template-columns: repeat(var(--stx-pulse-count, 5), minmax(0, 1fr)); }
.stx-pulse-fig { padding: 0 20px; border-left: 1px solid var(--border); min-width: 0; }
.stx-pulse-fig:first-child { padding-left: 0; border-left: 0; }
.stx-pulse-value { font-size: 2rem; font-weight: 700; letter-spacing: -0.025em; line-height: 1.1; font-variant-numeric: tabular-nums; white-space: nowrap; }
.stx-pulse-value small { font-size: 0.5em; font-weight: 600; color: var(--text-secondary); margin-left: 0.2em; letter-spacing: 0; }
.stx-pulse-label { color: var(--text-secondary); font-size: 0.9rem; }
/* The change on the 30 days before. A percentage only when the earlier figure is large enough
   to make one meaningful; otherwise the earlier figure in words, or nothing at all. */
.stx-delta { margin: 8px 0 0; font-size: 0.8rem; color: var(--text-muted); }
.stx-delta b { font-weight: 600; color: var(--text-secondary); }
.stx-delta.is-up b { color: var(--stx-up); }

/* ---- 3. activity over time ---- */

.stx-chart-head { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 16px; }
.stx-chart-head h2 { margin: 0; font-size: 1.2rem; letter-spacing: -0.01em; }
.stx-chart-controls { margin-left: auto; display: flex; flex-wrap: wrap; gap: 10px; }
.stx-chart-sum { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 18px; margin: 20px 0 0; }
.stx-chart-total { font-size: 2rem; font-weight: 700; letter-spacing: -0.025em; line-height: 1.1; font-variant-numeric: tabular-nums; }
.stx-chart-total small { font-size: 0.48em; font-weight: 600; color: var(--text-secondary); letter-spacing: 0; margin-left: 0.3em; }

/* One bar per month (or per year, All time). The plot has a fixed height so the page never
   moves when the figures arrive; the figures are also in a visually hidden table. */
.stx-bars {
  display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr);
  gap: 10px; align-items: end;
  height: 236px; margin-top: 18px;
  border-bottom: 1px solid var(--border-strong);
}
.stx-bar-col { display: flex; flex-direction: column; justify-content: flex-end; align-items: center; height: 100%; min-width: 0; }
.stx-bar-val { margin-bottom: 6px; font-size: 0.74rem; color: var(--text-muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
/* --stx-v is the bar's share of the tallest bar (0 to 1); 26px is kept clear for the figure above it. */
.stx-bar { width: 100%; max-width: 64px; height: calc(var(--stx-v, 0) * (100% - 26px)); min-height: 2px; border-radius: 5px 5px 0 0; background: var(--stx-fill); }
.stx-bar-col.is-peak .stx-bar-val { color: var(--text-primary); font-weight: 700; }
/* The month in progress: hatched, and named in words under the chart. */
.stx-bar-col.is-partial .stx-bar {
  background: repeating-linear-gradient(135deg, var(--stx-fill) 0 5px, var(--stx-fill-soft) 5px 10px);
}
.stx-bar-col.is-zero .stx-bar { height: 2px; border-radius: 0; background: var(--border-strong); }
.stx-bars-x {
  display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: 10px;
  margin-top: 8px; font-size: 0.76rem; color: var(--text-muted); text-align: center;
}
.stx-bars-x span { min-width: 0; white-space: nowrap; }
.stx-chart-note { margin: 14px 0 0; font-size: 0.82rem; color: var(--text-muted); }
/* Before there are three months to draw. */
.stx-chart-wait { margin: 14px 0 0; color: var(--text-secondary); max-width: 62ch; }

/* ---- 4. the network ---- */

.stx-network { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: 32px; align-items: start; }
.stx-map {
  position: relative; overflow: hidden;
  aspect-ratio: 4 / 3;
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  background: var(--surface-2);
}
.stx-map-figs {
  position: absolute; left: 14px; top: 14px; z-index: 2;
  display: flex; gap: 22px;
  padding: 10px 16px;
  border: 1px solid var(--border); border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--surface-1) 92%, transparent);
}
.stx-map-fig b { display: block; font-size: 1.25rem; font-weight: 700; letter-spacing: -0.02em; line-height: 1.15; font-variant-numeric: tabular-nums; }
.stx-map-fig span { font-size: 0.78rem; color: var(--text-muted); }
.stx-map-key { margin: 10px 0 0; font-size: 0.8rem; color: var(--text-muted); }
.stx-map + .stx-map-key + .act-map-fallback { margin-top: 0; }
.stx-lists { display: grid; gap: 30px; }
.stx-list-head { display: flex; align-items: baseline; gap: 12px; margin: 0 0 4px; }
.stx-list-head h3 { margin: 0; font-size: 1.02rem; }
.stx-list-head span { margin-left: auto; font-size: 0.78rem; color: var(--text-muted); }
.stx-rank { list-style: none; margin: 0; padding: 0; }
.stx-rank li {
  display: grid; grid-template-columns: 20px minmax(0, 1fr) auto; gap: 0 12px; align-items: baseline;
  padding: 10px 0 11px; border-top: 1px solid var(--border);
}
.stx-rank-n { font-size: 0.78rem; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.stx-rank-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.stx-rank-name b { font-family: var(--font-mono); font-weight: 600; margin-right: 8px; }
.stx-rank-name span { color: var(--text-muted); font-size: 0.9rem; }
.stx-rank-count { font-weight: 600; font-variant-numeric: tabular-nums; }
.stx-track { grid-column: 2 / -1; height: 4px; margin-top: 7px; border-radius: 2px; background: var(--surface-3); }
.stx-track span { display: block; height: 4px; border-radius: 2px; background: var(--stx-fill); }
.stx-more { margin-top: 10px; padding: 0; border: 0; background: none; font: inherit; font-size: 0.86rem; font-weight: 600; color: var(--stx-ink); cursor: pointer; }
.stx-more:focus-visible { outline: 2px solid var(--stx-ink); outline-offset: 3px; border-radius: 4px; }

/* ---- 5. the fleet ---- */

.stx-fleet { display: grid; grid-template-columns: minmax(0, 4fr) minmax(0, 8fr); gap: 48px; align-items: start; }
.stx-callout { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 20px; align-items: center; }
/* The share of all flying, as a ring. The same figure is in the sentence beside it. */
.stx-ring {
  --stx-share: 0%;
  width: 104px; height: 104px; border-radius: 50%;
  display: grid; place-items: center;
  background: conic-gradient(var(--stx-fill) 0 var(--stx-share), var(--surface-3) 0);
  font-size: 1.3rem; font-weight: 700; letter-spacing: -0.02em;
  position: relative; isolation: isolate;
}
.stx-ring::before { content: ""; position: absolute; inset: 12px; border-radius: 50%; background: var(--bg); z-index: -1; }
.stx-callout-title { font-size: 1.7rem; font-weight: 700; letter-spacing: -0.02em; line-height: 1.12; }
.stx-callout-sub { margin-top: 6px; color: var(--text-secondary); }
.stx-fleet-facts { grid-column: 1 / -1; display: flex; gap: 32px; padding-top: 18px; margin-top: 4px; border-top: 1px solid var(--border); }
.stx-fleet-facts b { display: block; font-size: 1.4rem; font-weight: 700; letter-spacing: -0.02em; line-height: 1.15; }
.stx-fleet-facts span { color: var(--text-muted); font-size: 0.86rem; }
.stx-types-head { display: flex; align-items: center; gap: 12px; margin-bottom: 6px; }
.stx-types-head h3 { margin: 0; font-size: 1.02rem; }
.stx-types-head .fd-seg { margin-left: auto; }
.stx-types { list-style: none; margin: 0; padding: 0; }
.stx-types li {
  display: grid; grid-template-columns: minmax(0, 190px) minmax(0, 1fr) 74px 82px; gap: 14px; align-items: center;
  padding: 9px 0; border-top: 1px solid var(--border);
}
.stx-type-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.stx-type-name b { font-family: var(--font-mono); font-weight: 600; margin-right: 8px; }
.stx-type-name span { color: var(--text-muted); font-size: 0.9rem; }
.stx-types .stx-track { grid-column: auto; margin-top: 0; height: 8px; border-radius: 4px; }
.stx-types .stx-track span { height: 8px; border-radius: 4px; }
.stx-type-fig { text-align: right; font-variant-numeric: tabular-nums; font-weight: 600; white-space: nowrap; }
.stx-type-fig.is-quiet { font-weight: 400; color: var(--text-muted); font-size: 0.9rem; }
.stx-types li.is-other .stx-track span { background: var(--stx-fill-soft); }

/* ---- 6. pilots and operations: three columns of fact, divided by hairlines ---- */

.stx-cols { display: grid; grid-template-columns: repeat(var(--stx-cols, 3), minmax(0, 1fr)); border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); }
.stx-col { padding: 28px 30px; min-width: 0; }
.stx-col:first-child { padding-left: 0; }
.stx-col:last-child { padding-right: 0; }
.stx-col + .stx-col { border-left: 1px solid var(--border); }
.stx-big { font-size: 2.3rem; font-weight: 700; letter-spacing: -0.03em; line-height: 1.05; font-variant-numeric: tabular-nums; white-space: nowrap; }
.stx-big small { font-size: 0.46em; font-weight: 600; color: var(--text-secondary); letter-spacing: 0; margin-left: 0.25em; }
.stx-big-label { margin-top: 4px; font-weight: 600; }
.stx-fact { margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--border); }
.stx-fact-title { font-size: 0.9rem; font-weight: 600; margin-bottom: 8px; }
.stx-pair { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
.stx-mid { font-size: 1.45rem; font-weight: 700; letter-spacing: -0.02em; line-height: 1.15; font-variant-numeric: tabular-nums; white-space: nowrap; }
.stx-mid small { font-size: 0.6em; font-weight: 600; color: var(--text-secondary); margin-left: 0.2em; }
.stx-hubrow { display: grid; grid-template-columns: 54px minmax(0, 1fr) 34px; gap: 10px; align-items: center; padding: 5px 0; font-size: 0.9rem; }
.stx-hubrow b { font-family: var(--font-mono); font-weight: 600; }
.stx-hubrow .stx-track { grid-column: auto; margin-top: 0; }
.stx-hubrow em { font-style: normal; text-align: right; font-variant-numeric: tabular-nums; }
/* Scheduled against charter and free flights: one bar in two parts, with both figures in words. */
.stx-split { display: flex; gap: 2px; height: 10px; border-radius: 5px; overflow: hidden; }
.stx-split span { display: block; height: 10px; background: var(--stx-fill); }
.stx-split span + span { background: var(--stx-fill-soft); }
.stx-legend { display: grid; gap: 4px; margin: 10px 0 0; padding: 0; list-style: none; font-size: 0.88rem; }
.stx-legend li { display: flex; align-items: baseline; gap: 8px; }
.stx-legend li::before { content: ""; width: 8px; height: 8px; border-radius: 2px; background: var(--stx-fill); flex: none; }
.stx-legend li + li::before { background: var(--stx-fill-soft); }
.stx-legend em { margin-left: auto; font-style: normal; color: var(--text-muted); font-variant-numeric: tabular-nums; }

/* ---- 7. records and milestones ---- */

.stx-records { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: 56px; align-items: start; }
.stx-record-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 32px; margin: 0; }
.stx-record { padding: 18px 0 20px; border-top: 1px solid var(--border); min-width: 0; }
.stx-record dt { font-size: 0.72rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-muted); }
.stx-record dd { margin: 4px 0 0; }
.stx-record-value { font-size: 1.5rem; font-weight: 700; letter-spacing: -0.02em; line-height: 1.15; }
.stx-record-detail { color: var(--text-secondary); font-size: 0.9rem; }
.stx-miles { list-style: none; margin: 6px 0 0; padding: 0; border-left: 2px solid var(--border); }
.stx-miles li { position: relative; padding: 0 0 20px 22px; }
.stx-miles li:last-child { padding-bottom: 0; }
.stx-miles li::before {
  content: ""; position: absolute; left: -7px; top: 6px;
  width: 12px; height: 12px; border-radius: 50%;
  background: var(--stx-fill); border: 2px solid var(--bg);
}
.stx-miles li.is-next::before { background: var(--bg); border: 2px dashed var(--border-strong); }
.stx-miles b { display: block; font-size: 1.05rem; }
.stx-miles span { color: var(--text-muted); font-size: 0.88rem; }

/* ---- closing: join, and how the figures are counted ---- */

.stx-cta {
  display: flex; flex-wrap: wrap; align-items: center; gap: 18px 28px;
  margin-top: 68px; padding: 30px 32px;
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  background: linear-gradient(110deg, var(--accent-soft), transparent 62%), var(--surface-1);
}
.stx-cta h2 { margin: 0; font-size: 1.45rem; letter-spacing: -0.015em; }
.stx-cta p { margin: 4px 0 0; color: var(--text-secondary); }
.stx-cta-actions { margin-left: auto; display: flex; flex-wrap: wrap; gap: 10px; }
.stx-footnote { margin: 26px 0 0; font-size: 0.82rem; color: var(--text-muted); }

/* ---- a new airline: no flights yet ---- */

.stx-start { padding: 40px 0 0; margin-top: 40px; border-top: 1px solid var(--border); }
.stx-start h2 { margin: 0; font-size: 1.6rem; letter-spacing: -0.015em; }
.stx-start p { margin: 10px 0 0; max-width: 60ch; color: var(--text-secondary); }
.stx-have { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); margin-top: 32px; border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); }
.stx-have > a, .stx-have > div { display: block; padding: 22px 20px 22px 0; color: inherit; min-width: 0; }
.stx-have a:hover { text-decoration: none; }
.stx-have a:hover .stx-have-label { color: var(--stx-ink); }
.stx-have-value { font-size: 2.3rem; font-weight: 700; letter-spacing: -0.03em; line-height: 1.05; }
.stx-have-label { color: var(--text-muted); font-size: 0.9rem; }

/* ---- loading: every block at its final size ---- */

/* Two classes on every rule: the template's own .skeleton:nth-child widths must not win. */
.stx-skel .skeleton { margin: 0; width: 100%; }
.stx-skel .stx-skel-plot { height: 236px; margin-top: 18px !important; border-radius: var(--radius-md); }
.stx-skel .stx-skel-map { aspect-ratio: 4 / 3; height: auto; border-radius: var(--radius-lg); }
.stx-skel .stx-skel-row { height: 20px; margin: 16px 0 0 !important; }
.stx-error { margin-top: 40px; padding: 48px 24px; text-align: center; border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); }
.stx-error h2 { margin: 0; font-size: 1.3rem; }
.stx-error p { margin: 8px 0 18px; color: var(--text-secondary); }

/* ---- tablet ---- */

@media (max-width: 1024px) {
  .stx-ident { grid-template-columns: minmax(0, 1fr); }
  .stx-facts { grid-template-columns: repeat(4, auto); justify-content: start; }
  .stx-second { grid-template-columns: repeat(3, minmax(0, 1fr)); border-bottom: 0; }
  .stx-second-fig { border-bottom: 1px solid var(--border); }
  .stx-pulse-figs { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 22px 0; }
  .stx-pulse-fig:nth-child(3n + 1) { padding-left: 0; border-left: 0; }
  .stx-network { grid-template-columns: minmax(0, 1fr); }
  .stx-map { aspect-ratio: 16 / 10; }
  .stx-lists { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 32px; }
  .stx-fleet { grid-template-columns: minmax(0, 1fr); gap: 32px; }
  .stx-col { padding: 24px 22px; }
  .stx-records { grid-template-columns: minmax(0, 1fr); gap: 36px; }
}

/* ---- phone ---- */

@media (max-width: 720px) {
  .stx-facts { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px 20px; }
  .stx-lead { grid-template-columns: minmax(0, 1fr); margin-top: 32px; }
  .stx-lead-fig, .stx-lead-fig + .stx-lead-fig { padding: 22px 0; border-left: 0; }
  .stx-lead-fig + .stx-lead-fig { border-top: 1px solid var(--border); }
  .stx-lead-value { font-size: clamp(3rem, 15vw, 3.8rem); }
  .stx-second, .page-figs { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .stx-second-fig:last-child:nth-child(odd) { grid-column: 1 / -1; }
  .stx-section { padding-top: 52px; }
  .stx-panel { padding: 20px 18px; border-radius: var(--radius-md); }
  .stx-pulse { margin-top: 28px; }
  .stx-live { margin-left: 0; flex-basis: 100%; margin-top: 4px; }
  .stx-pulse-figs { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px 0; }
  .stx-pulse-fig:nth-child(3n + 1) { padding-left: 20px; border-left: 1px solid var(--border); }
  .stx-pulse-fig:nth-child(odd) { padding-left: 0; border-left: 0; }
  .stx-pulse-value { font-size: 1.7rem; }
  .stx-chart-controls { margin-left: 0; flex-basis: 100%; }
  .stx-chart-controls .fd-seg { flex: 1 0 100%; }
  .stx-chart-controls .fd-seg button { flex: 1; padding: 0 6px; height: 40px; white-space: nowrap; }
  /* Twelve bars stay twelve bars. Only the peak keeps its figure and every second month its
     label; the full figures are in the sentence above and the table for assistive technology. */
  .stx-bars { gap: 5px; height: 190px; }
  .stx-bars-x { gap: 5px; font-size: 0.72rem; }
  .stx-bar-val { display: none; }
  .stx-bar-col.is-peak .stx-bar-val { display: block; }
  .stx-bars.is-months + .stx-bars-x span:nth-child(even) { visibility: hidden; }
  .stx-map { aspect-ratio: 1 / 1; border-radius: var(--radius-md); }
  .stx-map-figs { gap: 16px; padding: 8px 12px; }
  .stx-lists { grid-template-columns: minmax(0, 1fr); }
  .stx-callout { grid-template-columns: auto minmax(0, 1fr); }
  .stx-types li { grid-template-columns: minmax(0, 1fr) auto auto; gap: 4px 14px; }
  .stx-types .stx-track { grid-column: 1 / -1; grid-row: 2; }
  .stx-cols { grid-template-columns: minmax(0, 1fr); }
  .stx-col, .stx-col:first-child, .stx-col:last-child { padding: 24px 0; }
  .stx-col + .stx-col { border-left: 0; border-top: 1px solid var(--border); }
  .stx-record-grid { grid-template-columns: minmax(0, 1fr); }
  .stx-cta { padding: 24px 20px; margin-top: 52px; }
  .stx-cta-actions { margin-left: 0; width: 100%; }
  .stx-cta-actions .btn { flex: 1; justify-content: center; text-align: center; }
  .stx-have { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* The only movement on the page is the bars and tracks growing once, and it is off here. */
@media (prefers-reduced-motion: no-preference) {
  .stx-animate .stx-bar, .stx-animate .stx-track span { transform-origin: bottom left; animation: stx-grow 0.5s ease-out both; }
}
@keyframes stx-grow { from { transform: scaleY(0.02); } }

/* A figure keeps its number on one line, but its small unit may drop beneath it when the column is
   too narrow for both: a 30-day distance ("218,400 nm") can run out of its cell at 320px, and a
   big airline's lifetime distance ("746.3M nm") out of its column at 768px. Shrinking the type
   would shrink every airline's figures for an edge case. */
.stx-lead-value, .stx-pulse-value, .stx-big, .stx-mid { white-space: normal; }
.stx-lead-unit, .stx-pulse-value small, .stx-big small, .stx-mid small { display: inline-block; }
/* The narrowest phones: a five-digit 30-day figure ("55,668") is wider than its half of the band. */
@media (max-width: 360px) { .stx-pulse-value { font-size: 1.45rem; } }

/* Notices. These rules sit after the Events and Tours rules on purpose: .notice-grid and the
   notice heads restyle .act-grid and .act-card-head-plain at the same specificity - placed
   earlier, the activity rules win and the grid goes back to three columns. The Notices page is
   a two-column grid of cards (Tours and Events use three: a notice is a headline and two lines,
   and reads better wide); the notice has its own page; the dashboard shows ONE compact notice.
   Every colour is a theme token, so the tenant accent and the light / dark themes apply. Severity
   is always a word plus an icon, never colour alone. */

/* The full-list page's paging control. Centred under the grid, and present only while there
   is genuinely more - the server bounds every page, so an airline past the ceiling would
   otherwise lose its older notices with nothing on screen saying so. */
.notices-more {
  display: flex;
  justify-content: center;
  margin-top: 16px;
}

/* ------------------------------------------------------------ the Notices page: cards */
/* The hairline rings of an image-less head: the accent, a little stronger than --accent-soft. */
.notice-card-head-plain, .notice-hero .detail-hero-plain { --notice-ring: color-mix(in srgb, var(--accent-bright) 26%, transparent); }
.notice-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); margin-top: 28px; }
.notice-grid .act-card-head { height: 150px; }
a.notice-card { color: inherit; text-decoration: none; }
a.notice-card:hover { text-decoration: none; }
a.notice-card:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 2px; }

/* The head of a notice WITHOUT an image. The same height as a photo head, so a row of cards
   stays level; a quiet accent tint, a beacon of hairline rings and the notice-type icon. */
.notice-card-head-plain {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  padding: 0 43px;
  background:
    radial-gradient(circle at calc(100% - 75px) 50%, transparent 0 51px, var(--notice-ring) 51px 52px, transparent 52px 86px, var(--notice-ring) 86px 87px, transparent 87px 126px, var(--notice-ring) 126px 127px, transparent 127px),
    radial-gradient(460px 170px at 10% 0%, var(--accent-soft), transparent 72%),
    var(--surface-1);
}
.notice-glyph { width: 64px; height: 64px; color: var(--accent-bright); opacity: 0.7; }
.notice-glyph-warning { color: var(--warning); }
.notice-glyph-critical { color: var(--danger); }

.notice-card .list-card-body { gap: 10px; padding: 1rem 1.2rem 1.1rem; }
.notice-card-meta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.notice-card-date { margin-left: auto; font-size: 0.8rem; color: var(--text-muted); white-space: nowrap; }
.notice-card .list-card-name {
  font-size: 1.18rem;
  line-height: 1.3;
  overflow-wrap: anywhere;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
}
.notice-card-excerpt {
  margin: 0;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
}
.notice-card-state { display: inline-flex; align-items: center; gap: 6px; color: var(--text-muted); }
.notice-card-state-ok { color: var(--success); }
.notice-card-state-due { color: var(--warning); }
.notice-card-go { margin-left: auto; color: var(--accent-bright); font-weight: 600; white-space: nowrap; }
a.notice-card:hover .notice-card-go { text-decoration: underline; }
.badge .badge-icon { width: 12px; height: 12px; flex: none; }

/* ------------------------------------------------------------ the notice page */
.notice-hero .act-hero-title { font-size: clamp(1.7rem, 3.6vw, 2.5rem); line-height: 1.12; max-width: 30ch; overflow-wrap: anywhere; }
.notice-hero .detail-hero-media img { height: 320px; }
.notice-hero .detail-hero-plain {
  background:
    radial-gradient(circle at calc(100% - 110px) 50%, transparent 0 58px, var(--notice-ring) 58px 59px, transparent 59px 100px, var(--notice-ring) 100px 101px, transparent 101px 148px, var(--notice-ring) 148px 149px, transparent 149px),
    radial-gradient(900px 300px at 15% 0%, var(--accent-soft), transparent 70%),
    var(--surface-1);
}
.notice-hero .detail-hero-plain .detail-hero-ident { padding: 1.9rem 220px 1.7rem 2rem; }
.notice-hero-glyph { position: absolute; right: 74px; top: 50%; transform: translateY(-50%); width: 72px; height: 72px; }
.notice-body { padding: 1.7rem 2rem 1.9rem; }
.notice-body .act-prose { max-width: 72ch; font-size: 1rem; color: var(--text-primary); }
.notice-body .act-prose a { color: var(--accent-bright); }

/* The must-read control, at the foot of the notice. */
.notice-ack {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  max-width: 72ch;
  margin-top: 22px;
  padding: 14px 16px;
  border-radius: var(--radius-md);
  border: 1px solid color-mix(in srgb, var(--warning) 40%, var(--border));
  background: color-mix(in srgb, var(--warning) 7%, transparent);
}
.notice-ack-text { flex: 1; min-width: 200px; font-size: 0.9rem; }
.notice-ack-text strong { display: block; }
.notice-ack-text span { color: var(--text-secondary); }
.notice-ack-done { border-color: color-mix(in srgb, var(--success) 40%, var(--border)); background: color-mix(in srgb, var(--success) 7%, transparent); }
.notice-ack-done strong { color: var(--success); }
.notice-foot { margin: 1.1rem 0 0; font-size: 0.91rem; }

/* ------------------------------------------------------------ the dashboard notice */
.dash-notice {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 12px 10px 12px 14px;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
}
.dash-notice-must { border-color: color-mix(in srgb, var(--warning) 45%, var(--border)); }
.dash-notice-icon {
  flex: none;
  width: 36px;
  height: 36px;
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--accent-soft);
  color: var(--accent-bright);
}
.dash-notice-icon svg { width: 19px; height: 19px; }
.dash-notice-warning .dash-notice-icon { background: color-mix(in srgb, var(--warning) 14%, transparent); color: var(--warning); }
.dash-notice-critical .dash-notice-icon { background: color-mix(in srgb, var(--danger) 14%, transparent); color: var(--danger); }
.dash-notice-main { flex: 1; min-width: 0; display: grid; gap: 4px; }
.dash-notice-top { display: flex; align-items: center; gap: 10px; min-width: 0; }
.dash-notice-title {
  min-width: 0;
  font-weight: 600;
  color: var(--text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.dash-notice-date { margin-left: auto; font-size: 0.78rem; color: var(--text-muted); white-space: nowrap; }
.dash-notice-sub { display: flex; align-items: baseline; gap: 16px; min-width: 0; font-size: 0.86rem; }
.dash-notice-excerpt { flex: 1; min-width: 0; color: var(--text-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dash-notice-acts { display: flex; gap: 16px; white-space: nowrap; font-size: 0.82rem; font-weight: 600; }
.dash-notice-more { color: var(--text-secondary); }
.dash-notice-read { color: var(--accent-bright); }
.dash-notice-dismiss {
  flex: none;
  width: 32px;
  height: 32px;
  margin-top: -2px;
  border: none;
  border-radius: 8px;
  background: none;
  color: var(--text-muted);
  font-size: 21px;
  line-height: 1;
  cursor: pointer;
}
.dash-notice-dismiss:hover { background: var(--surface-3); color: var(--text-primary); }
.dash-notice-dismiss:focus-visible, .dash-notice-title:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 2px; }

@media (max-width: 720px) {
  .notice-grid { grid-template-columns: minmax(0, 1fr); }
  .notice-grid .act-card-head { height: 132px; }
  .notice-hero .detail-hero-media img { height: 200px; }
  .notice-hero .detail-hero-plain .detail-hero-ident { padding: 1.4rem 96px 1.3rem 1.2rem; }
  .notice-hero-glyph { right: 22px; width: 48px; height: 48px; }
  .notice-hero .detail-hero-plain { background: radial-gradient(circle at calc(100% - 46px) 50%, transparent 0 40px, var(--notice-ring) 40px 41px, transparent 41px 70px, var(--notice-ring) 70px 71px, transparent 71px), radial-gradient(900px 300px at 15% 0%, var(--accent-soft), transparent 70%), var(--surface-1); }
  .notice-body { padding: 1.2rem 1.2rem 1.4rem; }
  .notice-ack .btn { width: 100%; }
}
@media (max-width: 640px) {
  .dash-notice-top { flex-wrap: wrap; row-gap: 4px; }
  .dash-notice-title {
    order: 3;
    flex-basis: 100%;
    white-space: normal;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
  }
  .dash-notice-sub { flex-direction: column; gap: 6px; }
  .dash-notice-excerpt { width: 100%; }
  .dash-notice-dismiss { width: 44px; height: 44px; margin: -8px -6px 0 -6px; }
  .dash-notice-acts a { padding: 6px 0; }
}

/* A dismiss that did not save keeps the card and says so in one short line. */
.dash-notice-error { margin: 2px 0 0; font-size: 0.82rem; color: var(--danger); }
/* Nothing posted, or the section off: the same gap under the heading as the grid. */
.notices-empty { margin-top: 26px; }

/* ============================================================================================
   The public Team page. Every colour is a theme token, so the tenant accent and the light / dark
   themes apply.

   The page is built on the shared page primitives (act-page, act-head, act-title, act-lede,
   act-grid, list-card, list-card-body, act-card-foot, fd-empty, act-loading / skeleton) and the
   pilot identity primitive (pilot-avatar, pilot-avatar-lg, pilot-avatar-initials / -image). Only
   what the Team page alone needs is here, and each rule names the shipped pattern it extends.
   ============================================================================================ */

/* ------------------------------------------------------------ the grid (the Events / Tours grid) */
/* Two columns, not the three Tours and Events use: a person is a face, a name, a title and a
   paragraph, and a paragraph reads better wide. One column from 720px (the act-grid phone rule). */
.team-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); margin-top: 28px; }
@media (max-width: 720px) {
  .team-grid { grid-template-columns: minmax(0, 1fr); }
}

/* ------------------------------------------------------------ the card (the list card) */
.team-card .list-card-body { padding: 1.35rem 1.45rem 1.25rem; gap: 0; }

/* The head: the face beside the name. The avatar is the shared primitive at its large size; it
   never sizes itself to its contents, so a card does not move when the picture arrives. */
.team-card-head { display: flex; align-items: flex-start; gap: 18px; min-width: 0; }
.team-card-avatar { flex: none; }
.team-card-ident { min-width: 0; padding-top: 6px; }
.team-card-name {
  margin: 0;
  font-size: 1.22rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1.2;
  overflow-wrap: anywhere;
}
/* The public title is the one accented line on the card: it is the person's organisational
   identity, and the only thing the page says about them the roster does not. */
.team-card-title {
  margin-top: 4px;
  font-size: 0.86rem;
  font-weight: 600;
  line-height: 1.35;
  color: var(--accent-bright);
  overflow-wrap: anywhere;
}
/* The linked pilot's number and base, in mono because they are codes - and only when the airline
   publishes pilot names, so the line is absent far more often than it is drawn. */
.team-card-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 10px;
  margin-top: 7px;
  font-family: var(--font-mono);
  font-size: 0.76rem;
  color: var(--text-muted);
}

/* The biography: plain text, at most 400 characters, in full. There is no detail page to read the
   rest on, so nothing is clamped; pre-line keeps the paragraph breaks the admin typed. */
.team-card-bio {
  margin: 14px 0 0;
  font-size: 0.94rem;
  line-height: 1.55;
  color: var(--text-secondary);
  white-space: pre-line;
  overflow-wrap: anywhere;
}

/* The foot (the Events / Tours card foot) holds the one action, and only exists when there is one:
   the pilot's public profile, when the airline runs public profiles and this pilot has one. */
.team-card-foot { margin-top: 16px; }

/* The empty, not-published and failed states sit the same distance under the heading as the grid
   (the same gap as .notices-empty). */
.team-list > .fd-empty, .team-list > .state { margin-top: 26px; }

/* ------------------------------------------------------------ loading (the activity-view shape) */
/* The card's own shape while the list loads: a circle and four lines, at the card's final size.
   The bars take one tone up from the card (surface-3 shimmering to the border tone): the generic
   bar is surface-2 on a surface-2 card, which on this page would leave a 96px circle invisible. */
.team-skel-card .skeleton {
  background: linear-gradient(90deg, var(--surface-3) 25%, var(--border-strong) 50%, var(--surface-3) 75%);
  background-size: 200% 100%;
}
@media (prefers-reduced-motion: reduce) {
  .team-skel-card .skeleton { background: var(--surface-3); }
}
.team-skel-card .list-card-body { padding: 1.35rem 1.45rem 1.25rem; }
.team-skel-head { display: flex; gap: 18px; align-items: flex-start; }
.team-skel-circle { width: 96px; height: 96px; border-radius: 50%; margin: 0; flex: none; }
.team-skel-ident { flex: 1; display: grid; gap: 10px; align-content: start; padding-top: 10px; }
.team-skel-ident .act-skel-name { width: 55%; }
.team-skel-ident .act-skel-line { width: 40%; }
.team-skel-bio { display: grid; gap: 10px; margin-top: 18px; }
.team-skel-bio .act-skel-line { width: 100%; }
.team-skel-bio .act-skel-short { width: 62%; }

/* ------------------------------------------------------------ phone */
@media (max-width: 720px) {
  .team-card .list-card-body { padding: 1.1rem 1.1rem 1.05rem; }
  .team-card-head { gap: 14px; }
  .team-card-avatar .pilot-avatar-lg, .team-skel-circle { width: 72px; height: 72px; font-size: 1.3rem; }
  .team-card-ident { padding-top: 2px; }
  .team-card-name { font-size: 1.12rem; }
  /* A 44px target on a phone (the hub page rule). */
  .team-page .btn-sm { min-height: 44px; }
}

/* ---- Targets & Challenges ---- */

/* The hubs list card: the hub's monthly target under its flown figure, in the card's foot. */
.hub-card-target { display: grid; gap: 6px; flex: 1; min-width: 0; margin-right: 12px; }
.hub-card-target .thin-bar, .hub-card-target .thin-bar-fill { height: 5px; border-radius: 3px; }
.hub-card-target-line { font-size: 0.84rem; color: var(--text-secondary); font-variant-numeric: tabular-nums; }
.hub-card-target-line strong { color: var(--text-primary); font-weight: 700; }

/* The Monthly competition table on the hub page: the hub comparison grid, with each hub's
   eligibility under its name and ineligible rows beneath the ranked ones. An unlisted hub has
   figures and no name. */
.hub-cmp-out { color: var(--text-muted); }
.hub-cmp-out .hub-cmp-name a, .hub-cmp-out .hub-cmp-name strong { color: var(--text-secondary); }
.hub-cmp-reason { font-size: 0.78rem; color: var(--text-muted); }
.hub-cmp-unlisted { font-style: italic; color: var(--text-secondary); }
.hub-cmp-eligible { font-size: 0.78rem; color: var(--success); }
.hub-cmp-divider { display: block; padding: 10px 0 4px; font-size: 0.69rem; font-weight: 600; letter-spacing: 0.07em; text-transform: uppercase; color: var(--text-muted); }

/* Monthly winners: one quiet strip beside the hub records. */
.hub-winners { display: grid; gap: 8px; margin: 0; padding: 0; list-style: none; }
.hub-winners li { display: flex; align-items: baseline; gap: 10px; font-size: 0.88rem; padding-top: 8px; border-top: 1px solid var(--border); }
.hub-winners li:first-child { border-top: 0; padding-top: 0; }
.hub-winners-month { flex: 0 0 5.5rem; color: var(--text-muted); font-size: 0.8rem; }
.hub-winners-hub { color: var(--text-primary); font-weight: 600; }
.hub-winners-hub.is-unlisted { font-style: italic; font-weight: 500; color: var(--text-secondary); }
.hub-winners-note { margin-left: auto; color: var(--text-muted); font-size: 0.78rem; white-space: nowrap; }

/* The pilot dashboard's Airline goals card: one row per goal, the progress bar the career band
   already draws. */
.dash-goals { display: grid; gap: 14px; }
.goal-row { display: grid; gap: 6px; }
.goal-row-head { display: flex; align-items: baseline; gap: 10px; font-size: 0.9rem; }
.goal-row-head strong { font-weight: 600; }
.goal-row-figure { margin-left: auto; white-space: nowrap; font-variant-numeric: tabular-nums; color: var(--text-secondary); }
.goal-row-figure b { color: var(--text-primary); }
.goal-row-sub { display: flex; gap: 12px; flex-wrap: wrap; font-size: 0.8rem; color: var(--text-muted); }
.goal-row-sub .is-met { color: var(--success); font-weight: 600; }

/* The statistics page's Airline goals section: the pulse figures' shape for two goals. */
.stx-goals-figs { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 20px; }
.stx-goal { padding: 0 20px; border-left: 1px solid var(--border); min-width: 0; display: grid; gap: 8px; }
.stx-goal:first-child { padding-left: 0; border-left: 0; }
.stx-goal .thin-bar, .stx-goal .thin-bar-fill { height: 6px; border-radius: 3px; }
.stx-goal-line { font-size: 0.86rem; color: var(--text-secondary); }
.stx-goal-line strong { color: var(--text-primary); }
.stx-goals-met { margin: 14px 0 0; font-size: 0.86rem; color: var(--text-secondary); }
@media (max-width: 640px) { .stx-goals-figs { grid-template-columns: minmax(0, 1fr); } .stx-goal { padding: 0; border-left: 0; } }
