/* Airline Manager design system.
   Reusable, layout-neutral primitives built on tokens.css. Every class is
   prefixed `am-` and is opt-in: nothing here selects a bare element, so adding
   this file cannot restyle existing markup.

   IMPORTANT - specificity: Blazor's scoped CSS appends a [b-hash] attribute to
   the last compound selector of every rule in a *.razor.css file, making those
   rules (0,2,0) while these are (0,1,0); the scoped bundle is also linked
   last. A scoped rule therefore always wins. The way to adopt a primitive is
   to DELETE the competing scoped rule, not to out-specify it from here. Do not
   wrap this file in @layer - unlayered styles beat layered ones outright,
   which would make these rules lose even harder. */

/* ------------------------------------------------------------------ reset -- */

/* Replaces Bootstrap Reboot, which used to be pulled in with the whole ~230KB
   of Bootstrap even though the app never used a single Bootstrap class. The
   declarations below are the ones the pages actually depended on, established
   by disabling the Bootstrap stylesheet in the browser and diffing computed
   styles rather than by guessing.

   The biggest of them is body's line-height: nearly every element in the app
   inherits 1.5 from it, so dropping it silently reflowed every page. */

body {
    line-height: var(--am-lh-body, 1.5);
}

h1, h2, h3, h4, h5, h6 {
    margin-top: 0;
    margin-bottom: .5rem;
    font-weight: 500;
    line-height: 1.2;
}

/* Reboot's heading scale, flattened. Bootstrap made h1-h3 viewport-responsive;
   every heading in this app sets its own size, so a fixed scale is enough and
   avoids headings resizing as the window moves. */
h1 { font-size: 2.5rem; }
h2 { font-size: 2rem; }
h3 { font-size: 1.75rem; }
h4 { font-size: 1.5rem; }
h5 { font-size: 1.25rem; }
h6 { font-size: 1rem; }

p { margin-top: 0; margin-bottom: 1rem; }
ul, ol, dl { margin-top: 0; margin-bottom: 1rem; }
ul ul, ul ol, ol ul, ol ol { margin-bottom: 0; }
ul, ol { padding-left: 2rem; }
dt { font-weight: 700; }
dd { margin-bottom: .5rem; margin-left: 0; }
blockquote, figure { margin: 0 0 1rem; }
address { margin-bottom: 1rem; font-style: normal; }
pre { margin-top: 0; margin-bottom: 1rem; overflow: auto; }
pre, code, kbd, samp { font-family: var(--am-font-mono); font-size: 1em; }
small { font-size: .875em; }
sub, sup { position: relative; font-size: .75em; line-height: 0; vertical-align: baseline; }
sub { bottom: -.25em; }
sup { top: -.5em; }
b, strong { font-weight: bolder; }
abbr[title] { text-decoration: underline dotted; cursor: help; }
mark { padding: .1875em; background-color: var(--am-warning-bg); color: var(--am-warning-text); }

hr {
    margin: 1rem 0;
    border: 0;
    border-top: var(--am-border-width) solid var(--am-border);
    opacity: .25;
}

/* Bootstrap coloured bare links its own blue. Nothing in this app wants that;
   the accent is the correct default for the one or two links that are not
   individually styled. */
a { color: var(--am-accent); }
a:not([href]), a:not([href]):hover { color: inherit; text-decoration: none; }

table { border-collapse: collapse; caption-side: bottom; }
th { text-align: inherit; text-align: -webkit-match-parent; font-weight: 500; }
th, td { padding: 0; }

label { display: inline-block; }
button { border-radius: 0; }
button, [type="button"], [type="reset"], [type="submit"] { -webkit-appearance: button; }
button:not(:disabled), [type="button"]:not(:disabled),
[type="reset"]:not(:disabled), [type="submit"]:not(:disabled) { cursor: pointer; }
select { word-wrap: normal; }
textarea { resize: vertical; }
output { display: inline-block; }
progress { vertical-align: baseline; }

