/* Pyxis — account site.
   The CSP forbids inline style: every bit of styling lives here.
   No external webfont: the CSP is default-src 'self' and the system font is free. */

:root {
  --bg: #0b0f14;
  --panel: #131a22;
  --panel-2: #1a232e;
  --line: #24303d;
  --ink: #dfe7ef;
  --dim: #8fa1b3;
  --accent: #ff8a1f;      /* the game's HUD orange */
  --accent-ink: #1b1206;
  --ok: #4ade80;
  --warn: #e0b341;
  --bad: #f87171;
}

* { box-sizing: border-box; }

/* Used by every element that appears and disappears without a reload. It was
   missing: without it the suggestions dropdown and the chosen-origin field
   stayed visible all the time. */
.hidden { display: none !important; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 16px/1.55 "Segoe UI", system-ui, -apple-system, sans-serif;
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

/* ------------------------------------------------------------------ top */
.topbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap;
  padding: .85rem 1.25rem;
  border-bottom: 1px solid var(--line);
  background: var(--panel);
}
.brand { font-weight: 700; letter-spacing: .04em; text-transform: uppercase; }
.topbar nav { display: flex; align-items: center; gap: 1rem; }
.topbar .cta {
  background: var(--accent); color: var(--accent-ink);
  padding: .4rem .8rem; border-radius: 6px; font-weight: 600;
}
.topbar .cta:hover { text-decoration: none; filter: brightness(1.1); }
.inline { display: inline; }

/* Discreet destructive action inside a table: it looks like a link, but it is a
   form button — the action is a POST with CSRF, never a GET that a prefetch fires. */
.button-link {
  display: inline-flex; align-items: center; gap: .35rem;
  background: var(--panel-2); border: 1px solid var(--line);
  padding: .35rem .7rem; cursor: pointer; white-space: nowrap;
  color: var(--dim); font: inherit; font-size: .8rem; border-radius: 7px;
  transition: border-color .15s ease, color .15s ease, background .15s ease;
}
.button-link:hover {
  color: var(--bad); border-color: var(--bad);
  background: color-mix(in srgb, var(--bad) 14%, transparent);
}
.linkish {
  background: none; border: 0; color: var(--accent);
  font: inherit; cursor: pointer; padding: 0;
}
.linkish:hover { text-decoration: underline; }

/* ---------------------------------------------------------------- body */
main { max-width: 62rem; margin: 0 auto; padding: 2rem 1.25rem 3rem; }
h1 { font-size: 1.9rem; margin: 0 0 .5rem; }
h2 { font-size: 1.25rem; margin: 2rem 0 .75rem; }
.lead { color: var(--dim); font-size: 1.05rem; max-width: 46rem; }

.panel {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 10px; padding: 1.25rem; margin: 1rem 0;
}

.grid { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); }

/* --------------------------------------------------------------- forms */
form.stack { display: flex; flex-direction: column; gap: .9rem; max-width: 26rem; }
label { display: block; font-size: .9rem; color: var(--dim); margin-bottom: .25rem; }
input[type=email], input[type=password], input[type=text] {
  width: 100%; padding: .6rem .7rem;
  background: var(--panel-2); color: var(--ink);
  border: 1px solid var(--line); border-radius: 6px;
  font: inherit;
}
input:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
button.primary {
  background: var(--accent); color: var(--accent-ink);
  border: 0; border-radius: 6px; padding: .65rem 1.1rem;
  font: inherit; font-weight: 600; cursor: pointer;
}
button.primary:hover { filter: brightness(1.1); }
.hint { font-size: .85rem; color: var(--dim); }

/* -------------------------------------------------------------- warnings */
.flash {
  padding: .7rem .9rem; border-radius: 8px; margin: 0 0 1rem;
  border: 1px solid var(--line); background: var(--panel-2);
}
.flash.ok  { border-color: var(--ok);  color: var(--ok); }
.flash.bad { border-color: var(--bad); color: var(--bad); }

/* --------------------------------------------------------------- table */
table { width: 100%; border-collapse: collapse; font-size: .93rem; }
th, td { text-align: left; padding: .55rem .6rem; border-bottom: 1px solid var(--line); }
th { color: var(--dim); font-weight: 600; }
td.num { text-align: right; font-variant-numeric: tabular-nums; }
.empty { color: var(--dim); font-style: italic; }

/* ---------------------------------------------------------------- key */
.key {
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  font-size: 1.35rem; letter-spacing: .12em;
  background: var(--panel-2); border: 1px dashed var(--accent);
  border-radius: 8px; padding: .8rem 1rem; display: inline-block;
  word-break: break-all;
}
.badge {
  display: inline-block; font-size: .78rem; padding: .1rem .5rem;
  border-radius: 999px; border: 1px solid var(--line); color: var(--dim);
}
.badge.on { border-color: var(--ok); color: var(--ok); }

