@charset "UTF-8";
/**
 * Shared modal shell (spec-migration §6, #52): right-side panel over a
 * scrim, the legacy /wa header-modal layout. Skin comes from the
 * --lms-* tokens on .lms-core-widget; the scrim alpha is structural
 * (a dimming layer, not a brand color). Responsive per AGENTS.md:
 * full-width panel under 480px, 40px touch targets.
 *
 * ONE SHELL, BOTH DRAWERS. The Fleet Menu and the Empty Leg Menu render
 * this markup, exactly as the legacy .aircraft-search-modal and
 * .black-modal shared a single rule block in style-overwrite.css. A change
 * here lands on both, which is the point.
 *
 * TWO SKINS. The drawers are dark; the Empty Legs spec sheet is the legacy
 * .white-modal — the same right-hand panel, light. `.lms-modal--light` on
 * the root selects it (see "THE LIGHT SKIN" below).
 *
 * One shared file, plugin-level like the variation tokens it composes
 * with. It is SCSS like every other stylesheet here: it was the single
 * hand-written .css in the tree, which put it outside `npm run build:css`
 * AND outside the check:css drift gate — the one file a contributor could
 * edit in place without anything noticing.
 */
.lms-modal {
  position: fixed;
  inset: 0;
  z-index: 99999;
  background: rgba(0, 0, 0, 0.4); /* Structural scrim, deliberately not tokenized. */
  display: flex;
  justify-content: flex-end;
  /*
   * THE SHELL RENDERS INLINE, WHERE THE SHORTCODE SITS, so a block theme
   * lays it out as one of its content children: Twenty Twenty-Four's
   * constrained-layout rule puts `max-width: <content-size>;
   * margin-inline: auto; margin-block-start: 1.2rem` on every child of
   * .entry-content, and a fixed element still honours margins and
   * max-width. The drawer opened 620px wide, floating in the MIDDLE of
   * the page with its scrim inset from all four edges, which is how both
   * menus looked on every block-theme page (the /wa routes escaped it —
   * they are not block content — which is why it read as an
   * Empty-Legs-only fault).
   *
   * !important IS THE CORRECT TOOL HERE, and the only one. The rule being
   * countered is
   *
   *   .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)) {
   *     max-width: var(--wp--style--global--content-size);
   *     margin-left: auto !important; margin-right: auto !important; }
   *
   * printed by WordPress itself, with its own !important on the margins —
   * no amount of specificity beats that, and the max-width ties at (0,1,0)
   * and is decided by whichever sheet the host prints last. The shell is
   * not a content block and must not be laid out as one; a plugin cannot
   * choose its host theme, so it states that unconditionally.
   */
  margin: 0 !important;
  max-width: none !important;
}

.lms-modal[hidden] {
  display: none;
}

/*
 * The panel is DARK, which is the legacy treatment for every modal that
 * survived the migration: the /wa header modals and the empty-leg spec
 * overlay were all a black drawer with inverted type
 * (.lx-modal-container: #000 ground, #fff text, 30px 40px 30px 30px).
 * The first port rendered them light-on-light, so the drawer read as a
 * second page rather than an overlay.
 *
 * Built from the --lms-color-invert pair, NOT from --lms-color-text: on
 * the light brands that pair is the design's #000, while the text colour
 * is a soft #333 that rendered the drawer dark grey. On the dark
 * variation the pair swaps, so the panel stays a contrasting surface
 * instead of becoming a black box on a black page.
 */
.lms-modal__panel {
  width: 45vw;
  /* The cap is an ultrawide guard, not the intended width. It used to be
     720px against a 50vw request, which meant it bound from 1440px up and
     the drawer was 37.5% of a 1920 screen rather than the half it claimed.
     900px keeps 45vw honest on every ordinary display and only bites past
     2000px, where a drawer half the desk wide stops being a drawer. */
  max-width: 900px;
  height: 100%;
  overflow-y: auto;
  font-family: var(--lms-font-body);
  font-size: var(--lms-font-size-base);
  /* Compact: the legacy 30/40/40/30 was a page inset on a drawer. The
     drawer is a summary of something bigger — it holds rows, not a
     layout — so it takes a tighter, even one. */
  /* No top padding: the pinned head (below) carries it, so nothing can
     scroll through a gap above the stuck head. */
  padding: 0 26px 30px;
  box-sizing: border-box;
  /* The drawer's own edge. The scrim alone left it reading as a black
     area of the page on a dark hero; a cast shadow separates the two
     planes the way the panel's elevation implies. Structural, like the
     scrim it sits on. */
  box-shadow: -18px 0 46px rgba(0, 0, 0, 0.38);
}

