/* ==========================================================================
   Astral Sovereignty — "Command" interface preset (first pass)

   A command-console skin over the same screens: glassy dark panels, thin
   glowing blue/cyan edges, uppercase letter-spaced headings. Corners are
   clean — the first pass cut them with clip-path, which sliced the 1px
   border at the diagonal and read as broken; the owner killed it.
   Loaded alongside game.css on every page; EVERY rule here is scoped under
   `.preset-command` (the class rides on <html> — set pre-paint by the inline
   read in index.html, owned by core/preset.js) so with the class absent this
   file changes nothing. tests/ui_preset.test.js pins that scoping.

   Discipline (do not relax these):
   - Chrome (header, tab bars, strips) gets PAINT ONLY: background, border
     color, glow, text color. Its geometry — heights, paddings, sticky
     offsets, tap targets — is pinned by tests/header_layout.test.js against
     game.css, which cannot see this file; nothing here may move it.
   - No `position` anywhere in this file: the sticky stack and the measured
     --chrome-h in app.js stay exactly as game.css built them.
   - No backdrop-filter: it janks scrolling lists on low-end phones. Glass is
     faked with translucent gradients; glow is cheap box-shadow, no filters.
   - No animations added: the base pulse/spin keyframes carry the motion, and
     the global prefers-reduced-motion kill switch in game.css already covers
     everything. If one is ever added here, it must ship with its own
     prefers-reduced-motion guard.
   - No clip-path: cut corners sliced the border open (and would clip focus
     outlines on anything interactive). Panels keep their normal radius.
   ========================================================================== */

/* ---------- 1. Tokens ----------------------------------------------------- */

/* Same custom properties game.css keys everything on, retuned: deeper
   blue-black backgrounds, blue-tinted hairlines, brighter link blue. Text
   tokens are kept or brightened — backgrounds only got darker, so contrast
   only improves. Semantic colors (amber/green/danger and their dims) are
   deliberately untouched: warnings must read the same in every skin. */
.preset-command {
  --bg-0:      #010309;
  --bg-1:      #030711;
  --bg-2:      #060d1c;
  --panel:     #0a1120;
  --panel-2:   #0e1728;
  --panel-3:   #152238;

  --line:      #14263e;
  --line-soft: #0e1b2d;
  --line-lit:  #23496f;
  --edge-ui:   #3d6ea6;

  --blue-lit:  #79b4ff;

  /* "What colour marks the tab you are on" — cyan in Command, as the two
     border-bottom-color rules in section 3 already say twice over. It is a
     token because a layout may put that marker on an edge those two rules
     cannot reach: the app-shell concept moves it to the top border of a bottom
     bar, and a preset that could only speak through `border-bottom-color`
     would silently stop painting it. Answering with the token instead keeps
     the decision here, where every other Command colour decision is, and keeps
     the concept's stylesheet free of both colours and any knowledge that this
     preset exists. Classic's answer is the fallback at the point of use. */
  --tab-current: var(--cyan);

  --text-4:    #7d92af;

  --rad:       6px;
  --rad-sm:    3px;

  /* Command's own knobs.

     EVERY ONE OF THEM IS A MIX OF THE TOKENS ABOVE, and so is every colour in
     the rules below. That is not tidiness — it is what makes the preset
     themeable at all. core/colours.js paints the whole client by writing
     game.css's tokens onto <html>, which beats this block; a hex code written
     into a rule down there is a colour no scheme can reach, and a player who
     picked Ember would get warm panels inside a blue-glowing frame. The numbers
     are the same numbers this file always had, expressed as the mix that
     produces them, so the default scheme is pixel-for-pixel what it was.
     tests/colours.test.js fails on a bare hex outside this block. */
  --cmd-edge:       color-mix(in srgb, var(--edge-ui) 60%, var(--line));   /* panel border */
  --cmd-edge-lit:   color-mix(in srgb, var(--cyan) 55%, var(--blue-lit));  /* accent edge */
  --cmd-glow-blue:  color-mix(in srgb, var(--blue) 28%, transparent);
  --cmd-glow-cyan:  color-mix(in srgb, var(--cyan) 18%, transparent);
  --cmd-head-line:  linear-gradient(90deg, color-mix(in srgb, var(--cyan) 45%, transparent), transparent 70%);

  /* The chrome band and its hairline. A shade between --bg-1 and --bg-2, and a
     hairline between --line and --line-lit: neither had a token of its own and
     both were written four times as a literal. */
  --cmd-chrome-bg:   color-mix(in srgb, var(--bg-1) 70%, var(--bg-2));
  --cmd-chrome-line: color-mix(in srgb, var(--line) 55%, var(--line-lit));
  /* The label of the tab you are ON — brighter than body text, which is the
     whole reason it is not just var(--text). */
  --cmd-tab-ink:     color-mix(in srgb, var(--text) 85%, white);

  /* ---- Art drop-in slots -------------------------------------------------
     Filled with crops from the owner's concept screens (space-assets repo,
     astral-ui-screens: the Reports & Intelligence screen). Concept-derived,
     not production art — when real paintings exist, replace the files and
     nothing here moves. Set either back to `none` to empty a slot.
     --cmd-hero-page  full-width backdrop at the top of every game screen —
                      scrolls with content (no fixed attachment: phone jank).
                      The webp carries its own baked-in vignette: it fades to
                      transparent on every side, so no masking CSS is needed
                      and content panels sit on it without a hard art edge.
     --cmd-hero-auth  backdrop inside the login card, under its glass layer
                      (see section 10 — the glass is tuned to let it read). */
  --cmd-hero-page: url('../img/game/concept/hero_page_nyx_nebula.webp');
  --cmd-hero-auth: url('../img/game/concept/hero_auth_battle_korvus.webp');
}