fieldset { min-width: 0; margin: 0; padding: 0; border: 0; }
legend {
    width: 100%;
    margin-bottom: .5rem;
    padding: 0;
    float: left;
    font-size: 1.5rem;
    line-height: inherit;
}
legend + * { clear: left; }

img, svg { vertical-align: middle; }
[hidden] { display: none !important; }

/* Scrollbars. Use only the standard properties - Chromium ignores
   ::-webkit-scrollbar entirely on any element that also sets scrollbar-width,
   so declaring both is the classic "my scrollbar styles do nothing" bug. */
* {
    scrollbar-width: thin;
    scrollbar-color: var(--am-border-strong) transparent;
}

/* ---------------------------------------------------------------- labels -- */

/* The small upper-case caption above a value. Markup carries sentence case;
   the casing is presentation. */
.am-label {
    color: var(--am-text-dim);
    font: 800 var(--am-fs-micro) / 1 var(--am-font-mono);
    letter-spacing: var(--am-track-label);
    text-transform: uppercase;
}

.am-eyebrow {
    color: var(--am-text-dim);
    font: 800 var(--am-fs-micro) / 1 var(--am-font-mono);
    letter-spacing: var(--am-track-eyebrow);
    text-transform: uppercase;
}

/* Numeric cell. tabular-nums keeps digits from reflowing as simulation values
   tick, which is the difference between a table that reads as data and one
   that visibly shimmers. */
.am-num {
    font-family: var(--am-font-mono);
    font-variant-numeric: tabular-nums;
    font-feature-settings: 'tnum' 1;
    text-align: right;
}

.am-sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* --------------------------------------------------------------- surfaces -- */

.am-panel {
    border: var(--am-border-width) solid var(--am-border);
    border-radius: var(--am-radius);
    background: var(--am-surface-1);
    color: var(--am-text);
}

.am-panel-raised {
    border: var(--am-border-width) solid var(--am-border-strong);
    border-radius: var(--am-radius);
    background: color-mix(in srgb, var(--am-surface-1) 94%, transparent);
    box-shadow: var(--am-shadow-2);
    color: var(--am-text);
}

/* ------------------------------------------------ workspace structure -- */

/* Shared geometry for full-screen management workspaces and entity sidebars.
   Components remain responsible for their own columns and data visualisation;
   these primitives make navigation, headings and scroll ownership consistent. */
.am-workspace {
    display: flex;
    flex-direction: column;
    min-width: 0;
    min-height: 0;
    overflow: hidden;
}

.am-workspace-header {
    min-height: 48px;
    padding: 0 var(--am-space-3);
    display: flex;
    align-items: center;
    gap: var(--am-space-2);
    flex: 0 0 auto;
    border-bottom: var(--am-border-width) solid var(--am-border);
    background: color-mix(in srgb, var(--am-surface-1) 94%, transparent);
    backdrop-filter: blur(14px);
}

.am-workspace-nav,
.am-sidebar-toolbar {
    display: flex;
    align-items: center;
    gap: var(--am-space-1);
}

.am-breadcrumb {
    min-width: 0;
    display: flex;
    align-items: center;
    gap: var(--am-space-1);
    color: var(--am-text-dim);
    font-size: var(--am-fs-body);
}