/*
 * THE DRAWER IS A DARK SCOPE, and every module that renders into it gets
 * that for free.
 *
 * Both drawers fill their body with markup authored for the PAGE — the
 * Empty Leg Menu injects list fragments, the spec overlay is a page section
 * promoted in place — and that markup paints itself in --lms-color-bg /
 * --lms-color-surface / --lms-color-text like everything else in the
 * plugin. On a black panel that produced the exact fault reported: full
 * white cards stacked inside the drawer, and body copy in a #333 that
 * vanished into the ground.
 *
 * Re-pointing the SURFACE tokens for the subtree fixes every such component
 * at once, and keeps the alternative — a per-component inverted override in
 * each module sheet, forever, for each new one — off the table. Fleet's
 * drawer content was already written against --lms-color-invert-contrast
 * and currentcolor, so it is unaffected.
 *
 * --lms-color-primary is NOT remapped: the accent gold is legible on the
 * panel and is the drawer's one colour. Nor is the --lms-color-invert pair
 * itself — the panel paints from it, and a redefinition here would
 * resolve into that very declaration.
 *
 * Scoped to the open, dark-skinned shell: the paint and the remap are one
 * decision, taken together, and neither applies to a light modal or to
 * the spec sheet's inline (no-JS) state, where the panel element is a
 * plain page section.
 */
.lms-modal:not(.lms-modal--light) .lms-modal__panel {
  background: var(--lms-color-invert);
  color: var(--lms-color-invert-contrast);
  --lms-color-bg: var(--lms-color-invert);
  --lms-color-surface: var(--lms-color-invert);
  /* The one step off the ground the drawer has: placeholders, hovers and
     any tinted band inside the injected markup. */
  --lms-color-page-bg: color-mix(in srgb, var(--lms-color-invert-contrast) 8%, var(--lms-color-invert));
  --lms-color-text: var(--lms-color-invert-contrast);
  --lms-color-text-muted: color-mix(in srgb, var(--lms-color-invert-contrast) 60%, transparent);
  --lms-color-border: color-mix(in srgb, var(--lms-color-invert-contrast) 18%, transparent);
  /* A drop shadow is invisible on black and only fuzzes the edge. */
  --lms-shadow-card: none;
}

.lms-modal__panel *,
.lms-modal__panel *::before,
.lms-modal__panel *::after {
  box-sizing: border-box;
}

/* Legacy .lx-modal-header: search left, close right. The legacy 50px gap
   before the list is gone — it pushed the first row of a COMPACT list
   below the fold of a laptop panel for no gain, and a hairline says
   "header ends here" in 24px what whitespace was saying in 50. */
.lms-modal__head {
  display: flex;
  align-items: center;
  gap: 16px;
  /* PINNED while the list scrolls (Christine, 2026-09-28 — the close and
     the search must stay reachable on a phone). The panel is the scroll
     box, so the head sticks to its top edge; it spans the panel's full
     width over the side padding (negative SIDE margins = the panel's
     inset, restated as its own padding; the panel's top padding lives
     here outright, because Chromium pins a sticky box by its margin
     box and a negative top margin left it 18px low) and paints the
     panel's ground, so rows pass under it edge to edge. */
  position: sticky;
  top: 0;
  z-index: 2;
  margin: 0 -26px 18px;
  padding: 24px 26px 16px;
  background: var(--lms-color-bg);
  border-bottom: 1px solid color-mix(in srgb, var(--lms-color-invert-contrast) 16%, transparent);
}

.lms-modal__title {
  font-family: var(--lms-font-display);
  font-size: 1.34em;
  font-weight: 400;
  line-height: 1.2;
  margin: 0;
  flex: 0 0 auto;
  color: var(--lms-color-invert-contrast);
}

/* Inverted with the panel: legacy set the search a shade off the panel
   ground (#2c2c2c on #000) with a magnifier chip a shade darker again
   (#181818) and a gold rule only while it holds focus. Derived from the
   tokens so it follows the panel on either variation.

   The glyph is a background image rather than a sibling element so the
   search stays ONE control — the legacy .input-group needed two nodes and
   a wrapper to say the same thing.

   HALF THE HEAD, LEFT-ALIGNED, which is the legacy .input-group.search
   width exactly. It used to grow into whatever the title and close left
   over, so on the Fleet drawer — whose title is visually hidden — it
   stretched the full width of the panel and read as a text field someone
   had forgotten to size. The close button keeps its own margin-left: auto,
   so the two sit at opposite ends with the gap between them. */
.lms-modal__search {
  flex: 0 1 50%;
  min-width: 0;
  min-height: 44px; /* Touch target (AGENTS.md). */
  padding: 8px 12px 8px 42px;
  font: inherit;
  color: var(--lms-color-invert-contrast);
  background-color: color-mix(in srgb, var(--lms-color-invert-contrast) 14%, var(--lms-color-invert));
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23a0a0a0' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='m20 20-3.6-3.6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: 13px center;
  background-size: 18px 18px;
  border: 1px solid transparent;
  border-radius: var(--lms-input-radius);
  transition: border-color 0.2s ease;
}