/* ---------- 2. Backdrop --------------------------------------------------- */

.preset-command #stars { opacity: .7; }
.preset-command ::selection { background: var(--blue-deep); }

.preset-command main.game-main {
  background-image: var(--cmd-hero-page);
  background-repeat: no-repeat;
  background-position: top center;
  background-size: min(100%, 1280px) auto;
}

/* ---------- 3. Chrome — PAINT ONLY (see header comment) ------------------- */

.preset-command .shell-header {
  background: color-mix(in srgb, var(--bg-1) 90%, transparent);
  border-bottom-color: var(--cmd-chrome-line);
  box-shadow: 0 1px 0 color-mix(in srgb, var(--cyan) 8%, transparent);
}
.preset-command .shell-header .brand span { color: var(--cmd-edge-lit); }
/* The generic .btn treatment below uppercases labels (a width change); the
   header's line-fitting is load-bearing, so its buttons opt out. */
.preset-command .shell-header .btn { text-transform: none; letter-spacing: normal; }

.preset-command .tick-chip {
  background: color-mix(in srgb, var(--bg-2) 85%, transparent);
  border-color: var(--line-lit);
  box-shadow: inset 0 1px 0 color-mix(in srgb, var(--cmd-edge-lit) 7%, transparent);
}
.preset-command .shard-chip { border-color: var(--line-lit); }

.preset-command .tabbar {
  background: color-mix(in srgb, var(--cmd-chrome-bg) 97%, transparent);
  border-bottom-color: var(--cmd-chrome-line);
}
.preset-command .tabbar a { text-transform: uppercase; letter-spacing: .04em; }
.preset-command .tabbar a[aria-current="page"] {
  color: var(--cmd-tab-ink);
  border-bottom-color: var(--tab-current);
  text-shadow: 0 0 10px color-mix(in srgb, var(--cyan) 45%, transparent);
}
.preset-command .tabbar a .badge {
  background: color-mix(in srgb, var(--cyan) 14%, transparent);
  color: color-mix(in srgb, var(--cyan) 70%, white);
}

.preset-command .sub-tabbar {
  background: var(--cmd-chrome-bg);
  border-bottom-color: var(--line-soft);
}
.preset-command .sub-tabbar a { text-transform: uppercase; letter-spacing: .04em; font-size: var(--t-xs); }
.preset-command .sub-tabbar a[aria-current="page"] { border-bottom-color: var(--tab-current); }

/* ---------- 4. Cards ------------------------------------------------------ */

/* Glass panels. Glow stays inset — cheap, and it cannot bleed onto
   neighbours. */
.preset-command .card {
  background: linear-gradient(160deg,
    color-mix(in srgb, var(--panel-2) 88%, transparent),
    color-mix(in srgb, var(--bg-2) 93%, transparent));
  border-color: var(--cmd-edge);
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, var(--cmd-edge-lit) 10%, transparent),
    inset 0 0 24px color-mix(in srgb, var(--blue-deep) 16%, transparent);
}
/* Nested sub-cards read as inner readouts: square, accent-edged. */
.preset-command .card--sub {
  background: color-mix(in srgb, var(--bg-2) 80%, transparent);
  border-left: 2px solid var(--cmd-edge);
  box-shadow: none;
}
.preset-command .card.selectable:hover {
  border-color: var(--edge-ui);
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, var(--cmd-edge-lit) 14%, transparent),
    inset 0 0 18px color-mix(in srgb, var(--blue) 14%, transparent);
}
.preset-command .card.is-selected {
  border-color: var(--cmd-edge-lit);
  background: linear-gradient(160deg,
    color-mix(in srgb, var(--panel-3) 90%, transparent),
    color-mix(in srgb, var(--bg-2) 94%, transparent));
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, var(--cmd-edge-lit) 22%, transparent),
    inset 0 0 22px color-mix(in srgb, var(--blue) 18%, transparent);
}

