/* AIAS Monthly Air Service Dashboard - chrome and components.
   All values come from design-tokens.css. Flat white cards, 1px borders,
   uniform 10px grid gap, no shadows anywhere (logo drop shadow excepted). */

* { box-sizing: border-box; }
html { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
body { margin: 0; background: var(--aias-page-bg); font: var(--aias-t-body); color: var(--aias-ink-body); }

/* ---------------- reading width ----------------
   The dashboard is a report, not a wall: content is capped and centred so an
   ultrawide monitor gets margins instead of enormous stretched cards (client
   request Aug 2026). The header, filter bar and footer stay full bleed - only
   their CONTENT is capped, via a padding that grows once the viewport passes
   the cap, so every row still lines up with the cards. */
:root { --aias-max: 1240px; --aias-scrim: rgba(255, 255, 255, 0.5);
        --aias-hover: rgba(11, 37, 69, 0.06); }
/* the pcbar / pcfoot are deliberately NOT capped: they carry the shared
   portal padding so the brand mark sits exactly where it does in every
   other tool */
.hdr-row, .filters, .canvas {
  padding-left: max(var(--aias-pad-x), calc((100% - var(--aias-max)) / 2));
  padding-right: max(var(--aias-pad-x), calc((100% - var(--aias-max)) / 2));
}
.print-filters { max-width: var(--aias-max); margin-left: auto; margin-right: auto; }

/* ---------------- dark theme ----------------
   The light palette above is the contractual handoff and is untouched. Dark
   is the additive alternate for the shared portal day/night toggle
   (body.dark, set by pcApplyTheme in index.html); chart ink is themed in
   charts.js applyTheme, which the toggle calls before re-rendering. */
body.dark {
  --aias-page-bg:     #0B1524;
  --aias-canvas:      #0F1B2C;
  --aias-surface:     #132133;
  --aias-surface-alt: #17273B;
  --aias-placeholder: #162437;
  --aias-border:      #26374D;
  --aias-border-soft: #22324655;
  --aias-rule:        #1E2C3F;
  --aias-rule-dashed: #3A4E68;
  --aias-ink:         #E8EFF7;
  --aias-ink-body:    #C6D2E0;
  --aias-ink-muted:   #A3B3C6;
  --aias-ink-faint:   #7E90A6;
  --aias-ink-ghost:   #5E6F85;
  --aias-tile-label:  #93A5B8;
  --aias-teal-600:    #49B6C4;
  --aias-navy-700:    #6D9EE0;
  --aias-pos:         #3FBE86;
  --aias-pos-bg:      #123528;
  --aias-neg:         #E2896C;
  --aias-neg-bg:      #3A2018;
  --aias-neg-bar:     #A86A56;
  --aias-neutral-bar: #5A6C81;
  --aias-amber:       #C9862F;
  --aias-scrim:       rgba(11, 21, 36, 0.55);
  --aias-hover:       rgba(180, 214, 255, 0.10);
}
body.dark .card.reserved { background: var(--aias-placeholder); }
/* the accent turns LIGHT in dark mode, so solid accent buttons take dark ink */
body.dark .seg button[aria-checked="true"],
body.dark .btn-solid { color: #0B1524; }
a { color: var(--aias-teal-600); text-decoration: none; }
a:hover { color: var(--aias-navy-700); text-decoration: underline; }
button { font-family: var(--aias-font); }

/* solid ring: the old 35%-alpha shadow measured ~1.5:1 on white, under the
   3:1 non-text minimum, so keyboard focus was effectively invisible (audit) */
:is(button, select, input, [role="button"]):focus-visible {
  outline: 2px solid var(--aias-teal-600);
  outline-offset: 1px;
  border-color: var(--aias-teal-600);
}

/* ---------------- header band ---------------- */
.hdr { position: sticky; top: 0; z-index: 6; height: var(--aias-header-h); flex-shrink: 0; overflow: hidden;
       background: linear-gradient(180deg, #06182E 0%, #0B2545 70%, #0E2A4C 100%); }
.hdr .motif { position: absolute; inset: 0; width: 100%; height: 100%; }
/* horizontal padding comes from the reading width cap near the top */
.hdr-row { position: relative; display: flex; align-items: center; justify-content: space-between;
           height: 100%; }
.hdr-left { display: flex; align-items: center; gap: 16px; }
.hdr-left img { width: 64px; height: 64px; object-fit: contain; filter: var(--aias-logo-shadow); }
.brand { font: var(--aias-t-brand); color: #fff; letter-spacing: .6px; white-space: nowrap; }
.brand-sub, .period-sub { font: var(--aias-t-header-sub); color: var(--aias-header-sub); white-space: nowrap; }
.hdr-right { text-align: right; }
.period { font: var(--aias-t-period); color: #fff; }

/* ---------------- view tabs (Passenger / Cargo pages) ----------------
   Reset + Export PDF live on THIS row, not in the filter bar: down there the
   bar wraps at common widths and the open Airlines panel landed on top of
   both buttons, swallowing the clicks. */
.viewbar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
           background: var(--aias-surface); border-bottom: 1px solid var(--aias-border);
           padding-left: max(var(--aias-pad-x), calc((100% - var(--aias-max)) / 2));
           padding-right: max(var(--aias-pad-x), calc((100% - var(--aias-max)) / 2)); }
.viewbar .filters-actions { margin-left: auto; padding: 6px 0; }
.viewtabs { display: flex; gap: 2px; }
.viewtabs button { border: 0; background: transparent; cursor: pointer; position: relative;
  font: 700 13px var(--aias-font); letter-spacing: .5px; text-transform: uppercase;
  color: var(--aias-ink-muted); padding: 11px 18px 10px; }
.viewtabs button:hover { color: var(--aias-navy-700); }
.viewtabs button[aria-selected="true"] { color: var(--aias-ink); }
.viewtabs button[aria-selected="true"]::after { content: ""; position: absolute;
  left: 10px; right: 10px; bottom: -1px; height: 3px; background: var(--aias-teal-600);
  border-radius: 2px 2px 0 0; }
.viewtabs button:focus-visible { outline: 2px solid var(--aias-teal-600); outline-offset: -3px; }

/* ---------------- export menu ---------------- */
.print-wrap { position: relative; }
.print-menu { position: absolute; top: 38px; right: 0; z-index: 9; min-width: 190px;
  background: var(--aias-surface); border: 1px solid var(--aias-border); border-radius: 4px;
  display: flex; flex-direction: column; padding: 4px; }
.print-menu[hidden] { display: none; }
.print-menu button { border: 0; background: transparent; text-align: left; cursor: pointer;
  font: var(--aias-t-body); color: var(--aias-ink-body); padding: 7px 10px; border-radius: 3px; }
.print-menu button:hover { background: var(--aias-surface-alt); color: var(--aias-navy-700); }
.print-menu button:focus-visible { outline: 2px solid var(--aias-teal-600); outline-offset: -2px; }

/* ---------------- filter bar ---------------- */
/* No overflow clipping here: the carriers dropdown panel is an absolutely
   positioned child and any overflow on the bar would clip it invisible.
   Narrow screens wrap to a second row instead of scrolling. */
.filters { position: sticky; top: var(--aias-header-h); z-index: 5; display: flex; align-items: center;
           flex-wrap: wrap; gap: var(--aias-gap); min-height: 52px; padding-top: 6px; padding-bottom: 6px;
           background: var(--aias-surface); border-bottom: 1px solid var(--aias-border); }
.filters > * { flex-shrink: 0; }
.filters-spacer { flex: 1 1 auto; min-width: 12px; }
/* Reset + Export travel together: when the bar wraps at a narrow width they
   move to the next line as one right aligned pair, instead of Export being
   stranded alone on the left */
.filters-actions { display: flex; align-items: center; gap: var(--aias-gap); margin-left: auto; }
.fl { font: var(--aias-t-kpi-label); color: var(--aias-ink-muted); text-transform: uppercase;
      letter-spacing: .5px; white-space: nowrap; }
select, .dd-btn { height: 32px; border: 1px solid var(--aias-border); border-radius: 4px;
  background: var(--aias-surface); font: var(--aias-t-body); color: var(--aias-ink-body); padding: 0 10px; }
select:hover, .dd-btn:hover { border-color: var(--aias-teal-600); }
.seg { display: flex; border: 1px solid var(--aias-border); border-radius: 4px; overflow: hidden; }
.seg button { border: 0; background: transparent; font: 600 12px var(--aias-font); color: var(--aias-ink-muted);
              padding: 6px 14px; cursor: pointer; white-space: nowrap; }
.seg button:hover { color: var(--aias-navy-700); }
.seg button[aria-checked="true"] { background: var(--aias-navy-700); color: #fff; }
.btn-ghost { border: 0; background: transparent; font: 600 12px var(--aias-font);
             color: var(--aias-teal-600); cursor: pointer; white-space: nowrap; }
.btn-ghost:hover { color: var(--aias-navy-700); }
.btn-solid { border: 1px solid var(--aias-navy-700); background: var(--aias-navy-700); color: #fff;
             font: 600 12px var(--aias-font); padding: 7px 14px; border-radius: 4px; cursor: pointer;
             white-space: nowrap; }
.btn-solid:hover { border-color: var(--aias-teal-600); }
.dd { position: relative; }
.dd-btn { cursor: pointer; }
.dd-panel { position: absolute; top: 36px; left: 0; z-index: 9; min-width: 250px; padding: 0;
            background: var(--aias-surface); border: 1px solid var(--aias-border); border-radius: 4px;
            display: flex; flex-direction: column; max-height: 340px; overflow-y: auto; }
/* the author display:flex above would defeat the hidden attribute (an
   author rule beats the UA [hidden] rule) - re-assert it explicitly */
.dd-panel[hidden] { display: none; }
.report[hidden] { display: none; }
.seg[hidden] { display: none; }
.dd-panel label { display: flex; align-items: center; gap: 7px; font: var(--aias-t-body);
                  color: var(--aias-ink-body); cursor: pointer; white-space: nowrap; }
.dd-panel label[hidden] { display: none; }
.dd-panel input { accent-color: var(--aias-teal-600); }
/* search + count header stays put while the airline list scrolls */
.dd-head { position: sticky; top: 0; z-index: 1; background: var(--aias-surface);
           padding: 8px 10px 6px; border-bottom: 1px solid var(--aias-rule);
           display: flex; flex-direction: column; gap: 6px; }
.dd-search { height: 28px; border: 1px solid var(--aias-border); border-radius: 4px; padding: 0 8px;
             font: var(--aias-t-body); color: var(--aias-ink-body); background: var(--aias-surface); }
.dd-search:focus-visible { outline: 2px solid var(--aias-teal-600); outline-offset: 1px; }
.dd-meta { display: flex; align-items: center; justify-content: space-between; gap: 12px;
           font: var(--aias-t-footnote); color: var(--aias-ink-faint); }
.dd-act { border: 0; background: transparent; padding: 0; font: 600 11.5px var(--aias-font);
          color: var(--aias-teal-600); cursor: pointer; }
.dd-act:hover { color: var(--aias-navy-700); }
.dd-act:disabled { color: var(--aias-ink-ghost); cursor: default; }
.dd-list { display: flex; flex-direction: column; gap: 6px; padding: 8px 10px; }
.dd-foot { padding: 0 10px 9px; font: var(--aias-t-footnote); color: var(--aias-ink-faint);
           white-space: normal; max-width: 230px; }

/* ---------------- canvas and section grids ---------------- */
.canvas { background: var(--aias-canvas); padding-top: 20px; padding-bottom: 12px;
          min-height: calc(100vh - 148px); }
.report { display: block; }
.grid2 { display: grid; grid-template-columns: 1fr 1fr; grid-auto-rows: 1fr; gap: var(--aias-gap);
         margin-top: var(--aias-gap); align-items: stretch; }
.grid-cap { display: grid; grid-template-columns: 2fr 1fr; gap: var(--aias-gap); margin-top: var(--aias-gap); }
.grid-cargo { display: grid; grid-template-columns: 1.5fr 1fr; gap: var(--aias-gap); margin-top: var(--aias-gap); }
.col { display: flex; flex-direction: column; gap: var(--aias-gap); min-height: 0; }
.col > .card { flex: 1; }
/* stretch, not start: a KPI label that wraps to two lines used to make its
   card taller than its neighbours, leaving the row with a ragged bottom edge
   and split tiles at six different heights. Equal height cards + the split
   row pushed to the bottom keep every tile on one line. */
.kpis { display: grid; grid-template-columns: repeat(6, 1fr); gap: var(--aias-gap);
        align-items: stretch; margin-top: var(--aias-gap); }
.kpis.four { grid-template-columns: repeat(4, 1fr); }
.kpis.five { grid-template-columns: repeat(5, 1fr); }
.strip { margin-top: var(--aias-gap); }

/* ---------------- section band + footnote ---------------- */
.band { display: flex; align-items: center; gap: 10px; padding: 18px 0 0; }
.band + .band { padding-top: 10px; }
.band-label { font: var(--aias-t-section); color: var(--aias-ink); letter-spacing: .5px;
              text-transform: uppercase; white-space: nowrap; flex-shrink: 0; }
.band-rule { flex: 1; height: 1px; background: var(--aias-border); }
.band-note { font: 400 11px var(--aias-font); color: var(--aias-ink-faint); white-space: nowrap; flex-shrink: 0; }
.foot { display: flex; justify-content: space-between; padding: 6px 0 12px;
        font: var(--aias-t-footnote); color: var(--aias-ink-faint); }

/* ---------------- panel card ---------------- */
.card { background: var(--aias-surface); border: 1px solid var(--aias-border);
        border-radius: var(--aias-r-card); padding: var(--aias-card-pad);
        display: flex; flex-direction: column; min-width: 0; }
.panel-head { display: flex; justify-content: space-between; align-items: baseline; gap: 14px; }
/* Title = bold subject + quiet scope + a colour mark at the left edge (client
   request Aug 2026, replacing ALL CAPS: "the caps are intense, plain is plain").
   The mark is NOT decoration: it reuses the fixed airport encoding, navy for
   ANC, teal for FAI, split for the system view, so a glance at the edge of a
   card says whose numbers these are. Both colours come from tokens that
   body.dark already lightens, so the dark theme needs no rule of its own. */
.panel-title { font: 400 12.5px/1.35 var(--aias-font); color: var(--aias-ink-muted);
               position: relative; padding-left: 12px; }
.panel-title .pt-subject { font: 700 16px/1.3 var(--aias-font); color: var(--aias-ink);
                           letter-spacing: -.008em; }
.panel-title .pt-scope { white-space: nowrap; }
.panel-title::before { content: ''; position: absolute; left: 0; top: 3px; width: 3px; height: 15px;
                       border-radius: 2px; background: var(--aias-navy-700); }
.panel-title[data-scope="fai"]::before { background: var(--aias-teal-600); }
.panel-title[data-scope="sys"]::before {
  background: linear-gradient(var(--aias-navy-700) 50%, var(--aias-teal-600) 50%); }
.panel-right { white-space: nowrap; flex-shrink: 0; }
.panel-note { font: var(--aias-t-panel-note); color: var(--aias-ink-faint); white-space: nowrap; }
.panel-foot { font: var(--aias-t-footnote); color: var(--aias-ink-faint); margin-top: 6px; }
/* per panel source line, pinned to the card bottom (cards are flex columns) */
.src-note { font: 400 10.5px var(--aias-font); color: var(--aias-ink-faint);
            margin-top: auto; padding-top: 6px; }
.stat3 .src-note, .stat2 .src-note { grid-column: 1 / -1; margin-top: 0; }
.subhead { font: 600 13px var(--aias-font); color: var(--aias-ink); margin-top: 10px; }
.legend { display: flex; gap: 12px; font: var(--aias-t-panel-note); color: var(--aias-ink-muted);
          white-space: nowrap; flex-shrink: 0; flex-wrap: wrap; }
.legend [data-carrier-toggle] { cursor: pointer; border-radius: 3px; padding: 0 2px;
  text-decoration: underline dotted; text-underline-offset: 3px; }
.legend [data-carrier-toggle]:hover { color: var(--aias-navy-700); }
.legend .leg-sel { outline: 1px solid var(--aias-teal-600); outline-offset: 1px; border-radius: 2px; }
.pos { color: var(--aias-pos); }
.neg { color: var(--aias-neg); }
.neu { color: var(--aias-ink-muted); }
.new { color: var(--aias-teal-600); font-weight: 600; }

/* ---------------- KPI card + split tiles ---------------- */
.kpi { padding: var(--aias-kpi-pad); }
.kpi-label { font: var(--aias-t-kpi-label); color: var(--aias-ink-muted); text-transform: uppercase;
             letter-spacing: .5px; }
.kpi-line { display: flex; align-items: baseline; gap: 8px; margin-top: 2px; flex-wrap: wrap; }
.kpi-value { font: var(--aias-t-kpi-value); color: var(--aias-ink); }
.kpi-delta { font: var(--aias-t-kpi-delta); white-space: nowrap; }
/* qualifier under the value (the busiest TSA day names its date). Allowed to
   wrap: the cards stretch to equal height anyway, and a truncated coverage
   caveat would be worse than a second line. */
.kpi-sub { font: 400 10.5px/1.3 var(--aias-font); color: var(--aias-ink-faint); margin-top: 3px; }
.split { display: grid; grid-template-columns: 1fr 1fr; gap: 7px; margin-top: auto; padding-top: 9px;
         border-top: 1px solid var(--aias-rule); }
.tile { background: var(--aias-surface-alt); border: 1px solid var(--aias-border-soft);
        border-radius: var(--aias-r-tile); padding: var(--aias-tile-pad); cursor: pointer; min-width: 0; }
.tile:hover { border-color: var(--aias-teal-600); }
.tile-code { font: var(--aias-t-tile-code); color: var(--aias-tile-label); letter-spacing: 1px; }
.tile-value { font: var(--aias-t-tile-value); color: var(--aias-ink); margin-top: 1px; }
.pill { display: inline-block; margin-top: 4px; padding: 2px 6px; border-radius: var(--aias-r-pill);
        font: var(--aias-t-tile-delta); white-space: nowrap; }
.pill.pos { background: var(--aias-pos-bg); color: var(--aias-pos); }
.pill.neg { background: var(--aias-neg-bg); color: var(--aias-neg); }
.pill.neu { background: var(--aias-rule); color: var(--aias-ink-muted); }
.pill.new { background: var(--aias-teal-100); color: var(--aias-teal-600); }

/* ---------------- charts: shared ---------------- */
.chart-svg { width: 100%; height: auto; flex: 0 0 auto; display: block; }
/* hover: the tooltip hit column under the cursor highlights so the tipped
   point is visually anchored to the chart */
.chart-svg rect[data-tip]:hover { fill: var(--aias-hover); }
.bar-col:hover { background: var(--aias-hover); }
/* absolute variant: labels sit at their true data fraction (used where the
   slots are not evenly distributed across categories, e.g. weeks vs months) */
.axis-abs { position: relative; height: 16px; }
.axis-abs span { position: absolute; top: 2px; transform: translateX(-50%); white-space: nowrap; }
/* cell variant, under stacked column charts only: same side padding and gap
   as .bars with one flex:1 cell per column, so each centered label sits
   exactly under its column (the old space-between row distributed labels by
   text width and drifted off the columns) */
.axis { display: flex; gap: 10px; font: var(--aias-t-axis);
        color: var(--aias-ink-faint); padding: 0 4px; margin-top: 2px; }
.axis span { flex: 1 1 0; min-width: 0; text-align: center; white-space: nowrap; }
.mark { transition: opacity .12s ease-out; }
.mark.dim { opacity: .45; }
/* dataset with no airline dimension under an active airline filter: the
   panel fades and the reason overlays it. The overlay also catches hover
   and clicks, so a faded panel reads as unavailable, not interactive. */
.no-gran { position: relative; }
.no-gran > * { opacity: .3; }
.no-gran::after { content: attr(data-nogran); position: absolute; inset: 0; z-index: 3;
  display: flex; align-items: center; justify-content: center; text-align: center;
  padding: 16px 22px; font: 600 12.5px/1.5 var(--aias-font); color: var(--aias-ink-body);
  background: var(--aias-scrim); border-radius: var(--aias-r-card); }
.mk-anim { transition: height .18s ease-out, width .18s ease-out; }
.empty-fill { flex: 1; min-height: 120px; background: var(--aias-placeholder); border-radius: 4px;
              display: flex; align-items: center; justify-content: center; margin-top: 8px; }
.empty-fill span { font: var(--aias-t-kpi-label); color: var(--aias-ink-ghost);
                   text-transform: uppercase; letter-spacing: .5px; }

/* YoY strip */
.yoy-strip { display: flex; align-items: flex-end; flex-wrap: wrap; gap: 4px; margin-top: 6px; }
.yoy-cap { flex: 0 0 100%; font: 600 11px var(--aias-font); color: var(--aias-ink-muted);
           white-space: nowrap; align-self: center; }
.yoy-col { flex: 1; display: flex; flex-direction: column; justify-content: flex-end; gap: 2px; min-width: 0; }
.yoy-val { font: 600 10.5px var(--aias-font); text-align: center; white-space: nowrap; }
.yoy-bar { width: 100%; }

/* stacked vertical bars */
.bars { display: flex; align-items: flex-end; gap: 10px; flex: 1; padding: 22px 4px 4px; min-height: 190px;
  position: relative; }
/* a standalone full width card holding a .bars chart needs an EXPLICIT
   .bars height: the stack percentages resolve against a definite height,
   which grid cards inherit from their stretched row but a lone card never
   gets (min-height does not make a height definite) */
.pax-card .bars { height: 300px; flex: none; }
/* small vertical axis behind the bars: hairlines at the tallest column's
   value and its half, aligned to the bar area (inside the .bars padding) */
.bars-axis { position: absolute; top: 22px; left: 4px; right: 4px; bottom: 4px;
  pointer-events: none; z-index: 0; }
.bars-axis.labels { z-index: 2; }
.bars-axis-row { position: absolute; left: 0; right: 0; border-top: 1px solid var(--aias-rule); }
.bars-axis-row span { position: absolute; left: 0; top: -11px;
  font: 10px/1 var(--aias-font); color: #54677A;
  background: var(--aias-surface); padding: 1px 3px; border-radius: 2px; }
body.dark .bars-axis-row span { color: var(--aias-ink-muted); }
.bar-col { flex: 1; display: flex; flex-direction: column; justify-content: flex-end; height: 100%;
  position: relative; z-index: 1; border-radius: 4px;
           min-width: 0; cursor: default; }
.bar-val { font: var(--aias-t-bar-value); color: var(--aias-ink); text-align: center; margin-bottom: 3px;
           white-space: nowrap; }
.bar-stack { display: flex; flex-direction: column-reverse; } /* first segment = bottom (largest) */
.bar-stack .seg { min-height: 2px; display: flex; align-items: center; justify-content: center; overflow: hidden; }
.bar-stack .seg span { font: 700 10.5px var(--aias-font); white-space: nowrap; }
/* segment hover emphasis is LOCAL: the other segments of the same column
   fade so the hovered piece reads clearly; nothing else in the chart moves
   (the old series-wide dim lit up the whole carrier band on every hover) */
.bar-stack:hover .seg { opacity: .55; }
.bar-stack .seg:hover { opacity: 1; }

/* horizontal bar rows */
.rows { display: flex; flex-direction: column; gap: 7px; margin-top: 10px; }
.row-share, .row-split, .row-bench { display: grid; gap: 8px; align-items: center;
  font: var(--aias-t-body); color: var(--aias-ink-body); min-width: 0; }
.row-share { grid-template-columns: 110px 1fr 74px; cursor: pointer; padding-left: 4px;
             border-left: 2px solid transparent; }
.row-share:hover { border-left-color: var(--aias-border); }
.row-share.sel { border-left-color: var(--aias-teal-600); }
.row-share:not([data-carrier-toggle]) { cursor: default; }
.row-share:not([data-carrier-toggle]):hover { border-left-color: transparent; }
/* cargo rows carry full operator and aircraft names, not airline codes */
#sec-cargo .row-split { grid-template-columns: 108px 1fr 96px; }
.row-split { grid-template-columns: 78px 1fr 42px; }
.row-bench { grid-template-columns: 96px 1fr 52px; }
.row-bench span:first-child { font: 600 12px var(--aias-font); }
.row-share > span:first-child, .row-split > span:first-child { overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
.row-val { text-align: right; white-space: nowrap; }
.row-val b { font-size: 12px; }
.bench-val { font: 700 13px var(--aias-font); }
.track { height: 12px; background: var(--aias-rule); border-radius: var(--aias-r-bar); overflow: hidden; }
.track.tall { height: 16px; }
.fill { height: 100%; display: flex; border-radius: var(--aias-r-bar); overflow: hidden; }
.fill1 { height: 100%; border-radius: var(--aias-r-bar); }
.rows.bench { gap: 9px; }

/* donut */
.donut-wrap { display: flex; align-items: center; gap: 18px; flex: 1; padding-top: 6px; }
.donut-wrap.two { gap: 24px; justify-content: center; }
.donut { flex-shrink: 0; }
.donut-legend { display: grid; grid-template-columns: 1fr 1fr; gap: 8px 16px;
                font: 400 11px var(--aias-font); color: var(--aias-ink-body); flex: 1; align-content: center; }
.donut-legend.one-col { grid-template-columns: 1fr; flex: 0 0 auto; gap: 5px; }
.donut-legend div { display: flex; justify-content: space-between; gap: 8px; }

/* 100 percent stacked bar */
.pct-bar { display: flex; height: 20px; border-radius: 3px; overflow: hidden; margin-top: 10px; }
.pct-bar span { font: 700 10.5px var(--aias-font); color: #fff; }
.pct-legend { display: flex; gap: 14px; font: 400 11px var(--aias-font); color: var(--aias-ink-body);
              margin-top: 8px; flex-wrap: wrap; }

/* capacity outlook strip */
/* Capacity outlook: wide column pairs, each bar carrying its own total, with
   the month and its growth underneath (client request Aug 2026). */
.outlook { display: flex; gap: 10px; margin-top: 8px; align-items: stretch; }
.ol-col { flex: 1; display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.ol-bars { display: flex; align-items: flex-end; justify-content: center; gap: 6px; height: 96px; }
.ol-b { display: flex; flex-direction: column; justify-content: flex-end; align-items: center;
        gap: 3px; height: 100%; flex: 1 1 0; max-width: 46px; }
.ol-b > div { width: 100%; border-radius: 3px 3px 0 0; min-height: 2px; }
.ol-n { font: 700 10.5px var(--aias-font); color: var(--aias-ink-faint); white-space: nowrap; }
.ol-n.cur { color: var(--aias-ink); }
/* caption centers under the centered bar pair (left-aligned it sat half a
   column away from its own bars) */
.ol-cap { font: 600 11.5px var(--aias-font); color: var(--aias-ink-body); white-space: nowrap;
          text-align: center; }
.ol-note { width: 190px; font: 400 11.5px/1.5 var(--aias-font); color: var(--aias-ink-muted);
           border-left: 1px solid var(--aias-border); padding-left: 14px; flex-shrink: 0; }

/* Financial page (fiscal year, AIAS combined).
   The basis block sits directly under the band: this page is the only one on a
   fiscal year and with no airport dimension, so it states that before any figure.
   It reuses the card surface so it reads as part of the report, not a warning. */
.fin-basis { background: var(--aias-surface); border: 1px solid var(--aias-border);
             border-left: 3px solid var(--aias-teal-600); border-radius: var(--aias-r-card);
             padding: 10px 14px; margin-top: var(--aias-gap);
             font: 400 11.5px/1.6 var(--aias-font); color: var(--aias-ink-body); }
.fin-basis b { color: var(--aias-ink); }
/* A card whose source does not foot, shown at the client's direction. It must read as
   provisional at a glance, not sit in the grid looking as solid as the card beside it:
   an amber rule down the edge and a banner above the chart that states the problem
   before the reader gets to the numbers. Amber, not red: the figures are published,
   not wrong. */
.card.as-published { border-left: 3px solid var(--aias-amber, #B4790E); }
.as-pub-flag { font: 600 11.5px var(--aias-font); line-height: 1.45;
               color: #7A5206; background: rgba(180, 121, 14, .10);
               border: 1px solid rgba(180, 121, 14, .28); border-radius: var(--aias-r-card);
               padding: 7px 9px; margin: 0 0 9px; }
body.dark .as-pub-flag { color: #E8C07A; background: rgba(180, 121, 14, .16);
                         border-color: rgba(180, 121, 14, .40); }

/* the fiscal year columns select the year, so they read as controls */
.fin-pairs .ol-col { cursor: pointer; border-radius: var(--aias-r-card); padding: 4px 2px;
                     border: 1px solid transparent; }
.fin-pairs .ol-col:hover { background: var(--aias-surface-alt); }
.fin-pairs .ol-col.on { border-color: var(--aias-teal-600); background: var(--aias-surface-alt); }
.fin-pairs .ol-col:focus-visible { outline: 2px solid var(--aias-teal-600); outline-offset: 1px; }

/* fiscal-year bars */
.fy-bars { display: flex; align-items: stretch; gap: 26px; flex: 1; padding: 12px 10px 0; min-height: 170px; }
.fy-col { flex: 1; display: flex; flex-direction: column; justify-content: flex-end; gap: 5px; }
.fy-val { font: 700 13px var(--aias-font); color: var(--aias-ink); text-align: center; }
/* The column stays full width so the whole thing is a click target, but the BAR
   is capped and centred: at four years a flex:1 bar drew ~275px wide and read as a
   block, twice the visual weight of the paired strip directly above it. */
.fy-bar { border-radius: 3px 3px 0 0; width: 100%; max-width: 118px; margin: 0 auto; }
.fy-cap { font: 600 12px var(--aias-font); color: var(--aias-ink-muted); text-align: center; }
/* when the columns set the fiscal year they read as controls, exactly as the
   paired revenue and expense strip above them does */
.fy-col[data-fy-set] { cursor: pointer; border-radius: var(--aias-r-card); padding: 4px 2px;
                       border: 1px solid transparent; }
.fy-col[data-fy-set]:hover { background: var(--aias-surface-alt); }
.fy-col[data-fy-set].on { border-color: var(--aias-teal-600); background: var(--aias-surface-alt); }
.fy-col[data-fy-set]:focus-visible { outline: 2px solid var(--aias-teal-600); outline-offset: 1px; }

/* destinations */
.map-card { margin-top: var(--aias-gap); }
.map-mount.map-empty { min-height: 120px; }
.map-mount { flex: 1; min-height: 300px; display: flex; align-items: center; justify-content: center;
             margin-top: 4px; }
.map-svg { width: 100%; height: auto; max-height: 420px; display: block; }
.dest-pair { align-items: stretch; }
.dest-card { padding: 9px 12px; }
.dest-head { display: flex; justify-content: space-between; align-items: baseline;
             padding-bottom: 5px; margin-bottom: 6px; }
/* destination card headings follow the panel titles off ALL CAPS; they are
   short and already scoped by their section, so they need no colour mark */
.dest-title { font: 700 14px var(--aias-font); color: var(--aias-ink); white-space: nowrap;
              letter-spacing: -.008em; }
.dest-grid { display: grid; grid-template-columns: 1fr 1fr; grid-auto-flow: column;
             grid-template-rows: repeat(5, auto); gap: 4px 8px; flex: 1; align-content: center; }
.dest-row { display: flex; align-items: center; gap: 6px; background: var(--aias-surface-alt);
            border: 1px solid var(--aias-border-soft); border-radius: 5px; padding: 5px 9px; min-width: 0; }
.dr-rank { font: 700 10px var(--aias-font); color: var(--aias-ink-faint); width: 14px; flex-shrink: 0; }
.dr-code { font: 700 12px var(--aias-font); color: var(--aias-ink); flex-shrink: 0; }
.dr-city { font: 400 11.5px var(--aias-font); color: var(--aias-ink-muted); overflow: hidden;
           text-overflow: ellipsis; white-space: nowrap; min-width: 0; flex: 1; }
.dr-val { font: 600 11.5px var(--aias-font); color: var(--aias-ink); margin-left: auto; flex-shrink: 0; }
.dest-row .pos, .dest-row .neg, .dest-row .new { font: 600 10.5px var(--aias-font); white-space: nowrap;
  flex-shrink: 0; }

/* cargo stat card */
.stat3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 8px; align-content: center; }
/* two tile variant, since the cargo card lost its Share of landings tile */
.stat2 { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; align-content: center; }
.stat-label { font: 600 10.5px var(--aias-font); color: var(--aias-ink-faint); text-transform: uppercase;
              letter-spacing: .4px; }
.stat-val { font: 700 18px var(--aias-font); color: var(--aias-ink); }

/* reserved placeholder */
.card.reserved { background: var(--aias-placeholder); border: 1px dashed var(--aias-rule-dashed);
                 align-items: center; justify-content: center; min-height: 200px; }
.card.reserved span { font: 600 12px var(--aias-font); color: var(--aias-ink-ghost);
                      text-transform: uppercase; letter-spacing: .6px; }

/* tooltip */
#tip { position: fixed; z-index: 20; display: none; background: var(--aias-navy-700); color: #fff;
       font: var(--aias-t-panel-note); border-radius: 4px; padding: 6px 8px; pointer-events: none;
       white-space: nowrap; }

/* ---------------- responsive (SCREEN only: the print page box is narrower
   than 1024px, and letting these fire during pagination collapsed the PDF
   into 11 single-column pages) ---------------- */
@media screen and (max-width: 1400px) {
  /* .five needs its own line: it out-ranks the bare .kpis rule on specificity,
     so without this the cargo band kept five columns on a narrow screen */
  .kpis, .kpis.five { grid-template-columns: repeat(3, 1fr); }
  .kpis.four { grid-template-columns: repeat(2, 1fr); }
}
@media screen and (max-width: 1100px) {
  /* Below about 1080px the header CLIPPED its own right hand block: .brand is
     nowrap, .hdr-row is space-between, and .hdr is overflow:hidden, so a long
     organisation name pushed the period and the data through line off the edge and
     the header simply cut them off. Measured at a 960px viewport the right block
     ended at x=1033 with nothing to scroll to.
     This matters because the dashboard is embedded in host pages with narrow content
     columns (the Alaska DOT site caps its container at 960px), where the date being
     invisible is not a cosmetic problem.
     Fix: let the bar grow and the name wrap, rather than truncating the client's own
     name with an ellipsis. min-width:0 is what lets the flex child shrink at all. */
  .hdr { height: auto; min-height: var(--aias-header-h); }
  .hdr-row { flex-wrap: wrap; row-gap: 4px; padding-top: 10px; padding-bottom: 10px; }
  .hdr-left { min-width: 0; flex: 1 1 auto; }
  .brand { white-space: normal; }
  .hdr-right { flex: 0 0 auto; margin-left: auto; }
  .brand-sub { display: none; }
}
@media screen and (max-width: 1024px) {
  .grid2, .grid-cap, .grid-cargo, .dest-pair { grid-template-columns: 1fr; }
  .grid2 > .card, .grid-cap > .card, .grid-cargo > .card { min-height: 260px; }
  .outlook { flex-wrap: wrap; }
  .ol-note { width: 100%; border-left: 0; padding-left: 0; }
  .map-mount { aspect-ratio: 16 / 9; min-height: 0; }
}
@media screen and (max-width: 720px) {
  .kpis, .kpis.four, .kpis.five { grid-template-columns: 1fr; }
  .brand { font-size: 13px; }
}

/* ---------------- print: the seven section letter landscape report -------- */
@page { size: letter landscape; margin: 8mm; }
.print-filters { display: none; }
@media print {
  body { background: #fff; }
  .filters, #tip, .pcbar, .pcfoot, .viewbar { display: none !important; }
  /* scoped export: the consolidated pass renders every section, so print
     drops whichever page is outside the chosen scope. Stated as "not the chosen
     view" rather than naming the others, so adding a page (Financial, Aug 2026)
     cannot silently leak into another page's export. */
  body.print-passenger .report:not([data-view="passenger"]),
  body.print-cargo .report:not([data-view="cargo"]),
  body.print-financial .report:not([data-view="financial"]) { display: none !important; }
  .print-filters { display: block; padding: 4px 16px 0; font: 600 10px var(--aias-font);
                   color: var(--aias-ink-muted); text-transform: uppercase; letter-spacing: .5px; }
  /* stays a containing block: as `static` the absolutely positioned aurora
     motif escaped .hdr's overflow clip and washed over every printed page.
     It is also trimmed here: the header and the filter line sit on page one,
     eating into the space the first section needs, which pushed the
     executive summary a few pixels onto a second page. */
  .hdr { position: relative; height: 62px; }
  .hdr-row { gap: 18px; }
  .brand-sub, .period-sub { white-space: normal; }
  .gran-tag { display: none; }
  .hdr-left img { width: 42px; height: 42px; }
  .brand { font-size: 13px; }
  /* print ignores the on screen reading width cap: the page IS the cap */
  .canvas { background: var(--aias-canvas); padding: 8px 16px !important; min-height: 0;
            zoom: 0.70; /* one section per letter landscape page */ }
  /* A definite HEIGHT here (the old height:130px) made both dimensions
     definite, which defeats the inline aspect-ratio and stretched the SVG
     text up to 2.75:1, and collapsed the meet-fitted bubble charts to a
     sliver. Let width:100% + aspect-ratio size them exactly as on screen;
     the page zoom below is tuned for the taller sections that produces. */
  .chart-svg { height: auto; width: 100%; min-height: 0; flex: 0 0 auto; }
  /* The tall full width charts (both bubble scatters and the map) would
     otherwise print ~400px deep and push their section onto a second page.
     Cap their WIDTH, never their height: with aspect-ratio governing, a
     narrower box is proportionally shorter, so they shrink without the
     distortion that fixing a height reintroduces. */
  .card.strip .chart-svg, .map-svg { max-width: 58%; margin-left: auto; margin-right: auto; }
  /* destinations lands a hair over a landscape page; a mild squeeze fits it.
     CARGO deliberately runs to TWO pages: at 1100px against a 756px page it
     would need ~40% scale to fit one, which is unreadable, and it is now the
     densest section (KPIs, landed weight, operators, families, stats,
     landings and the operator profile). Cards still avoid breaking inside. */
  #sec-dest-ANC, #sec-dest-FAI { zoom: 0.93; }
  /* The executive summary shares page one with the header and the filter
     line, so it has the least room of any section. The busiest TSA day card
     (Aug 2026) added a sub line to the KPI band and took it a dozen pixels
     over, spilling the report onto an extra page. Same mild squeeze as
     destinations,
     rather than dropping the global zoom and shrinking every other page. */
  #sec-overview { zoom: 0.98; }
  /* The Financial page fitted one landscape page until the landing fee strip was
     added (Aug 2026), which took it from 493px to 704px and spilled it onto a
     second. A page's usable height is ~756px but the header and the print filter
     line eat into page one, so 704 does not fit. Two targeted trims rather than a
     section wide squeeze, which would shrink the KPI figures for no reason:
     the fee columns do not need a 170px well in print, and the strip's three
     disclosure notes tighten. Re-measure with a headless print pass if this card
     grows again. */
  /* 0.90 is the mildest squeeze that still fits ONE landscape page now the FY2025
     revenue card carries its as published banner. Measured, not guessed: 0.91 spills.
     Re-measure with a headless print pass if anything on this page grows again. */
  #sec-financial { zoom: 0.90; }
  /* The as published banner MUST print, it is the disclosure, but it does not need
     screen padding to do its job. Trimming it here buys back most of what it costs,
     so the section squeeze above stays mild instead of dropping to 0.89 and shrinking
     the KPI figures with it. */
  .as-pub-flag { padding: 4px 7px; margin-bottom: 6px; line-height: 1.3; }
  #sec-financial .fy-bars { min-height: 104px; padding-top: 6px; }
  #sec-financial .card.strip .panel-foot { line-height: 1.35; }
  /* scaled, not squeezed: a forced 38px height left the 51px content
     overflowing into the source notes below on every export (audit) */
  .yoy-strip { zoom: .74; margin-bottom: 6px; }
  .kpi-value { font-size: 22px; }
  .tile-value { font-size: 16px; }
  .report { break-before: page; page-break-before: always; break-after: auto; page-break-after: auto; }
  .report.sec-first { break-before: auto; page-break-before: auto; }
  .card, .band, .kpis, .grid2, .grid-cap, .grid-cargo { break-inside: avoid; page-break-inside: avoid; }
  .bars { min-height: 150px; }
  .map-svg { max-height: 330px; }
  .tile, .row-share { cursor: default; }
}

/* ============================================================
   Aug 2026 client amendment: type upscale ("a lot of fonts are
   too small"). Overrides the handoff type tokens; design-tokens.css
   stays verbatim as the original handoff record. Four tiers:
   captions >= 10px, data labels 10.5 to 11, support text 11.5 to 12,
   body 12.5. Hierarchy is unchanged (labels never outsize values).
   ============================================================ */
:root {
  --aias-t-header-sub: 400 12px/1.35 var(--aias-font);
  --aias-t-panel-note: 400 12px/1.3 var(--aias-font);
  --aias-t-kpi-label:  600 11.5px/1.2 var(--aias-font);
  --aias-t-tile-code:  700 10.5px/1.2 var(--aias-font);
  --aias-t-tile-delta: 700 11px/1.2 var(--aias-font);
  --aias-t-body:       400 12.5px/1.35 var(--aias-font);
  --aias-t-bar-value:  700 11px/1.2 var(--aias-font);
  --aias-t-axis:       400 11.5px/1.2 var(--aias-font);
  --aias-t-footnote:   400 11px/1.3 var(--aias-font);
  /* light faint ink measured 2.69:1 on cards at 10-12px (audit): raised to
     the same hue at 4.99:1 white / 4.68:1 canvas. Dark theme already passed
     and keeps its own values (body.dark rules outrank this block). */
  --aias-ink-faint:   #5D7285;
  --aias-tile-label:  #5D7285;
}
/* the LF month pair card at the 1 mo window: bars grow into the tall grid
   row the daily TSA chart sets instead of leaving a blank band (audit) */
.outlook.tall .ol-bars { height: 230px; }
.outlook.tall .ol-b { max-width: 64px; }
@media print { .outlook.tall .ol-bars { height: 96px; } }