/* Planetary (surface-landing) marker on a route step's station. */
.badge-planet {
  display: inline-block; font-size: .72rem; font-weight: 600;
  padding: .04rem .4rem; margin-left: .35rem; border-radius: 999px;
  border: 1px solid var(--warn); color: var(--warn);
  vertical-align: middle; white-space: nowrap;
}
.badge-planet i { margin-right: .2rem; }

/* How fresh the route's prices are, on each step. Dim by default; the warn colour
   kicks in when the data is over a day old (an old price may be gone on arrival). */
.data-age { color: var(--dim); white-space: nowrap; }
.data-age i { margin-right: .2rem; }
.data-age.stale { color: var(--warn); }

/* ---------------------------------------------------------------- footer */
footer {
  border-top: 1px solid var(--line); padding: 1.5rem 1.25rem;
  color: var(--dim); font-size: .88rem; text-align: center;
}
.fineprint { font-size: .8rem; opacity: .8; }

/* ========================== admin panel ========================== */
.adminnav {
  display: flex; gap: 1.25rem; flex-wrap: wrap;
  padding: .6rem 0 1rem; margin-bottom: .5rem;
  border-bottom: 1px solid var(--line); font-size: .95rem;
}

.stat { text-align: center; padding: 1rem; }
.stat-num { font-size: 1.9rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.stat-lbl { color: var(--dim); font-size: .85rem; margin-top: .2rem; }

.badge.bad { border-color: var(--bad); color: var(--bad); }

.botoes { display: flex; gap: .6rem; flex-wrap: wrap; margin-top: 1rem; }
.botoes button, button.danger {
  background: var(--panel-2); color: var(--ink);
  border: 1px solid var(--line); border-radius: 6px;
  padding: .55rem 1rem; font: inherit; cursor: pointer;
}
.botoes button:hover { border-color: var(--accent); }
button.danger { border-color: var(--bad); color: var(--bad); }
button.danger:hover { background: var(--bad); color: #fff; }
.botoes button.primary { background: var(--accent); color: var(--accent-ink); border: 0; font-weight: 600; }

.actions label { margin-top: .5rem; }
.license-row {
  border-top: 1px solid var(--line);
  padding-top: 1rem; margin-top: 1rem;
}
.license-row:first-of-type { border-top: 0; padding-top: 0; margin-top: 0; }

input[type=file] {
  width: 100%; padding: .5rem;
  background: var(--panel-2); color: var(--ink);
  border: 1px solid var(--line); border-radius: 6px; font: inherit;
}

/* Second-factor QR: fixed white background, because a camera reader needs real
   contrast — the page's dark theme inverted trips up many scanners. */
.qr {
  display: inline-block;
  background: #fff;
  padding: .75rem;
  border-radius: 10px;
  line-height: 0;
  margin: .5rem 0 1rem;
}
.qr svg { display: block; }

/* ============================ visual ============================ */
.hero {
  padding: 2.5rem 2rem;
  margin: -1rem 0 1.5rem;
  border-radius: 14px;
  border: 1px solid var(--line);
  background:
    radial-gradient(ellipse 70% 120% at 12% -20%, rgba(255,138,31,.16), transparent 60%),
    linear-gradient(180deg, var(--panel) 0%, var(--bg) 100%);
}
.hero h1 { font-size: 2.2rem; line-height: 1.2; margin-bottom: .75rem; }
.hero h1 i { color: var(--accent); }
.hero .lead { margin: 0; }

h2 i, h1 i { color: var(--accent); margin-right: .35rem; }
.topbar nav i { opacity: .85; margin-right: .3rem; }
.brand i { color: var(--accent); }

.panel { transition: border-color .15s ease; }
.grid > .panel:hover { border-color: var(--accent-dim, #b3650e); }

.button-large {
  display: inline-flex; align-items: center; gap: .5rem;
  background: var(--accent); color: var(--accent-ink);
  padding: .7rem 1.3rem; border-radius: 8px;
  font-weight: 600; text-decoration: none;
}
.button-large:hover { filter: brightness(1.1); text-decoration: none; }

.steps { list-style: none; padding: 0; }
.steps li {
  padding: .6rem 0 .6rem 2.2rem; position: relative;
  border-bottom: 1px solid var(--line);
}
.steps li:last-child { border-bottom: 0; }
.steps li i { position: absolute; left: 0; top: .75rem; color: var(--accent); }

.flash i { margin-right: .4rem; }
button i, .cta i { margin-right: .35rem; }

/* ====================== station search ====================== */
.autocomplete { position: relative; margin-bottom: 1rem; }
.autocomplete input { width: 100%; }

.dropdown {
  position: absolute; z-index: 20; left: 0; right: 0; top: 100%;
  margin-top: .25rem; max-height: 20rem; overflow-y: auto;
  background: var(--panel-2); border: 1px solid var(--line);
  border-radius: 8px; box-shadow: 0 12px 32px rgba(0,0,0,.5);
}
.dropdown.hidden { display: none; }

.ac-item { padding: .5rem .75rem; cursor: pointer; border-bottom: 1px solid var(--line); }
.ac-item:last-child { border-bottom: 0; }
.ac-item.marked { background: var(--panel); }
.ac-name { color: var(--ink); }
.ac-meta { color: var(--dim); font-size: .82rem; }
.ac-msg { padding: .7rem .75rem; color: var(--dim); font-size: .88rem; }

.button-secondary {
  display: inline-flex; align-items: center; gap: .45rem;
  background: var(--panel-2); color: var(--accent);
  border: 1px solid var(--line); border-radius: 8px;
  padding: .55rem 1rem; font: inherit; cursor: pointer;
}
.button-secondary:hover { border-color: var(--accent); }
.button-secondary.used { color: var(--ok); border-color: var(--ok); }

.chip {
  display: inline-block; margin: .15rem .2rem;
  padding: .18rem .6rem; border-radius: 999px;
  border: 1px solid var(--line); color: var(--ink);
  font-size: .82rem; text-decoration: none;
}
.chip:hover { border-color: var(--accent); color: var(--accent); text-decoration: none; }

/* ========================= internal logs ========================= */
select {
  width: 100%; padding: .6rem .7rem;
  background: var(--panel-2); color: var(--ink);
  border: 1px solid var(--line); border-radius: 6px; font: inherit;
}
.badge.warn { border-color: var(--warn, #e0b341); color: var(--warn, #e0b341); }
.stat-num.error { color: var(--bad); }
.nowrap { white-space: nowrap; }
table.log { font-family: ui-monospace, Consolas, monospace; font-size: .82rem; }
table.log td { vertical-align: top; }

/* ===================== field help ===================== */
label { display: flex; align-items: center; gap: .4rem; }
.help { color: var(--dim); cursor: help; position: relative; display: inline-flex; }
.help:hover, .help:focus { color: var(--accent); outline: none; }
.help .tip {
  position: absolute; bottom: 140%; left: 50%; transform: translateX(-50%);
  width: 17rem; padding: .6rem .7rem;
  background: var(--panel-2); color: var(--ink);
  border: 1px solid var(--accent); border-radius: 8px;
  font-size: .82rem; line-height: 1.45; font-weight: 400;
  box-shadow: 0 10px 26px rgba(0,0,0,.55);
  opacity: 0; visibility: hidden; transition: opacity .12s ease;
  z-index: 30; pointer-events: none;
}
.help:hover .tip, .help:focus .tip { opacity: 1; visibility: visible; }

.suggestions { padding: .9rem 1rem; }
.suggestions .chip { margin: .2rem; }

/* ==================================================================== */
/*  Routes page — application layout                                    */
/* ==================================================================== */

.app {
  display: grid; gap: 1.25rem; align-items: start;
  grid-template-columns: minmax(0, 22rem) minmax(0, 1fr);
}
@media (max-width: 60rem) { .app { grid-template-columns: 1fr; } }

main { max-width: 76rem; }

.card {
  background: linear-gradient(180deg, var(--panel) 0%, #11161d 100%);
  border: 1px solid var(--line); border-radius: 14px; padding: 1.25rem;
}
.card h2 { margin: 0 0 1rem; font-size: 1.05rem; letter-spacing: .02em; }
.section-title { margin-top: 2.5rem; }

/* ------------------------------------------------------------- HUD */
.hud {
  display: flex; align-items: center; gap: 1rem; flex-wrap: wrap;
  padding: 1rem 1.25rem; margin-bottom: 1.25rem;
  border-radius: 14px; border: 1px solid var(--line);
  background: linear-gradient(100deg, var(--panel) 0%, #11161d 100%);
}
.hud-alive { border-left: 3px solid var(--ok); }
.hud-dead { border-left: 3px solid var(--line); }
.hud-icon {
  width: 2.75rem; height: 2.75rem; flex: none;
  display: grid; place-items: center; border-radius: 50%;
  background: var(--panel-2); font-size: 1.1rem;
}
.hud-alive .hud-icon { color: var(--ok); }
.hud-dead .hud-icon { color: var(--dim); }
.hud-text { display: flex; flex-direction: column; gap: .15rem; min-width: 12rem; flex: 1; }
.hud-text strong { font-size: 1rem; }
.hud-text span { color: var(--dim); font-size: .88rem; }
.hud-text b { color: var(--ink); }
.hud-data { display: flex; gap: 1.75rem; margin: 0; }
.hud-data dt { color: var(--dim); font-size: .72rem; text-transform: uppercase; letter-spacing: .06em; }
.hud-data dd { margin: .1rem 0 0; font-variant-numeric: tabular-nums; }

/* The next action, the same one the app shows: whoever has the site open does not
   need to switch windows to know what to do now. */
.hud-action-txt { color: var(--accent) !important; font-weight: 600; }

/* Game warnings (fuel, legal state, wrong target). They take the whole line
   because they are running text, not a column datum. */
.hud-warnings {
  flex-basis: 100%; margin: .25rem 0 0; padding: 0; list-style: none;
  display: flex; flex-direction: column; gap: .3rem;
}
.hud-warnings li {
  font-size: .84rem; color: var(--warn);
  padding: .4rem .6rem; border-radius: 8px;
  background: color-mix(in srgb, var(--warn) 12%, transparent);
}
.hud-warnings i { margin-right: .35rem; }
/* Costly mistake in progress: the app plays a sound and flashes; here, solid red.
   An alert that changes weight depending on the screen stops being an alert. */
.hud-warnings li.severe {
  color: #fff; font-weight: 600;
  background: var(--bad);
  animation: alert-pulse 1.24s ease-in-out infinite;
}
@keyframes alert-pulse {
  0%, 100% { background: var(--bad); }
  50%      { background: #ff2d2d; }
}
@media (prefers-reduced-motion: reduce) {
  .hud-warnings li.severe { animation: none; }
}

/* ---------------------------------------------------------- fields */
.field { margin-bottom: 1rem; }
.field > label {
  font-size: .8rem; text-transform: uppercase; letter-spacing: .06em;
  color: var(--dim); margin-bottom: .4rem;
}
.pair { display: grid; grid-template-columns: 1fr 1fr; gap: .75rem; }
@media (max-width: 30rem) { .pair { grid-template-columns: 1fr; } }

.input-icon { position: relative; display: flex; align-items: center; }
.input-icon > i:first-child {
  position: absolute; left: .7rem; color: var(--dim); pointer-events: none; font-size: .9rem;
}
.input-icon input { padding-left: 2.1rem !important; }
.input-icon .suffix {
  position: absolute; right: .7rem; color: var(--dim); font-size: .82rem; pointer-events: none;
}
.input-icon:focus-within > i:first-child { color: var(--accent); }

.chosen {
  display: flex; align-items: center; gap: .5rem; margin: .5rem 0 0;
  padding: .5rem .7rem; border-radius: 8px;
  background: rgba(255,138,31,.09); border: 1px solid rgba(255,138,31,.35);
  font-size: .9rem;
}
.chosen i { color: var(--accent); }
.chosen .clear {
  margin-left: auto; background: none; border: 0; color: var(--dim); cursor: pointer;
}
.chosen .clear:hover { color: var(--bad); }

.band { display: flex; align-items: center; gap: .8rem; }
.band input[type=range] { flex: 1; accent-color: var(--accent); }
.band output {
  min-width: 3.5rem; text-align: right; font-variant-numeric: tabular-nums;
  color: var(--accent); font-weight: 600;
}

.chips { display: flex; flex-wrap: wrap; gap: .35rem; }
button.chip { background: transparent; cursor: pointer; font: inherit; }

.markers { display: grid; gap: .5rem; margin-top: .75rem; }
.marker { display: flex; align-items: center; gap: .55rem; cursor: pointer; font-size: .9rem; }
.marker input { accent-color: var(--accent); width: 1rem; height: 1rem; }
.marker span { color: var(--ink); }

.advanced { margin: .5rem 0 1rem; border-top: 1px solid var(--line); padding-top: .75rem; }
.advanced summary { cursor: pointer; color: var(--dim); font-size: .9rem; user-select: none; }
.advanced summary:hover { color: var(--accent); }
.advanced[open] summary { margin-bottom: .9rem; color: var(--ink); }

.wide { width: 100%; justify-content: center; }
button.primary.wide { display: flex; align-items: center; gap: .5rem; padding: .8rem; font-size: 1rem; }
.center { text-align: center; }

/* -------------------------------------------------------- result */
.result { min-height: 22rem; }
.empty-initial {
  display: grid; place-items: center; gap: 1rem; text-align: center;
  padding: 5rem 2rem; color: var(--dim);
  border: 1px dashed var(--line); border-radius: 14px;
}
.empty-initial i { font-size: 2.5rem; opacity: .35; }

.calculating {
  display: grid; place-items: center; gap: .6rem; text-align: center;
  padding: 4rem 2rem; border: 1px solid var(--line); border-radius: 14px;
  background: var(--panel);
}
.orbit {
  width: 4rem; height: 4rem; border-radius: 50%;
  border: 2px solid var(--line); border-top-color: var(--accent);
  display: grid; place-items: center; color: var(--accent);
  animation: spin 1.1s linear infinite;
}
.orbit i { animation: spin 1.1s linear infinite reverse; }
@keyframes spin { to { transform: rotate(360deg); } }
.calc-title { font-size: 1.05rem; color: var(--ink); margin: .5rem 0 0; }
.calc-time { font-variant-numeric: tabular-nums; color: var(--accent); font-size: 1.6rem; margin: .25rem 0 0; }

.summary {
  display: flex; align-items: center; gap: 2rem; flex-wrap: wrap;
  padding: 1.1rem 1.25rem; margin-bottom: 1rem;
  border-radius: 14px; border: 1px solid rgba(255,138,31,.35);
  background: linear-gradient(100deg, rgba(255,138,31,.10), transparent 70%), var(--panel);
}
.summary > div { display: flex; flex-direction: column; }
.summary-label { color: var(--dim); font-size: .72rem; text-transform: uppercase; letter-spacing: .06em; }
.summary-value { font-size: 1.35rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.summary .primary { margin-left: auto; }
.summary .primary.ready { background: var(--ok); }

.route-steps { list-style: none; margin: 0; padding: 0; }
.step { display: flex; gap: 1rem; padding-bottom: 1rem; position: relative; }
.step::before {
  content: ''; position: absolute; left: 1.05rem; top: 2.4rem; bottom: 0;
  width: 2px; background: var(--line);
}
.step:last-child::before { display: none; }
.step-num {
  width: 2.15rem; height: 2.15rem; flex: none; border-radius: 50%;
  display: grid; place-items: center; font-weight: 700;
  background: var(--accent); color: var(--accent-ink); z-index: 1;
}
.step-body {
  flex: 1; min-width: 0;
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 12px; padding: .9rem 1rem;
}
.step-title { display: flex; gap: .6rem; flex-wrap: wrap; align-items: baseline; }
.step-title .from i, .step-title .to i { color: var(--accent); margin-right: .3rem; }
.step-meta { color: var(--dim); font-size: .85rem; margin: .45rem 0 .7rem; }
.step-meta i { margin-right: .2rem; opacity: .7; }
.profit { color: var(--ok); }

table.cargo { font-size: .87rem; }
table.cargo th { font-size: .72rem; text-transform: uppercase; letter-spacing: .05em; }
table.cargo td, table.cargo th { padding: .4rem .5rem; }

.card.notice { border-color: rgba(224,85,85,.4); }
.card.notice h3 { margin: 0 0 .5rem; }
.card.notice h3 i { color: var(--bad); }


/* ====================================================== main page */

.hero .seal {
  display: inline-flex; align-items: center; gap: .4rem;
  font-size: .74rem; letter-spacing: .08em; text-transform: uppercase;
  color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent);
  padding: .28rem .7rem; border-radius: 999px; margin-bottom: 1rem;
}
.hero h1 em { color: var(--accent); font-style: normal; }

.hero-actions { display: flex; flex-wrap: wrap; gap: .7rem; margin: 1.5rem 0 0; }

.button-ghost {
  display: inline-flex; align-items: center; gap: .5rem;
  padding: .7rem 1.2rem; border-radius: 8px; text-decoration: none;
  color: var(--ink); border: 1px solid var(--line); background: var(--panel-2);
  font-weight: 500; transition: border-color .15s ease;
}
.button-ghost:hover { border-color: var(--accent); text-decoration: none; }

/* Real numbers from the database. Tabular so they do not dance when they change. */
.numbers {
  display: flex; flex-wrap: wrap; gap: 2.5rem; margin: 2rem 0 0;
  padding-top: 1.5rem; border-top: 1px solid var(--line);
}
.numbers dt {
  font-size: .72rem; letter-spacing: .07em; text-transform: uppercase;
  color: var(--dim);
}
.numbers dd {
  margin: .2rem 0 0; font-size: 1.6rem; font-weight: 600;
  font-variant-numeric: tabular-nums; color: var(--ink);
}

/* Feature card: the icon is what the eye catches first, so it gets a real size
   instead of being stuck next to the title. */
.feature { display: flex; flex-direction: column; gap: .5rem; }
.feature > i {
  font-size: 1.35rem; color: var(--accent); width: 2.4rem; height: 2.4rem;
  display: grid; place-items: center; border-radius: 9px;
  background: color-mix(in srgb, var(--accent) 11%, transparent);
}
.feature h3 { margin: .3rem 0 0; font-size: 1rem; }
.feature p { margin: 0; color: var(--dim); font-size: .9rem; line-height: 1.55; }

.steps li strong { color: var(--ink); }
.steps li i { color: var(--accent); }

@media (max-width: 40rem) {
  .numbers { gap: 1.5rem; }
  .numbers dd { font-size: 1.3rem; }
  .hero-actions { flex-direction: column; }
  .hero-actions a { justify-content: center; }
}


/* The reckoning of the hop: what goes out, what comes in, and what is left. The
   profit we always show is net, but without seeing the investment beside it the
   number looks too big — and the player does not know how much capital they need. */
.step-tally {
  margin: .35rem 0 .6rem; font-size: .82rem; color: var(--dim);
  display: flex; flex-wrap: wrap; gap: .5rem; align-items: center;
}
.step-tally b { color: var(--ok); }
.step-tally i { color: var(--dim); }


/* ============================================================== circuit */
/* Two stations repeated five times are not a ten-stop route. Naming it changes
   what the player does: they do not follow it to the end, they go around in laps
   until they tire — and they need to know how much each lap earns. */
.circuit {
  margin: 1rem 0; padding: 1.1rem 1.25rem; border-radius: 12px;
  border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent);
  background: color-mix(in srgb, var(--accent) 8%, var(--panel));
}
.circuit-title {
  margin: 0 0 .9rem; font-size: 1.05rem; font-weight: 600; color: var(--ink);
}
.circuit-title i { color: var(--accent); margin-right: .45rem; }
.circuit-num { display: flex; flex-wrap: wrap; gap: 2rem; margin: 0 0 .8rem; }
.circuit-num dt {
  font-size: .7rem; letter-spacing: .07em; text-transform: uppercase;
  color: var(--dim);
}
.circuit-num dd {
  margin: .15rem 0 0; font-size: 1.25rem; font-weight: 600;
  font-variant-numeric: tabular-nums; color: var(--accent);
}
.circuit .hint { margin: 0; }

.per-hour { color: var(--dim); font-variant-numeric: tabular-nums; }

/* The gain numbers are smaller than the hero's: here they inform, there they
   convince. Same family, different weight. */
.numbers.gain { border-top: 0; padding-top: 0; margin-top: 0; gap: 2rem; }
.numbers.gain dd { font-size: 1.35rem; color: var(--ok); }

/* "keep me signed in" checkbox on the sign-in form */
.check { display: flex; align-items: center; gap: .5rem; margin: -.25rem 0 .25rem; font-size: .85rem; color: var(--muted, #9aa0a6); cursor: pointer; }
.check input[type="checkbox"] { width: auto; margin: 0; accent-color: #ff8c0d; }

/* ========================= My hangar ========================= */
/* The stat row on the loadout panel reuses .hud-data; here it may wrap onto a
   second line when the ship carries a lot of numbers. */
.hud-data.wrap { flex-wrap: wrap; row-gap: .75rem; }
/* Sub-heading inside the loadout panel (Core / Optional / Hardpoints). h3 is not
   otherwise styled, so it carries its own accent-icon rule. */
.hangar-sub { font-size: 1rem; margin: 1.25rem 0 .35rem; color: var(--dim); font-weight: 600; }
.hangar-sub i { color: var(--accent); margin-right: .3rem; }

/* -------------------------------------------------- hangar: friendlier layout */
/* Everything below is redrawn live by assets/hangar.js on the same markup — so it
   must read from CSS classes only (the CSP forbids inline style). */

/* Empty state: a calm, centred invitation instead of a bare paragraph. */
.hangar-empty { text-align: center; }
.hangar-empty-icon {
  width: 3.25rem; height: 3.25rem; margin: .25rem auto .75rem;
  display: grid; place-items: center; border-radius: 50%;
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  color: var(--accent); font-size: 1.3rem;
}
.hangar-empty p { max-width: 38rem; margin: 0 auto .6rem; }

/* Verdict banner: the one-glance read at the very top of the content. */
.verdict {
  display: flex; align-items: flex-start; gap: 1rem;
  padding: 1.25rem 1.4rem; margin: 1.25rem 0 1rem;
  border-radius: 14px; border: 1px solid var(--line);
  background: linear-gradient(100deg, var(--panel) 0%, #11161d 100%);
}
.verdict-work    { border-left: 3px solid var(--accent); }
.verdict-good    { border-left: 3px solid var(--ok); }
.verdict-unknown { border-left: 3px solid var(--dim); }
.verdict-icon {
  width: 3rem; height: 3rem; flex: none;
  display: grid; place-items: center; border-radius: 50%;
  background: var(--panel-2); font-size: 1.35rem;
}
.verdict-work .verdict-icon    { color: var(--accent); }
.verdict-good .verdict-icon    { color: var(--ok); }
.verdict-unknown .verdict-icon { color: var(--dim); }
.verdict-text { min-width: 0; }
.verdict-text h2 { margin: 0 0 .35rem; font-size: 1.2rem; line-height: 1.3; }
.verdict-text h2 i { margin: 0; }
.verdict-text p { margin: 0; color: var(--dim); }
.verdict-tags { margin-top: .6rem !important; display: flex; gap: .4rem; flex-wrap: wrap; }
.verdict-tags .badge.on i { font-size: .5rem; vertical-align: middle; margin-right: .25rem; }

/* Key-stat strip: compact tiles instead of a definition list dump. */
.stat-strip {
  display: flex; flex-wrap: wrap; gap: .75rem; margin: 0 0 1rem;
}
.stat-cell {
  flex: 1 1 8rem; min-width: 8rem;
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 12px; padding: .8rem 1rem;
}
.stat-cell .stat-lbl {
  color: var(--dim); font-size: .72rem; text-transform: uppercase;
  letter-spacing: .06em; margin: 0 0 .25rem; text-align: left;
}
.stat-cell .stat-num {
  font-size: 1.35rem; font-weight: 700; font-variant-numeric: tabular-nums;
  text-align: left; padding: 0;
}
.stat-cell .stat-unit { font-size: .9rem; font-weight: 400; color: var(--dim); }
.stat-cell .stat-arrow { color: var(--dim); margin: 0 .15rem; }
.stat-cell .stat-goal { color: var(--accent); }
.stat-cell .stat-place { font-size: 1.05rem; font-weight: 600; }

/* Cargo progress bar — native <progress> so no inline style is ever needed. */
.cargo-bar-wrap { margin: 0 0 1.25rem; }
.cargo-bar-head {
  display: flex; justify-content: space-between; font-size: .82rem;
  color: var(--dim); margin-bottom: .3rem;
}
.cargo-bar-head span:last-child { color: var(--ink); font-variant-numeric: tabular-nums; }
progress.cargo-bar {
  -webkit-appearance: none; appearance: none;
  width: 100%; height: .7rem; border: 0; border-radius: 999px;
  background: var(--panel-2); overflow: hidden;
}
progress.cargo-bar::-webkit-progress-bar { background: var(--panel-2); border-radius: 999px; }
progress.cargo-bar::-webkit-progress-value {
  background: linear-gradient(90deg, color-mix(in srgb, var(--accent) 70%, #fff) 0%, var(--accent) 100%);
  border-radius: 999px;
}
progress.cargo-bar::-moz-progress-bar {
  background: var(--accent); border-radius: 999px;
}
.cargo-bar-wrap .hint { margin: .4rem 0 0; }

/* Section heading inside the live content (h2 already styled globally; this just
   keeps the top margin tidy right after the stat strip / cards). */
.section-head { margin-top: 1.75rem; }

/* Improvement CARDS — one upgrade each, not a raw table. */
.up-cards {
  display: grid; gap: .85rem; margin: 0 0 1rem;
  grid-template-columns: repeat(auto-fill, minmax(19rem, 1fr));
}
.up-card {
  display: flex; gap: .9rem; align-items: flex-start;
  background: linear-gradient(180deg, var(--panel) 0%, #11161d 100%);
  border: 1px solid var(--line); border-radius: 14px; padding: 1rem 1.1rem;
  transition: border-color .15s ease;
}
.up-card:hover { border-color: color-mix(in srgb, var(--accent) 45%, var(--line)); }
.up-icon {
  width: 2.5rem; height: 2.5rem; flex: none;
  display: grid; place-items: center; border-radius: 10px;
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  color: var(--accent); font-size: 1.05rem;
}
.up-body { min-width: 0; flex: 1; }
.up-title { margin: 0 0 .3rem; font-size: 1rem; }
.up-why { margin: 0 0 .6rem; color: var(--dim); font-size: .88rem; line-height: 1.5; }
.up-swap {
  margin: 0 0 .6rem; display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
  font-size: .9rem;
}
.up-now {
  color: var(--dim); text-decoration: line-through;
  text-decoration-color: color-mix(in srgb, var(--dim) 60%, transparent);
}
.up-swap i { color: var(--accent); }
.up-rec {
  color: var(--ink); font-weight: 600;
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
  padding: .1rem .5rem; border-radius: 7px;
}
.up-chip { margin: 0; }

/* Full loadout — reference, folded away so it does not shout. */
.loadout-details {
  margin: 1.5rem 0 1rem; border: 1px solid var(--line); border-radius: 12px;
  background: var(--panel); overflow: hidden;
}
.loadout-details > summary {
  cursor: pointer; padding: .85rem 1.1rem; user-select: none;
  color: var(--ink); font-weight: 600; list-style: none;
}
.loadout-details > summary::-webkit-details-marker { display: none; }
.loadout-details > summary i { color: var(--accent); margin-right: .4rem; }
.loadout-details > summary .hint { font-weight: 400; margin-left: .3rem; }
.loadout-details > summary:hover { color: var(--accent); }
.loadout-details[open] > summary { border-bottom: 1px solid var(--line); }
.loadout-body { padding: .25rem 1.1rem 1rem; }
.loadout-body table { opacity: .92; }

/* Where to buy — the nearest-station locator, filled in by assets/hangar.js
   (via /api/outfit.php). Empty containers collapse so a card with no result
   looks exactly as it did before. */
.up-locate { margin: .1rem 0 .6rem; font-size: .85rem; }
.up-locate:empty { display: none; }
.loc-loading { color: var(--dim); }
.loc-loading i { margin-right: .35rem; color: var(--accent); }
.loc-head { color: var(--ok); font-weight: 600; margin-bottom: .15rem; }
.loc-line { line-height: 1.5; }
.loc-line > i { color: var(--ok); margin-right: .35rem; }
.loc-station { color: var(--ink); font-weight: 600; }
.loc-meta { color: var(--dim); }

.shop-list { display: grid; gap: .6rem; }
.shop-item {
  border: 1px solid var(--line); border-radius: 10px;
  padding: .55rem .7rem; background: var(--panel);
}
.shop-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: .5rem; flex-wrap: wrap;
}
.shop-name { color: var(--ink); font-weight: 600; font-size: .9rem; }
.shop-item .up-locate { margin: .45rem 0 0; }

/* ------------------------------------- the Free route card, awake and asleep
   The card configures a mode that only runs while the app runs, and it fills
   three of its fields from the ship. With no reading there is nothing honest to
   put in them, so the form goes grey and inert — and the notice above it stays
   at full contrast, because it is the one thing left to read. Toggled by
   assets/free-prefs.js; the POST is refused server-side either way. */
.free-card.card-asleep #fp-form {
  opacity: .45;
  filter: grayscale(.7);
  pointer-events: none;   /* nothing to click, and no focus ring to mislead */
  user-select: none;
}
/* Locked, but not asleep: the ship's own numbers. They read as data rather than
   as an empty box someone forgot to fill, and the cursor says "not yours". */
.free-card input[data-ship] { cursor: default; }
.free-card input[data-ship][type=text] {
  background: var(--panel); color: var(--dim);
  font-variant-numeric: tabular-nums;
}
.free-card input[data-ship][type=checkbox] { cursor: default; opacity: .8; }
.free-card .hint .fa-lock { margin-right: .3rem; color: var(--dim); }

/* ---------------------------------------------------- the name and the voice */
/* Added with the Pyxis identity: the landing page explains the name and lets a
   visitor HEAR the app before downloading anything. */

.etymology {
  margin: .9rem 0 0;
  padding-left: .9rem;
  border-left: 2px solid var(--accent);
  font-size: .9rem;
  color: var(--dim);
}
.etymology i { color: var(--accent); margin-right: .4rem; }
.etymology em { color: var(--ink); font-style: normal; font-weight: 600; }

.voice > p { margin: 0 0 .8rem; }
.voice > .hint { margin: 0; }

.voice-samples {
  list-style: none;
  margin: 1.2rem 0 0;
  padding: 0;
  display: grid;
  gap: .5rem;
}
.voice-samples li {
  display: flex;
  align-items: center;
  gap: .8rem;
  padding: .55rem .8rem;
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: 10px;
  transition: border-color .15s ease;
}
.voice-samples li:hover { border-color: var(--accent); }

/* The play button: round, accent-outlined, fills in while the line plays. */
.voice-play {
  flex: none;
  width: 2.1rem;
  height: 2.1rem;
  display: grid;
  place-items: center;
  padding: 0;
  border-radius: 50%;
  border: 1px solid var(--accent);
  background: transparent;
  color: var(--accent);
  cursor: pointer;
  font-size: .75rem;
  transition: background-color .15s ease, color .15s ease;
}
.voice-play:hover,
.voice-play:focus-visible { background: var(--accent); color: var(--accent-ink); }
.voice-play.is-playing {
  background: var(--accent);
  color: var(--accent-ink);
  animation: voice-pulse 1.1s ease-in-out infinite;
}
@keyframes voice-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(255, 138, 31, .45); }
  50%      { box-shadow: 0 0 0 .4rem rgba(255, 138, 31, 0); }
}
/* Someone who asked the OS for less motion gets the colour change and no pulse. */
@media (prefers-reduced-motion: reduce) {
  .voice-play.is-playing { animation: none; }
}

/* What KIND of line it is, so the three read as different situations and not as
   three identical buttons. */
.voice-kind { flex: none; width: 1rem; text-align: center; color: var(--dim); }
.voice-samples li:hover .voice-kind { color: var(--accent); }

.voice-samples li > span {
  font-style: italic;
  color: var(--ink);
  font-size: .95rem;
}

/* Wrapped in <noscript> in the markup, so there is no class to toggle and no
   flash of a fallback that everyone with JS would see for an instant. */
.voice-nojs { margin: .9rem 0 0; }

@media (max-width: 30rem) {
  .voice-samples li > span { font-size: .88rem; }
  .voice-kind { display: none; }
}