.preset-command .panel-empty { border-color: var(--line-lit); }

/* The map's system panel floats over the LIVE canvas — the one surface where
   translucent glass fails outright: system names and HUD labels read straight
   through the panel and its text. Same hues as the card glass, alpha 1; the
   gradient alone keeps the glass look. (The cards inside the panel may stay
   translucent — they now sit on this opaque backdrop.) */
.preset-command .map-side {
  background: linear-gradient(165deg, var(--panel), var(--bg-1));
  border-left-color: var(--cmd-edge);
}

/* ---------- 5. Headings --------------------------------------------------- */

.preset-command h1 { text-transform: uppercase; letter-spacing: .07em; }
/* Uppercase at 1.45rem is a banner on a 360px screen — with the (base-skin)
   inline icon fix a screen title should be one tight line, so on phones the
   preset pulls the size and tracking back in. Same 799px breakpoint the
   header restacks at; page paint only, no chrome geometry. */
@media (max-width: 799px) {
  .preset-command h1 { font-size: 1.2rem; letter-spacing: .05em; }
}
.preset-command .card > h2,
.preset-command details.card--fold > summary h2,
.preset-command .modal-head h2 {
  text-transform: uppercase;
  letter-spacing: .07em;
  font-size: 1rem;
}
.preset-command .card > h2 {
  padding-bottom: .35rem;
  background: var(--cmd-head-line) left bottom / 100% 1px no-repeat;
}
/* A fold summary is a heading sharing its line with a count chip and a caret, so
   it has ~1.5px less room than the .07em above wants: "No orders this tick (1)"
   wrapped and left the (1) orphaned, at 40px tall against classic's 23px. The
   tracking is the only thing that has to give. */
.preset-command details.card--fold > summary h2 { letter-spacing: .04em; }
.preset-command .card h3 { text-transform: uppercase; letter-spacing: .06em; font-size: .9rem; }

/* ---------- 6. Stats, pills, meters --------------------------------------- */

/* HUD readouts: dim uppercase labels, bright confident values. */
.preset-command .kv dt {
  text-transform: uppercase;
  letter-spacing: .06em;
  font-size: var(--t-xs);
  padding-top: .12rem;   /* optically re-baselines the smaller label */
}
.preset-command .kv dd { color: var(--text); }
.preset-command .res-row .qty { color: color-mix(in srgb, var(--text) 80%, var(--blue-lit)); }

/* currentColor keeps every semantic pill variant its own color. */
.preset-command .pill {
  text-transform: uppercase;
  border-radius: 4px;
  border: 1px solid color-mix(in srgb, currentColor 40%, transparent);
}
.preset-command .release-chip { border-radius: 4px; }
.preset-command .chip { border-radius: 4px; }

/* :not() guards keep base .meter.warn/.meter.bad fills winning — semantic
   colors stay semantic; only the default fill goes blue→cyan. */
.preset-command .meter {
  background: color-mix(in srgb, var(--bg-1) 90%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--cmd-edge-lit) 12%, transparent);
}
.preset-command .meter:not(.warn):not(.bad) > i {
  background: linear-gradient(90deg, var(--blue), var(--cyan));
}

.preset-command .spinner { border-top-color: var(--cyan); }
.preset-command .name-link { color: color-mix(in srgb, var(--cmd-edge-lit) 80%, var(--text)); }

/* ---------- 7. Tables (rankings, battle log, reports) --------------------- */

.preset-command .tbl-wrap { border-color: var(--cmd-edge); }
.preset-command .tbl th {
  background: linear-gradient(180deg, var(--panel-2), var(--panel));
  color: color-mix(in srgb, var(--text-3) 70%, var(--blue-lit));
  letter-spacing: .09em;
  border-bottom-color: color-mix(in srgb, var(--line-lit) 65%, var(--line));
}
.preset-command .tbl td { border-bottom-color: var(--line-soft); }
.preset-command .tbl tbody tr:hover { background: color-mix(in srgb, var(--blue) 8%, transparent); }

/* ---------- 8. Buttons & forms -------------------------------------------- */