.am-breadcrumb [aria-current="page"] {
    min-width: 0;
    overflow: hidden;
    color: var(--am-text-strong);
    font-weight: 700;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.am-workspace-content {
    flex: 1 1 auto;
    min-width: 0;
    min-height: 0;
    overflow: auto;
}

.am-sidebar {
    color: var(--am-text);
    font-size: var(--am-fs-body);
    line-height: var(--am-lh);
}

.am-sidebar-toolbar { margin-left: auto; }

/* Section tabs use buttons rather than links because they swap one workspace
   pane in place. aria-pressed is the single source of truth for the active
   state, which keeps pointer and assistive-technology feedback aligned. */
.am-tablist {
    display: flex;
    align-items: stretch;
    gap: 3px;
    padding: 3px;
    border: 0;
    border-radius: var(--am-radius);
    background: var(--am-surface-3);
}

.am-tablist > button {
    min-height: var(--am-control-h);
    padding: 0 var(--am-space-3);
    border: 0;
    border-radius: var(--am-radius-sm);
    background: transparent;
    color: var(--am-text-dim);
    font: 800 var(--am-fs-label) var(--am-font-mono);
}

.am-tablist > button:hover:not(:disabled) {
    background: var(--am-surface-3);
    color: var(--am-text-strong);
}

.am-tablist > button[aria-pressed="true"],
.am-tablist > button[aria-current="page"] {
    background: var(--am-accent-bg-strong);
    color: var(--am-accent-text);
    box-shadow: var(--am-shadow-1);
}

/* A floating overlay above the map. */
.am-float {
    border: var(--am-border-width) solid var(--am-border-strong);
    border-radius: var(--am-radius);
    background: var(--am-glass);
    box-shadow: var(--am-shadow-2);
    backdrop-filter: blur(14px);
    color: var(--am-text);
}

/* ---------------------------------------------------------------- buttons -- */

.am-btn {
    min-height: var(--am-control-h);
    padding: 0 var(--am-space-3);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--am-gap-tight);
    border: var(--am-border-width) solid var(--am-border-control);
    border-radius: var(--am-radius-sm);
    background: var(--am-surface-2);
    color: var(--am-text-muted);
    font: 600 var(--am-fs-label) var(--am-font-ui);
    letter-spacing: .015em;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    transition: border-color var(--am-dur-fast) var(--am-ease),
                background-color var(--am-dur-fast) var(--am-ease),
                color var(--am-dur-fast) var(--am-ease);
}

.am-btn:hover:not(:disabled):not([aria-disabled="true"]) {
    border-color: var(--am-border-accent);
    background: var(--am-surface-3);
    color: var(--am-text-strong);
}

.am-btn:disabled,
.am-btn[aria-disabled="true"] {
    opacity: .35;
    filter: saturate(.35);
    cursor: not-allowed;
}

.am-btn-primary {
    border-color: transparent;
    background: var(--am-accent);
    color: var(--am-on-accent);
    box-shadow: var(--am-shadow-1);
}

.am-btn-primary:hover:not(:disabled):not([aria-disabled="true"]) {
    border-color: var(--am-accent-strong);
    background: var(--am-accent-strong);
    color: var(--am-on-accent);
}

.am-btn-danger {
    border-color: var(--am-danger-border);
    background: var(--am-danger-bg);
    color: var(--am-danger-text);
}

.am-btn-danger:hover:not(:disabled):not([aria-disabled="true"]) {
    border-color: var(--am-danger);
    background: #341410;
    color: var(--am-danger-text);
}

/* Selected state for segmented controls and rails. */
.am-btn[aria-pressed="true"],
.am-btn[aria-current="page"],
.am-btn.am-btn-active {
    border-color: var(--am-accent);
    background: var(--am-accent-bg-strong);
    color: var(--am-accent-text);
}

/* Square icon-only button. Always needs an aria-label. */
.am-icon-btn {
    width: 34px;
    height: 34px;
    padding: 0;
    display: inline-grid;
    place-items: center;
    flex: 0 0 auto;
    border: var(--am-border-width) solid transparent;
    border-radius: var(--am-radius-sm);
    background: transparent;
    color: var(--am-text-muted);
    cursor: pointer;
    transition: border-color var(--am-dur-fast) var(--am-ease),
                background-color var(--am-dur-fast) var(--am-ease),
                color var(--am-dur-fast) var(--am-ease);
}

.am-icon-btn:hover:not(:disabled) {
    border-color: var(--am-border-control);
    background: var(--am-surface-2);
    color: var(--am-text-strong);
}

.am-icon-btn:disabled { opacity: .3; cursor: default; }

.am-icon-btn[aria-pressed="true"],
.am-icon-btn[aria-current="page"],
.am-icon-btn.am-btn-active {
    border-color: var(--am-accent-dim);
    background: var(--am-accent-bg-strong);
    color: var(--am-accent-text);
}