.lms-modal__search::placeholder {
  color: var(--lms-color-invert-contrast);
  opacity: 0.55;
}

/* The one place a focus rule survives the core FOCUS POLICY as a border
   change: a search field is typed into, so it has to say where the caret
   went. It is the border colour only — no ring, no second box. */
.lms-modal__search:focus,
.lms-modal__search:focus-visible {
  border-color: var(--lms-color-primary);
  outline: none;
}

/* Clear the engine-drawn X on type=search: the panel is dark and the
   native glyph paints black on black. */
.lms-modal__search::-webkit-search-cancel-button {
  -webkit-appearance: none;
  appearance: none;
}

.lms-modal__close {
  flex: 0 0 auto;
  margin-left: auto;
  width: 40px;
  height: 40px; /* Touch target (AGENTS.md). */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 22px;
  line-height: 1;
  background: none;
  border: 1px solid color-mix(in srgb, var(--lms-color-invert-contrast) 45%, transparent);
  border-radius: 999px;
  color: var(--lms-color-invert-contrast);
  cursor: pointer;
  transition: border-color 0.2s ease, color 0.2s ease;
}

.lms-modal__close:hover,
.lms-modal__close:focus-visible {
  border-color: var(--lms-color-primary);
  color: var(--lms-color-primary);
}

/*
 * The three non-list states — loading, no records, unavailable — are one
 * element in this shell, where the legacy component had three mutually
 * exclusive branches. They share the legacy placement: centred, a long way
 * down the panel, never a line of text jammed under the search box.
 */
.lms-modal__status {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  color: var(--lms-color-invert-contrast);
  padding: 22vh 0 0;
  text-align: center;
  font-size: 1.07em;
  line-height: 1.5;
}

.lms-modal__status--error {
  color: var(--lms-color-error);
}

/* Legacy .lds-ring: a white ring on the dark panel, not a gold one. The
   status text stays underneath, so a slow fetch says what it is doing. */
.lms-modal__status--loading::before {
  content: "";
  width: 56px;
  height: 56px;
  border: 5px solid color-mix(in srgb, var(--lms-color-invert-contrast) 22%, transparent);
  border-top-color: var(--lms-color-invert-contrast);
  border-radius: 50%;
  animation: lms-spin 1.1s linear infinite;
}

@media (prefers-reduced-motion: reduce) {
  .lms-modal__status--loading::before {
    animation-duration: 2.6s;
  }
}
.lms-modal-locked {
  overflow: hidden;
}

/*
 * THE LIGHT SKIN — the legacy .white-modal (STYLE-SPEC.md §6.4): the spec
 * sheet is a white panel with black type, in both the wa app and the
 * lmsplugin widget. With the dark paint and remap scoped out above, the
 * panel and everything inside it keep the page's own tokens; what is
 * restated here is only the shell chrome that names the invert pair
 * outright. Module sheets own the sheet's layout.
 */
.lms-modal--light .lms-modal__panel {
  background: var(--lms-color-bg);
  color: var(--lms-color-text);
}

.lms-modal--light .lms-modal__head {
  /* The head sticks while the sheet scrolls (workspace-e3's phone round, 2026-09-28), so it needs the skin's own ground under it. */
  background: var(--lms-color-bg);
  border-bottom-color: var(--lms-color-border);
}

.lms-modal--light .lms-modal__title {
  color: var(--lms-color-text);
}

/* Legacy close-circle-icon-black.svg: a black ring with a black cross. */
.lms-modal--light .lms-modal__close {
  border-color: var(--lms-color-invert);
  color: var(--lms-color-invert);
}

@media (max-width: 992px) {
  .lms-modal__panel {
    width: 75vw;
  }
}
@media (max-width: 700px) {
  /* Full width from here down, not only under 480px: a 500–700px phone
     or split view got a 75vw drawer floating over a strip of page
     (Christine, 2026-09-28). */
  .lms-modal__panel {
    width: 100vw;
    max-width: none;
    padding: 0 18px 28px;
  }
  .lms-modal__head {
    flex-wrap: wrap;
    gap: 12px;
    /* The panel's tighter inset, restated (see the base rule). */
    margin: 0 -18px 16px;
    padding: 18px 18px 14px;
  }
  /* Title and close on the first line, the search full width under them:
     at this width a half-width field is too narrow to read back what has
     been typed into it. */
  .lms-modal__search {
    order: 3;
    flex-basis: 100%;
  }
  .lms-modal__status {
    padding-top: 14vh;
  }
}