.preset-command .btn {
  text-transform: uppercase;
  letter-spacing: .04em;
  background: linear-gradient(180deg, var(--panel-3), var(--panel));
  border-color: var(--line-lit);
}
.preset-command .btn:hover {
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--panel-3) 80%, var(--edge-ui)),
    color-mix(in srgb, var(--panel) 80%, var(--edge-ui)));
  border-color: var(--edge-ui);
}
.preset-command .btn--primary {
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--blue) 85%, var(--blue-lit)),
    color-mix(in srgb, var(--blue) 70%, var(--blue-deep)));
  border-color: var(--blue-lit);
  box-shadow: 0 0 14px var(--cmd-glow-blue);
}
.preset-command .btn--primary:hover {
  background: linear-gradient(180deg, color-mix(in srgb, var(--blue) 60%, var(--blue-lit)), var(--blue));
  border-color: var(--blue-lit);
}
.preset-command .btn--danger { background: transparent; border-color: var(--danger); }
.preset-command .btn--danger:hover { background: var(--danger-dim); }
.preset-command .btn--ghost { background: transparent; border-color: transparent; }
.preset-command .btn--ghost:hover { background: var(--blue-dim); border-color: transparent; }

/* Bare controls (no .field wrapper — the stance pickers, the map note) pick up
   the skin through the retuned tokens in game.css's element-level rule; only
   the focus glow needs restating here. Same text-like set as game.css scopes —
   a blanket input:focus would put the ring on checkboxes and sliders too. */
.preset-command .field input:focus,
.preset-command .field select:focus,
.preset-command .field textarea:focus,
.preset-command input:not([type]):focus,
.preset-command input[type="text"]:focus,
.preset-command input[type="email"]:focus,
.preset-command input[type="number"]:focus,
.preset-command input[type="url"]:focus,
.preset-command input[type="search"]:focus,
.preset-command input[type="password"]:focus,
.preset-command select:focus,
.preset-command textarea:focus {
  border-color: var(--cyan);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--cyan) 15%, transparent);
}
/* Restated after :focus so an invalid field stays red even while focused,
   exactly as the base cascade has it. */
.preset-command .field input[aria-invalid="true"],
.preset-command .field select[aria-invalid="true"] { border-color: var(--danger); }

/* ---------- 9. Banners, toasts, modal ------------------------------------- */

/* Backgrounds only — border-left-color carries ok/warn/bad semantics in the
   base sheet at equal specificity, and this file loads later, so touching
   border-color here would clobber them. */
.preset-command .banner { background: color-mix(in srgb, var(--bg-2) 85%, transparent); }
.preset-command .toast {
  background: color-mix(in srgb, var(--panel) 96%, transparent);
  box-shadow: 0 8px 24px rgba(0, 0, 0, .6),
              0 0 18px color-mix(in srgb, var(--blue-deep) 35%, transparent);
}

.preset-command dialog.modal {
  background: linear-gradient(165deg, var(--panel-2), var(--bg-2));
  border-color: var(--cmd-edge);
  box-shadow: inset 0 1px 0 color-mix(in srgb, var(--cmd-edge-lit) 12%, transparent);
}
.preset-command dialog.modal::backdrop { background: color-mix(in srgb, var(--bg-0) 78%, transparent); }
.preset-command .modal-head {
  border-bottom-color: var(--cmd-edge);
  background: var(--cmd-head-line) left bottom / 100% 1px no-repeat;
}

/* ---------- 10. Login ------------------------------------------------------ */

/* The first thing anyone sees. Brighter edge, and the art slot layered UNDER
   the glass gradient so the scene reads through it. The glass ran .88/.94
   while the slot was empty — dark enough to bury any image outright — so with
   real art in the slot it eases to .70 up top, where the scene shows, and
   stays .90 at the bottom, where the form fields and buttons live. The card's
   opaque --panel background sits under the whole stack, so text contrast
   bottoms out at the gradient, never at a bright pixel of artwork. */
.preset-command .auth-card {
  background-image:
    linear-gradient(170deg,
      color-mix(in srgb, var(--panel-2) 70%, transparent),
      color-mix(in srgb, var(--bg-1) 90%, transparent)),
    var(--cmd-hero-auth);
  background-size: cover;
  background-position: center;
  border-color: var(--cmd-edge);
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, var(--cmd-edge-lit) 18%, transparent),
    inset 0 0 42px color-mix(in srgb, var(--blue-deep) 22%, transparent);
}
.preset-command .auth-card h1 {
  letter-spacing: .1em;
  text-shadow: 0 0 14px var(--cmd-glow-blue);
}

/* ---------- 12. Map key ---------------------------------------------------- */

/* The map's other controls are .btn, so the skin already reaches HOME, SYSTEMS
   and LAYERS. "Map key" is a <summary>, so it alone stayed sentence-case with a
   dim border, pixel-identical to Classic while every neighbour changed — it read
   as a control the skin had forgotten. Paint only: the geometry (min-height,
   padding) stays in game.css, where a test pins it. */
.preset-command .map-key > summary {
  text-transform: uppercase;
  letter-spacing: .04em;
  font-weight: 600;
  border-color: var(--blue-lit);
}