/* An entity name that navigates. Reads as text until you approach it. */
.am-entity-link {
    padding: 0;
    border: 0;
    border-bottom: 1px dotted var(--am-accent-dim);
    background: none;
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
    transition: color var(--am-dur-fast) var(--am-ease),
                border-color var(--am-dur-fast) var(--am-ease);
}

.am-entity-link:hover {
    border-bottom-color: var(--am-accent);
    color: var(--am-accent-text);
}

/* ----------------------------------------------------------------- chips -- */

.am-chip {
    min-height: 24px;
    padding: 0 var(--am-space-2);
    display: inline-flex;
    align-items: center;
    gap: var(--am-space-1);
    border: var(--am-border-width) solid var(--am-border-subtle);
    border-radius: var(--am-radius-sm);
    background: var(--am-surface-2);
    color: var(--am-text-muted);
    font: 600 var(--am-fs-micro) var(--am-font-ui);
    letter-spacing: .025em;
    white-space: nowrap;
}

.am-chip-accent { border-color: var(--am-accent-dim); color: var(--am-accent-text); }
.am-chip-warning { border-color: var(--am-warning-border); color: var(--am-warning-text); }
.am-chip-danger { border-color: var(--am-danger-border); color: var(--am-danger-text); }

/* ---------------------------------------------------------------- meters -- */

/* A 0-100 gauge, shared by the credit score, the network strain readout and
   the scorecard. The fill is a child <i> whose width is set inline, matching
   the existing .load-meter pattern used for airport capacity. Severity comes
   from a modifier class rather than from the width, so the same markup reads
   correctly whether high is good (credit) or bad (strain). */
.am-meter {
    position: relative;
    height: 6px;
    border: var(--am-border-width) solid var(--am-border-subtle);
    border-radius: var(--am-radius-sm);
    background: var(--am-surface-1);
    overflow: hidden;
}

.am-meter > i {
    display: block;
    height: 100%;
    background: var(--am-accent);
    transition: width .3s ease;
}

.am-meter.positive > i { background: var(--am-positive); }
.am-meter.neutral > i { background: var(--am-series-2); }
.am-meter.warning > i { background: var(--am-warning); }
.am-meter.negative > i,
.am-meter.critical > i { background: var(--am-danger); }

/* ------------------------------------------------------------ form fields -- */

.am-field {
    min-height: var(--am-control-h);
    padding: 0 var(--am-space-2);
    border: var(--am-border-width) solid var(--am-border-control);
    border-radius: var(--am-radius-sm);
    background: var(--am-surface-1);
    color: var(--am-text-secondary);
    font: var(--am-fs-body) var(--am-font-ui);
    transition: border-color var(--am-dur-fast) var(--am-ease),
                background-color var(--am-dur-fast) var(--am-ease),
                box-shadow var(--am-dur-fast) var(--am-ease);
}

.am-field:hover:not(:disabled):not([readonly]) {
    border-color: var(--am-border-strong);
    background: var(--am-surface-2);
}

.am-field:focus,
.am-field:focus-visible {
    border-color: var(--am-accent);
    outline: none;
    box-shadow: var(--am-focus-ring);
}

.am-field:disabled,
.am-field[readonly] { opacity: .5; cursor: not-allowed; }
.am-field[readonly] { cursor: default; }
.am-field[aria-invalid="true"],
.am-field:invalid:not(:placeholder-shown) { border-color: var(--am-danger-border); }
.am-field::placeholder { color: var(--am-text-faint); }

/* Search field with a leading icon and a trailing clear button. */
.am-search {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: center;
    gap: var(--am-space-1);
    padding: 0 var(--am-space-2);
    border-radius: var(--am-radius-sm);
    transition: border-color var(--am-dur-fast) var(--am-ease),
                background-color var(--am-dur-fast) var(--am-ease),
                box-shadow var(--am-dur-fast) var(--am-ease);
}

.am-search:hover { border-color: var(--am-border-strong); }
.am-search:focus-within { border-color: var(--am-accent); box-shadow: var(--am-focus-ring); }

.am-search > input {
    min-width: 0;
    padding: 0;
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
}

.am-search > input:focus { outline: none; }

/* ----------------------------------------------------------------- table -- */

/* Grid-based table. The parent sets --am-table-cols; header and rows share it
   so columns line up without either side knowing the count. */
.am-table {
    display: flex;
    flex-direction: column;
    min-height: 0;
    overflow: auto;
}

.am-table-head,
.am-table-row {
    display: grid;
    grid-template-columns: var(--am-table-cols, var(--am-col-name) repeat(4, var(--am-col-metric)));
    align-items: center;
    gap: var(--am-space-2);
    text-align: left;
}

.am-table-head {
    position: sticky;
    z-index: 1;
    top: 0;
    padding: 0 var(--am-space-3);
    height: 38px;
    border-bottom: var(--am-border-width) solid var(--am-border);
    background: var(--am-surface-2);
}

.am-table-row {
    height: var(--am-row-h);
    padding: 0 var(--am-space-3);
    width: 100%;
    border: 0;
    border-bottom: var(--am-border-width) solid var(--am-border-subtle);
    background: var(--am-surface-1);
    color: var(--am-text-secondary);
    font: var(--am-fs-body) var(--am-font-mono);
    cursor: pointer;
    transition: background-color var(--am-dur-fast) var(--am-ease);
}

.am-table-row:hover { background: var(--am-surface-3); }
.am-table-row[aria-current="true"] { background: var(--am-accent-bg); }
.am-table-row:focus-visible {
    outline: var(--am-focus-width) solid var(--am-focus-outline);
    outline-offset: -2px;
    background: var(--am-surface-3);
}

/* Sortable column header. The button fills the cell; the wrapping element
   carries role="columnheader" and aria-sort, because a <button> cannot. */
.am-sort-btn {
    width: 100%;
    height: 100%;
    padding: 0;
    display: flex;
    align-items: center;
    gap: var(--am-space-1);
    border: 0;
    background: none;
    color: var(--am-text-dim);
    font: 800 var(--am-fs-micro) var(--am-font-mono);
    letter-spacing: var(--am-track-label);
    text-transform: uppercase;
    text-align: inherit;
    cursor: pointer;
    transition: color var(--am-dur-fast) var(--am-ease);
}

.am-sort-btn:hover { color: var(--am-text-strong); }

/* Numeric headers align to the right edge and put the arrow on the left, so
   the number column keeps a clean edge. */
.am-table-head .am-num .am-sort-btn { flex-direction: row-reverse; justify-content: flex-start; }

/* The indicator is always in the DOM so columns never jump width on sort. */
.am-sort-icon { opacity: 0; flex: 0 0 auto; font-size: 14px; }
.am-sort-btn:hover .am-sort-icon,
.am-sort-btn:focus-visible .am-sort-icon { opacity: .5; }
[aria-sort] .am-sort-icon { opacity: 1; color: var(--am-accent); }

/* ------------------------------------------------------------------ misc -- */

/* Vertical splitter. Renders as a hairline but keeps a 12px hit area. */
.am-resizer {
    position: relative;
    width: 2px;
    flex: 0 0 auto;
    background: var(--am-border-subtle);
    cursor: ew-resize;
    touch-action: none;
}

.am-resizer::before {
    content: "";
    position: absolute;
    inset: 0 -5px;
}

.am-resizer:hover,
.am-resizer:focus-visible,
.am-resizer.am-resizing { background: var(--am-accent); }

/* While a splitter drag is in flight the map must not receive pointer events,
   or MapLibre captures the pointer and the drag dies halfway. */
[data-resizing] { user-select: none; }
[data-resizing] .maplibregl-map { pointer-events: none; }

.am-empty {
    padding: var(--am-space-6);
    color: var(--am-text-faint);
    font: var(--am-fs-body) var(--am-font-mono);
    text-align: center;
}

@media (pointer: coarse) {
    .am-btn,
    .am-icon-btn,
    .am-tablist > button { min-height: var(--am-touch-target); }
    .am-icon-btn { width: var(--am-touch-target); height: var(--am-touch-target); }
}
