/* EveSynapse — EVE Dominion (2009) re-skin, modern implementation.
   Molten-orange eclipse palette: ember red and flare gold accents on
   neutral near-black grey containers. Single dependency-free stylesheet. */

@font-face {
  font-family: 'Shentox';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/static/fonts/shentox-regular.woff2') format('woff2');
}
@font-face {
  font-family: 'Univers Next Pro';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/static/fonts/univers-next-pro-medium.woff2') format('woff2');
}
@font-face {
  font-family: 'Univers Next Pro';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/static/fonts/univers-next-pro-bold.woff2') format('woff2');
}
@font-face {
  font-family: 'Univers Next Pro';
  font-style: italic;
  font-weight: 300;
  font-display: swap;
  src: url('/static/fonts/univers-next-pro-light-italic.woff2') format('woff2');
}
@font-face {
  font-family: 'Univers Next Pro';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url('/static/fonts/univers-next-pro-light.woff2') format('woff2');
}
@font-face {
  font-family: 'Univers Next Pro';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/static/fonts/univers-next-pro-regular.woff2') format('woff2');
}
@font-face {
  font-family: 'Univers Next Pro Condensed';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/static/fonts/univers-next-pro-medium-condensed.woff2') format('woff2');
}
@font-face {
  font-family: 'Univers Next Pro Condensed';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/static/fonts/univers-next-pro-bold-condensed.woff2') format('woff2');
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url('/static/fonts/inter-300.woff2') format('woff2');
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/static/fonts/inter-400.woff2') format('woff2');
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/static/fonts/inter-500.woff2') format('woff2');
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/static/fonts/inter-700.woff2') format('woff2');
}

:root {
  color-scheme: dark;
  /* v0.3.30: --text lightened a notch (#f5ead9 -> #faf3e6) for LCD
     readability; the ember palette is untouched. The extra text-tone
     variables below exist so the light theme can re-tone them. */
  --text: #faf3e6;
  --text-bright: #fff6e6;
  --accent: #ff6a1a;
  --success: #ffb84d;
  --danger: #c62f10;
  --gold: #ffd27a;
  --muted: #b39a7d;
  --muted-2: #b8a58c;
  --note: #c9a06a;
  --panel: #151515;
  --panel-head: #0e0e0e;
  --row: #101010;
  --row-alt: #141414;
  --row-hover: #1b1b1b;
  --input-bg: #0e0e0e;
}

* { box-sizing: border-box; }

html, body { min-height: 100%; }

body {
  margin: 0;
  /* The 2013 wallpaper at full strength behind the near-black
     containers, painted by the fixed layer below so the browser
     composites one dedicated background surface. */
  background: #0d0503;
  color: var(--text);
  font-family: "Shentox", "Univers Next Pro", "UniversNextPro330BasicLightLatin", "Inter", "Segoe UI", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-weight: 400;
  font-size: 13px;
  line-height: 1.4;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
}
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: url("/static/bg.jpg") no-repeat top center;
  background-size: cover;
  transform: translateZ(0);
}

a { color: var(--accent); text-decoration: none; }
a:hover { color: var(--success); text-decoration: underline; }

/* Headers, wordmark, nav category labels, buttons, badges,
   and table headers ride the Condensed cut of Univers Next
   Pro in Medium (500): it stays legible packed tight in
   dense tables and nav rows. The wordmark alone keeps Bold
   Condensed (600) — at letterspaced caps the Medium reads
   too light for the brand mark. Synthetic emboldening is
   disabled so nothing renders faux-bold. The nav menu links
   themselves ride the non-condensed cut at Regular weight
   (next rule), opening up against the condensed
   category labels. Body text keeps the Shentox stack. */
h1, h2, h3, h4, .wordmark, .btn, thead th, .badge,
.branch > summary {
  font-family: "Univers Next Pro Condensed", "Univers Next Pro", -apple-system, "SF Pro Display", "Segoe UI", "Inter", sans-serif;
  font-weight: 500;
  font-synthesis-weight: none;
}
/* Nav menu links: the entries under the category headers
   plus the standalone top-level rows (Home, Sync, Admin).
   Non-condensed Univers at Regular weight; sizes, colors,
   and hover/active treatments stay as they were. Regular
   (400) replaced Light 300 here once the true Regular face
   was embedded — before that, a 400 request resolved to
   the 500 Medium face, which reads bold. */
header a.navlink, .sidenav a.navlink, .branch .menu a {
  font-family: "Univers Next Pro", -apple-system, "SF Pro Display", "Segoe UI", "Inter", sans-serif;
  font-weight: 400;
  font-synthesis-weight: none;
}
.wordmark { font-weight: 600; }

h1, h2, h3, h4 {
  color: var(--text);
  letter-spacing: -0.01em;
  text-shadow: 0 -1px 0 #000;
}
h1 { font-size: 1.28rem; }
h2, h3 {
  background: linear-gradient(90deg, #ffd27a 0%, #ff6a1a 50%, #d63c14 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  text-shadow: none;
  /* Inline-block so the gradient maps across the heading's own
     text width, not the full container: a short word like
     "Wallet" now gets the whole gold→orange→ember sweep instead
     of only the leftmost gold slice. Headings here are always
     standalone blocks, so nothing flows up beside them. */
  display: inline-block;
}
h2 { font-size: 1.04rem; }
h3 { font-size: 0.88rem; margin: 1.4rem 0 0.4rem; }

small { color: var(--muted); }

/* --- top bar --- */
header {
  position: sticky;
  top: 0;
  z-index: 10;
  /* One of the app's two glass surfaces (user override:
     this bar and, since v0.3.07.009, the sidebar): the bar
     paint at 90% over a backdrop blur, so what scrolls
     beneath reads frosted. Bar content stays opaque; the
     90% paint alone is the no-blur fallback. */
  background: linear-gradient(to bottom, rgba(24, 24, 24, 0.9), rgba(11, 11, 11, 0.9));
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid #262626;
  box-shadow: 0 1px 8px rgba(0, 0, 0, 0.8);
}
header nav {
  max-width: 1560px;
  margin: 0 auto;
  padding-left: 1rem;
  padding-right: 1rem;
  display: flex;
  align-items: center;
}
header .topbar {
  padding-top: 0.5rem;
  padding-bottom: 0.05rem;
  gap: 1rem;
}
.wordmark {
  display: inline-block;
  font-size: 0.86rem;
  font-weight: 600;
  letter-spacing: 0.28em;
  background: linear-gradient(90deg, #ffd27a 0%, #ff6a1a 50%, #d63c14 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.wordmark:hover { color: var(--text-bright); text-decoration: none; }
header .who {
  margin-left: auto;
  color: var(--muted-2);
  text-shadow: 0 1px 0 #000;
  text-align: right;
}

/* --- primary nav: a short row of category branches. Each branch
   is a <details> so it opens by tap with no JavaScript; the branch
   holding the current page is marked via the .active class (the
   render pipeline derives it from the page being served). --- */
header .mainnav {
  padding-top: 0.1rem;
  padding-bottom: 0.45rem;
  gap: 0.3rem;
  flex-wrap: wrap;
}
header .mainnav .spacer { flex: 1; }
header a.navlink,
.branch > summary {
  color: var(--muted-2);
  text-shadow: 0 1px 0 #000;
  padding: 0.3rem 0.6rem;
  white-space: nowrap;
}
header a.navlink:hover,
.branch > summary:hover { color: var(--text-bright); text-decoration: none; }
header a.navlink.active,
.branch.active > summary {
  color: var(--text-bright);
  box-shadow: inset 0 -2px 0 var(--accent);
}
header a.navlink.utility { font-size: 0.9em; color: var(--muted); }
.branch { position: relative; }
.branch > summary {
  cursor: pointer;
  list-style: none;
  border-radius: 3px;
}
.branch > summary::-webkit-details-marker { display: none; }
.branch > summary:focus-visible {
  outline: none;
  box-shadow: 0 0 8px rgba(255, 106, 26, 0.55);
}
.branch > summary::after {
  content: "▾";
  display: inline-block;
  margin-left: 0.35em;
  font-size: 0.8em;
  transition: transform 0.15s ease;
}
.branch[open] > summary { color: var(--text-bright); }
.branch[open] > summary::after { transform: rotate(180deg); }
.branch .menu {
  position: absolute;
  top: calc(100% + 0.35rem);
  left: 0;
  z-index: 40;
  min-width: 11rem;
  display: flex;
  flex-direction: column;
  padding: 0.35rem;
  background: #0e0e0e;
  border: 1px solid #2a2a2a;
  border-radius: 4px;
  box-shadow: 0 10px 24px rgba(0, 0, 0, 0.65);
}
.branch .menu a {
  color: #d8c3a5;
  padding: 0.35rem 0.6rem;
  border-radius: 3px;
  white-space: nowrap;
}
.branch .menu a:hover { color: var(--text-bright); background: #1b1b1b; text-decoration: none; }
.branch .menu a.active { color: var(--gold); background: rgba(255, 106, 26, 0.18); }

/* --- layout + panels --- */
/* Fluid width: the container runs nearly the full viewport on
   wide screens (1560px cap) instead of the old fixed 1100px
   column, and simply fills narrow ones. */
html, body { overflow-x: clip; }
main {
  max-width: 1560px;
  margin: 1.5rem auto 2rem;
  padding: 0 1rem;
}
.panel {
  background: linear-gradient(#151515, #111111) padding-box,
    linear-gradient(135deg, #7a3a12 0%, #4a2408 45%, #2a1404 100%) border-box;
  border: 1px solid transparent;
  border-radius: 4px;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05), 0 2px 14px rgba(0, 0, 0, 0.55);
  padding: 1.25rem 1.25rem 1.5rem;
}
.panel > h1:first-child {
  /* The bar spans the full panel width by design; the gradient
     rides the title text (an inline span), so the ramp is scoped
     to the text itself and reads the same on "Sync" as on a long
     station name. Without the span (it is emitted by every page
     template) the title simply renders in the plain text color. */
  text-shadow: none;
  background: var(--panel-head);
  margin: -1.25rem -1.25rem 1rem;
  padding: 0.6rem 1.25rem;
  border-bottom: 1px solid;
  border-image: linear-gradient(90deg, #7a3a12, #4a2408 50%, #2a1404) 1;
  border-radius: 4px 4px 0 0;
  letter-spacing: 0.06em;
  font-size: 1.1rem;
}
/* One gradient everywhere: gold at 0%, mid orange at 50%, ember
   at 100%, always relative to the text's own width — on the
   wordmark, on h2/h3 (inline-block), and here on the title span. */
.panel > h1:first-child > .gt {
  background: linear-gradient(90deg, #ffd27a 0%, #ff6a1a 50%, #d63c14 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* --- responsive widget grid + cards (Home, Sync, Intel) --- */
/* Sibling widgets flow into as many ~350px columns as the width
   allows and stack to one column on narrow screens, so wide
   monitors spend width on content instead of empty margins. */
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(350px, 100%), 1fr));
  gap: 1rem;
  align-items: start;
  margin: 1rem 0 0.5rem;
}
.grid .spanall { grid-column: 1 / -1; }
.card {
  position: relative;
  background: #101010;
  border: 1px solid #262626;
  border-radius: 4px;
  padding: 0.85rem 1rem 1rem;
}
/* v0.3.07.012: shared darker header bands, minus the layered
   background trick. v0.3.07.010 layered the ember ramp over
   the band on the heading itself and relied on a two-value
   per-layer background clip to keep the ramp inside the
   glyphs; where that clip does not hold, the
   ramp paints the whole bar and the transparent heading text
   vanishes into it. Now the band is a solid ::before behind
   the heading, and the ramp reaches the glyphs only through
   the plain single-layer gradient-text rule on h2/h3 above —
   the same configuration the rest of the app already uses.
   Table headers keep their own rule. */
.panel > h2, .panel > h3,
.card > h2:first-child, .card > h3:first-child,
.foldable > h2:first-child, .foldable > h3:first-child {
  display: block;
  position: relative;
  z-index: 0;
  border-bottom: 1px solid #262626;
}
.panel > h2, .panel > h3,
.card > h2:first-child, .card > h3:first-child,
.foldable > h2:first-child, .foldable > h3:first-child {
  background: none;
  -webkit-background-clip: border-box;
  background-clip: border-box;
  color: var(--success);
  -webkit-text-fill-color: currentColor;
}
.panel > h2::before, .panel > h3::before,
.card > h2:first-child::before, .card > h3:first-child::before,
.foldable > h2:first-child::before, .foldable > h3:first-child::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--panel-head);
  border-radius: inherit;
}
.panel > h2, .panel > h3 { margin: 1.1rem 0 0.65rem; padding: 0.45rem 0.65rem; border-radius: 3px; }
.card > h2:first-child, .card > h3:first-child { margin: -0.85rem -1rem 0.75rem; padding: 0.55rem 1rem; border-radius: 4px 4px 0 0; }
.foldable > h2:first-child, .foldable > h3:first-child { margin: 0 0 0.75rem; padding: 0.45rem 0.65rem; border-radius: 3px; }
/* v0.3.07.014: module titles paint solid. The .012 band
   leaned on the h2/h3 gradient-text clip above, and on at
   least one phone Chrome build the clip does not paint
   inside these positioned headings — the band renders, the
   title does not. So the module/card/foldable titles take
   the palette's solid flare gold (the @supports fallback
   color) with no clipped background at all; page titles
   keep the gradient text. */
.panel > h2, .panel > h3,
.card > h2:first-child, .card > h3:first-child,
.foldable > h2:first-child, .foldable > h3:first-child {
  background: none;
  -webkit-background-clip: border-box;
  background-clip: border-box;
  color: var(--success);
  -webkit-text-fill-color: currentColor;
}
.card table { margin-bottom: 0.5rem; }
.card.has-fold > h2:first-child, .card.has-fold > h3:first-child { padding-right: 2.2rem; }

/* --- collapsible panels (JS-enhanced; open and inert without) --- */
.panel { position: relative; }
.foldbtn {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  right: 0.7rem;
  z-index: 2;
  width: 1.7rem;
  height: 1.7rem;
  padding: 0;
  font-size: 1rem;
  line-height: 1;
  font-family: inherit;
  color: var(--gold);
  background: #0e0e0e;
  -webkit-background-clip: border-box;
  background-clip: border-box;
  border: 1px solid #4a2408;
  border-radius: 3px;
  cursor: pointer;
}
.foldbtn:hover { color: var(--text-bright); border-color: var(--accent); }
.panel.has-fold > h1:first-child { padding-right: 3rem; }
.panel.folded > *:not(h1),
.card.folded > *:not(:first-child),
.foldable.folded > *:not(:first-child) { display: none; }

/* .foldable sections: the h2/h3 blocks inside a multi-section page
   panel (Character, Skills, Industry…). Each carries its own fold
   button in its heading and folds independently; sections listed
   data-fold="closed" in markup start folded once JS loads (skill
   categories), and stay plain visible content without JS. */
.foldable { position: relative; }
.foldable.has-fold > h2:first-child, .foldable.has-fold > h3:first-child { padding-right: 2.2rem; }

/* --- buttons --- */
.btn {
  display: inline-block;
  padding: 0.42rem 0.85rem;
  color: #2a1302;
  background: linear-gradient(to bottom, #ffb84d, #ff6a1a 55%, #e04e12) padding-box,
    linear-gradient(135deg, #ffd27a, #ff6a1a 50%, #a12808) border-box;
  border: 1px solid transparent;
  border-radius: 3px;
  text-shadow: 0 1px 0 rgba(255, 214, 150, 0.35);
  cursor: pointer;
}
.btn:hover {
  background: linear-gradient(to bottom, #ff6a1a, #d63c14 60%, #a12808) padding-box,
    linear-gradient(135deg, #ffd27a, #ff6a1a 50%, #a12808) border-box;
  color: var(--text-bright);
  text-decoration: none;
}
.btn:focus-visible, a:focus-visible {
  outline: none;
  box-shadow: 0 0 8px rgba(255, 106, 26, 0.55);
}

/* --- tables --- */
.tw { overflow-x: auto; -webkit-overflow-scrolling: touch; }
table {
  border-collapse: collapse;
  width: 100%;
  margin: 0.5rem 0 1.25rem;
  border: 1px solid #060606;
}
th, td {
  padding: 0.4rem 0.6rem;
  text-align: left;
  border-top: 1px solid #222222;
  border-bottom: 1px solid #060606;
  vertical-align: middle;
}
thead th {
  background: var(--panel-head);
  color: var(--accent);
  text-shadow: 1px -1px 0 #000;
  border-bottom: 1px solid #000;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-size: 0.7rem;
}
td, .isk { font-variant-numeric: tabular-nums; }
tbody tr { background: var(--row); }
tbody tr:nth-child(even) { background: var(--row-alt); }
tbody tr:hover td { background: var(--row-hover); }

/* Portable tables: inside their .tw scroll container, the first
   column stays pinned while the rest slides beneath it — the row
   identity is never lost on a narrow screen. Backgrounds are
   restated per-cell (a pinned cell can't rely on the row's). */
.tw th:first-child, .tw td:first-child {
  position: sticky;
  left: 0;
  z-index: 1;
  border-right: 1px solid #222222;
}
.tw thead th:first-child { background: var(--panel-head); z-index: 2; }
.tw tbody td:first-child, .tw tbody th:first-child { background: var(--row); }
.tw tbody tr:nth-child(even) td:first-child,
.tw tbody tr:nth-child(even) th:first-child { background: var(--row-alt); }
.tw tbody tr:hover td:first-child, .tw tbody tr:hover th:first-child { background: var(--row-hover); }

/* --- alerts --- */
.err {
  background: rgba(120, 26, 6, 0.38);
  border: 1px solid var(--danger);
  border-radius: 4px;
  color: #f7e0cf;
  padding: 0.6rem 0.85rem;
  box-shadow: rgba(0, 0, 0, 0.425) 0 1px 0, rgba(255, 255, 255, 0.08) 0 1px 0 inset;
}
.ok {
  background: rgba(255, 184, 77, 0.14);
  border: 1px solid var(--success);
  border-radius: 4px;
  color: #f7ecd8;
  padding: 0.6rem 0.85rem;
}

img.portrait {
  border: 1px solid #2c2c2c;
  border-radius: 4px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.6);
}

.isk {
  font-family: "Univers Next Pro", "Inter", sans-serif;
  font-weight: 300;
  /* Just under the 1.1rem panel title: the balance reads as a
     display numeral without out-shouting the page header. */
  font-size: 1.05rem;
  letter-spacing: 0.01em;
  color: var(--text-bright);
}

.corp-desc { white-space: pre-line; }

/* --- form inputs + market search suggestions --- */
input[type="text"], input[type="search"] {
  background: var(--input-bg);
  border: 1px solid #2a2a2a;
  border-radius: 3px;
  color: var(--text);
  padding: 0.42rem 0.6rem;
  font: inherit;
}
html[data-theme="light"] input[type="text"], html[data-theme="light"] input[type="search"] {
  border-color: #d8cdb8;
}
input[type="text"]:focus, input[type="search"]:focus {
  border-color: var(--accent);
  outline: none;
  box-shadow: 0 0 8px rgba(255, 106, 26, 0.35);
}
.searchwrap {
  position: relative;
  display: inline-block;
  width: min(26rem, calc(100vw - 10rem));
}
.searchwrap input { width: 100%; }
.suggest {
  position: absolute;
  left: 0;
  right: 0;
  top: calc(100% + 4px);
  z-index: 50;
  margin: 0;
  padding: 0.3rem;
  list-style: none;
  background: #0e0e0e;
  border: 1px solid #2a2a2a;
  border-radius: 4px;
  box-shadow: 0 10px 24px rgba(0, 0, 0, 0.65);
}
.suggest li {
  padding: 0.5rem 0.6rem;
  border-radius: 3px;
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.suggest li.sel { background: rgba(255, 106, 26, 0.18); color: var(--text-bright); }
.suggest li.pending {
  color: var(--note);
  cursor: default;
  background: transparent;
}
.suggest li .sug-label {
  display: block;
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  color: var(--muted-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* --- top banner global search: a quiet box between the wordmark
   and the sign-in line; it yields width first on small screens. --- */
.topsearch { margin: 0; }
.searchwrap.topsearch-wrap { width: min(20rem, 34vw); }
.topsearch input { padding: 0.3rem 0.55rem 0.3rem 2rem; font-size: 0.85rem; }
/* Gradient magnifier parked at the search field's left edge;
   the input's extra left padding keeps text clear of it. */
.search-glyph {
  position: absolute;
  left: 0.55rem;
  top: 50%;
  transform: translateY(-50%);
  width: 1rem;
  height: 1rem;
  pointer-events: none;
  fill: #ffb84d;
  stroke: #ffb84d;
}
@media (max-width: 720px) {
  .searchwrap.topsearch-wrap { width: min(11rem, 40vw); }
}

/* --- character live state: status dot, kill/loss badges, countdown --- */
.dot {
  display: inline-block;
  width: 0.6em;
  height: 0.6em;
  border-radius: 50%;
  margin-right: 0.4em;
  background: #6b5a4a;
}
.dot.on { background: #ffb84d; }
.dot.off { background: #a8230c; }
.badge {
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  padding: 0.1em 0.5em;
  border-radius: 3px;
  border: 1px solid;
}
.badge.kill { color: var(--gold); border-color: var(--success); background: rgba(255, 184, 77, 0.14); }
.badge.loss { color: #ffab8f; border-color: var(--danger); background: rgba(120, 26, 6, 0.38); }
.countdown { font-variant-numeric: tabular-nums; color: var(--accent); }

/* --- intel: wars involving one of the user's corporations --- */
tbody tr.yours td { background: rgba(255, 184, 77, 0.10); }
/* The pinned first cell of a highlighted row needs the tint
   solid, or scrolled columns would show through it. */
.tw tbody tr.yours td:first-child { background: #2a2015; }

/* --- footer --- */
footer {
  /* 85% opacity with blur (user spec, matching the top bar and
     sidebar glass treatment); the 85% paint alone is the no-blur
     fallback. */
  background: rgba(11, 11, 11, 0.85);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  border-top: 1px solid #262626;
  color: var(--muted);
  text-align: center;
  font-size: 0.72rem;
  text-shadow: 1px -1px 0 #000;
  padding: 1.4rem 1rem 1.6rem;
  margin-top: 2rem;
}
footer .version { color: #6b5844; }
footer .version span + span::before { content: "· "; margin: 0 0.4rem; }

/* --- small screens --- */
@media (max-width: 640px) {
  body { font-size: 12.5px; }
  main { margin-top: 1rem; padding: 0 0.6rem; }
  .panel { padding: 1rem 0.9rem 1.2rem; }
  .panel > h1:first-child { margin: -1rem -0.9rem 1rem; padding: 0.55rem 0.9rem; }
  header nav { padding-left: 0.6rem; padding-right: 0.6rem; }
  header .mainnav { gap: 0.15rem; }
  .wordmark { letter-spacing: 0.18em; font-size: 0.79rem; }
  /* On narrow screens an open branch drops as a full-width bar
     beneath the header instead of a floating dropdown: the branch
     stops being the menu's positioning context, so the menu spans
     the header (its nearest positioned ancestor). */
  .branch { position: static; }
  .branch .menu { left: 0; right: 0; top: 100%; min-width: 0; }
  /* Bigger, unmistakable tap targets on small screens, and the
     open branch reads as a pressed tab rather than a color shift. */
  .topbar { flex-wrap: wrap; }
  header a.navlink, .branch > summary { padding: 0.5rem 0.65rem; }
  .branch .menu { padding: 0.4rem; }
  .branch .menu a { padding: 0.65rem 0.8rem; }
  .branch[open] > summary { background: rgba(255, 106, 26, 0.15); }
  .searchwrap { width: calc(100vw - 9.5rem); }
  th, td { padding: 0.35rem 0.45rem; }
}

/* --- header character switcher + /characters/ page (Phase 1A) ---
   The switcher is a nav .branch living in the topbar; its menu
   right-aligns to the bar's edge instead of the left. Portrait
   chips align with the text they label. */
.switcher .menu { left: auto; right: 0; min-width: 15rem; }
.switcher .menu a { display: flex; align-items: center; gap: 0.5rem; }
.portrait { border-radius: 3px; vertical-align: middle; }

/* --- Phase 1B home overview widgets ---
   The widget grid is the standard .grid/.card vocabulary; only
   the fleet table, attention list and customize rows need their
   own rules. */
.home-actions { display: flex; gap: 0.5rem; flex-wrap: wrap; }
.fleet-tools { display: flex; gap: 0.4rem; align-items: center; flex-wrap: wrap; }
.fleet-tools input[type="search"] { background: var(--row); color: var(--text); border: 1px solid #333; padding: 0.4rem 0.6rem; border-radius: 3px; }
.chip { border: 1px solid #444; background: var(--row); color: var(--text); border-radius: 999px; padding: 0.15rem 0.7rem; cursor: pointer; font: inherit; font-size: 0.85rem; }
.chip.on { border-color: var(--accent); color: var(--accent); }
.relink { color: var(--danger); }
.attention { list-style: none; margin: 0; padding: 0; }
.attention li { background: var(--row); padding: 0.35rem 0.5rem; border-bottom: 1px solid #222; }
.attention li:nth-child(even) { background: var(--row-alt); }
.attention li:hover { background: var(--row-hover); }
.attention li:last-child { border-bottom: none; }
.cust-row { border: 1px solid #262626; background: var(--row); padding: 0.6rem 0.8rem; margin: 0.5rem 0; border-radius: 3px; }
.cust-actions { display: flex; gap: 0.4rem; flex-wrap: wrap; margin: 0.3rem 0 0; }
.cust-actions form { margin: 0; }
.cust-actions button, .cust-row > form button { font: inherit; cursor: pointer; }

/* --- widget settings (orders scope): a quiet inline form at the
   top of the card. Selects follow the input palette; the button
   is the no-JS path (app.js submits on change). --- */
.widget-scope { display: flex; gap: 0.4rem; align-items: center; flex-wrap: wrap; margin: 0 0 0.5rem; }
.widget-scope select {
  background: var(--input-bg);
  border: 1px solid #2a2a2a;
  border-radius: 3px;
  color: var(--text);
  padding: 0.3rem 0.4rem;
  font: inherit;
}
html[data-theme="light"] .widget-scope select {
  border-color: #d8cdb8;
}
.widget-scope select:focus { border-color: var(--accent); outline: none; }

/* --- home customize mode: drag handles, × removal, add-module
   pop-up. All three controls are inserted by app.js on the
   customize view only; the raw markup carries the plain
   add/remove + move forms (in the noscript module list), so
   nothing here is load-bearing without JavaScript. --- */
.home-actions form { margin: 0; }
.draghandle {
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  cursor: grab;
  color: var(--gold);
  background: #0e0e0e;
  border: 1px solid #4a2408;
  border-radius: 3px;
  font: inherit;
  font-size: 0.85em;
  line-height: 1;
  padding: 0.18rem 0.4rem;
  margin-right: 0.45rem;
}
.draghandle:active { cursor: grabbing; }
/* The lifted card: fully opaque in its real panel colors, fixed
   to the viewport at its true size, ember glow and a deep
   shadow. Nothing behind it can bleed through. */
.card.dragging {
  position: fixed;
  margin: 0;
  z-index: 50;
  pointer-events: none;
  background: #101010;
  border-color: var(--accent);
  box-shadow: 0 16px 38px rgba(0, 0, 0, 0.72), 0 0 14px rgba(255, 106, 26, 0.55);
  transform: scale(1.01);
}
/* Drop settle: the card glides from the pointer into its solved
   slot — position, and size when the solver gives it a different
   span there — then JS swaps it into the DOM. */
.card.drag-settle { transition: left 170ms ease, top 170ms ease, width 170ms ease, height 170ms ease, transform 170ms ease; }
/* The placeholder holds the dragged card's slot for the whole
   drag, wearing the span class the solver assigns the card at
   the hovered position and the card's own height — so the grid
   underneath is always the solved final layout, never collapsed. */
.drag-placeholder {
  background: rgba(255, 106, 26, 0.08);
  border: 1px dashed #6b3410;
  box-shadow: inset 0 0 18px rgba(0, 0, 0, 0.45);
}
/* The home grid engine: the server solves every module's column
   span (see solveHomeSpans) and the CSS only applies it. Six
   columns on desktop; cards in a row stretch to equal height,
   content top-aligned by block flow. */
.grid.home-grid {
  grid-template-columns: repeat(6, minmax(0, 1fr));
  align-items: stretch;
  grid-auto-flow: dense;
}
.grid.home-grid > .span3 { grid-column: span 3; }
.grid.home-grid > .span6 { grid-column: span 6; }
.grid.home-grid > .card { min-width: 0; }
/* Phones: two columns — wide modules own a row, flex modules
   pair two-up, a lone flex module stretches across both. */
@media (max-width: 719px) {
  .grid.home-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid.home-grid > .span3 { grid-column: span 1; }
  .grid.home-grid > .span6 { grid-column: span 2; }
}
/* Very small screens: a single column, everything full width. */
@media (max-width: 339px) {
  .grid.home-grid { grid-template-columns: minmax(0, 1fr); }
  .grid.home-grid > .span3, .grid.home-grid > .span6 { grid-column: span 1; }
}
/* --- market history chart: interactive day points ---------- */
.pchart { position: relative; }
.pchart svg {
  display: block;
  cursor: crosshair;
  touch-action: pan-y;
}
.chart-legend {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35rem 0.9rem;
  margin: 0.15rem 0 0.35rem;
  color: var(--note);
  font-family: "Univers Next Pro Condensed", "Univers Next Pro", sans-serif;
  font-size: 0.92em;
  letter-spacing: 0.03em;
}
.legend-item { display: inline-flex; align-items: center; gap: 0.35rem; }
.legend-swatch {
  display: inline-block;
  width: 1.4rem;
  height: 0.45rem;
  border-radius: 2px;
}
.legend-price { height: 2px; background: #ffb84d; }
.legend-volume { background: #d63c14; }
.legend-note { margin-left: auto; color: #9d8668; }
.pchart text {
  font-family: "Univers Next Pro Condensed", "Univers Next Pro", sans-serif;
  font-size: 11px;
}
.chart-gridline { stroke: #241708; stroke-width: 1; }
.volume-gridline { stroke: #2a1408; stroke-dasharray: 3 3; }
.chart-axis-label {
  fill: #c9a06a;
  paint-order: stroke;
  stroke: #151515;
  stroke-width: 3px;
  stroke-linejoin: round;
}
.volume-axis { fill: #d98a6a; text-anchor: end; }
.chart-date-tick { fill: #9d8668; }
.pchart .cdot {
  fill: #ffb84d;
  fill-opacity: 0;
  stroke: none;
  cursor: pointer;
}
.pchart .cdot:hover { fill-opacity: 0.18; }
.pchart .cdot:focus {
  outline: none;
  fill-opacity: 0.22;
  stroke: #ffd27a;
  stroke-width: 1.5;
}
.pchart .cdot.is-selected {
  fill-opacity: 0.28;
  stroke: #ffd27a;
  stroke-width: 1.5;
}
.ctip {
  position: absolute;
  z-index: 6;
  pointer-events: none;
  background: var(--panel);
  border: 1px solid #4a2408;
  border-radius: 3px;
  padding: 0.35rem 0.55rem;
  font-size: 0.85em;
  line-height: 1.45;
  white-space: nowrap;
  transform: translate(-50%, -115%);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.55);
}
.ctip .ctip-date { color: var(--gold); font-weight: 600; }
body.drag-active { user-select: none; -webkit-user-select: none; cursor: grabbing; }
@media (prefers-reduced-motion: reduce) {
  .card.drag-settle { transition: none; }
}
.cardremove {
  position: absolute;
  top: 0.5rem;
  right: 2.6rem;
  z-index: 2;
  width: 1.7rem;
  height: 1.7rem;
  padding: 0;
  font-size: 1rem;
  line-height: 1;
  font-family: inherit;
  color: var(--gold);
  background: #0e0e0e;
  border: 1px solid #4a2408;
  border-radius: 3px;
  cursor: pointer;
}
.cardremove:hover { color: var(--text-bright); border-color: var(--danger); }
/* The half/full resize toggle sits left of the × on flex
   modules; the heading leaves room for all three controls. */
.cardspan {
  position: absolute;
  top: 0.5rem;
  right: 4.5rem;
  z-index: 2;
  width: 1.7rem;
  height: 1.7rem;
  padding: 0;
  font-size: 0.95rem;
  line-height: 1;
  font-family: inherit;
  color: var(--gold);
  background: #0e0e0e;
  border: 1px solid #4a2408;
  border-radius: 3px;
  cursor: pointer;
}
.cardspan:hover { color: var(--text-bright); border-color: var(--accent); }
.cardspan[aria-pressed="true"] { color: var(--text-bright); border-color: var(--accent); }
.home-custom.has-controls .card > h2:first-child, .home-custom.has-controls .card > h3:first-child { padding-right: 4.6rem; }
.home-custom.has-controls .card.has-spanbtn > h2:first-child, .home-custom.has-controls .card.has-spanbtn > h3:first-child { padding-right: 6.6rem; }

/* Add-module pop-up: solid Dominion panel over a dimmed page,
   dismissed by its close button, a tap on the backdrop, or
   Escape (wired in app.js). */
.modal-backdrop {
  position: fixed;
  inset: 0;
  z-index: 60;
  background: rgba(0, 0, 0, 0.66);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
}
.modal-backdrop[hidden] { display: none; }
.modal {
  background: var(--panel);
  border: 1px solid #6b3410;
  border-radius: 4px;
  box-shadow: 0 18px 50px rgba(0, 0, 0, 0.8), 0 0 14px rgba(255, 106, 26, 0.25);
  width: min(34rem, 100%);
  max-height: 82vh;
  overflow-y: auto;
  padding: 1rem 1.1rem 1.1rem;
}
.modal-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; }
.modal-head h2 { margin: 0.1rem 0 0.6rem; }
.modal-close {
  flex: none;
  width: 1.7rem;
  height: 1.7rem;
  padding: 0;
  font-size: 1rem;
  line-height: 1;
  font-family: inherit;
  color: var(--gold);
  background: #0e0e0e;
  border: 1px solid #4a2408;
  border-radius: 3px;
  cursor: pointer;
}
.modal-close:hover { color: var(--text-bright); border-color: var(--accent); }
.modal-list { list-style: none; margin: 0; padding: 0; }
.modal-item {
  display: block;
  width: 100%;
  text-align: left;
  font: inherit;
  color: var(--text);
  background: var(--row);
  border: 1px solid #262626;
  border-radius: 3px;
  padding: 0.6rem 0.8rem;
  margin: 0.4rem 0;
  cursor: pointer;
}
.modal-item:hover { background: var(--row-hover); border-color: var(--accent); }
.modal-item strong { display: block; }
.modal-item small { display: block; margin-top: 0.15rem; }
.modal-empty { margin: 0.5rem 0 0; }

/* Live-region loading indicator: an ember ring while a section
   fills itself in. Reduced motion leaves the ring still. */
.loading-pulse {
  display: inline-block;
  width: 13px;
  height: 13px;
  margin-right: 8px;
  vertical-align: -2px;
  border-radius: 50%;
  border: 2px solid #3a2a1a;
  border-top-color: var(--success);
  animation: eve-spin 0.9s linear infinite;
}
@keyframes eve-spin {
  to { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
  .loading-pulse { animation: none; }
}

/* Top-banner page-sync indicator: shows only while this page
   still has data on the way (the count of names, descriptions,
   or history the page asked for). It says nothing about
   background sync — that lives on the Sync page. */
.page-sync {
  display: inline-flex;
  align-items: center;
  margin-left: auto;
  font-size: 0.85em;
  white-space: nowrap;
}
.page-sync[hidden] { display: none; }

/* v0.3.07 navigation shell and phone layout. The wallpaper stays
   on the dedicated body::before layer above; navigation lives in
   a left sidebar on wide screens and in an off-canvas drawer on
   small screens. Content panels remain opaque. */
/* Wide screens: the top bar is a fixed full-width strip across
   the very top (wordmark in its left corner, cluster at the
   right), and the sidebar hangs below it — its top edge offset
   by the bar height in expanded, rail, and hidden states alike,
   so the bar never moves, resizes, or gets covered. */
body {
  display: grid;
  grid-template-columns: 15.5rem minmax(0, 1fr);
  align-items: start;
  padding-top: calc(3.75rem + 1px);
}
header {
  position: fixed;
  top: 0;
  right: 0;
  left: 0;
  z-index: 60;
}
header nav { max-width: none; }
html[data-nav="rail"] body { grid-template-columns: 5rem minmax(0, 1fr); }
html[data-nav="hidden"] body { grid-template-columns: 0 minmax(0, 1fr); }
.nav-drawer-checkbox {
  position: fixed;
  top: 0;
  left: 0;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
.sidebar {
  position: sticky;
  top: calc(3.75rem + 1px);
  z-index: 50;
  height: calc(100vh - 3.75rem - 1px);
  height: calc(100dvh - 3.75rem - 1px);
  min-width: 0;
  /* v0.3.07.010: the sidebar takes the top bar's glass
     treatment (user ask) — same recipe, its own colors kept:
     the #151515 → #111111 paint at 90% over a backdrop blur.
     Rail flyouts and content panels stay solid; the 93% paint
     alone is the no-blur fallback. */
  background: linear-gradient(rgba(21, 21, 21, 0.9), rgba(17, 17, 17, 0.9)) padding-box;
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  border-right: 1px solid #262626;
}
html[data-nav="hidden"] .sidebar {
  visibility: hidden;
  pointer-events: none;
  overflow: hidden;
  border-right-color: transparent;
}
/* v0.3.07.011: wide nav state changes glide instead of
   snapping. The head script applies any saved state before
   first paint; app.js adds .nav-motion-ready only after that
   initial layout has had frames to land, so a refresh or
   navigation into a saved rail/hidden state never sweeps in.
   The drawer below already slides on its own transform. */
@media (min-width: 861px) {
  html.nav-motion-ready body {
    transition: grid-template-columns 180ms ease-out;
  }
  html.nav-motion-ready .sidebar {
    transition: visibility 0s linear 180ms;
  }
  html.nav-motion-ready:not([data-nav="hidden"]) .sidebar {
    transition-delay: 0s;
  }
  html.nav-motion-ready .nav-label {
    transition: max-width 180ms ease-out, opacity 140ms ease-out, transform 180ms ease-out;
  }
  html.nav-motion-ready .sidenav a.navlink,
  html.nav-motion-ready .sidebar .branch > summary {
    transition: gap 180ms ease-out, padding-right 180ms ease-out, padding-left 180ms ease-out;
  }
}
.sidebar-inner {
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow-y: auto;
  padding: 0.65rem 0.55rem 0.8rem;
}
.sidebar-brand {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  min-height: 2.4rem;
  padding: 0 0.35rem 0.55rem;
}
.sidebar-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
  margin-left: auto;
}
.nav-state-btn,
.nav-reopen,
.nav-drawer-close,
.nav-expand-btn {
  display: none;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  min-width: 2rem;
  min-height: 2rem;
  padding: 0.25rem 0.45rem;
  color: var(--gold);
  background: #0e0e0e;
  border: 1px solid #4a2408;
  border-radius: 3px;
  cursor: pointer;
  font: inherit;
}
/* v0.3.07.007: the glyph-only controls (collapse / hide /
   drawer close / expand-all) float bare — gradient sign, no
   resting box. The border stays on the box at full width but
   transparent, so the footprint never shifts; .nav-reopen
   keeps its labeled button box. */
.nav-state-btn,
.nav-drawer-close,
.nav-expand-btn {
  background: transparent;
  border-color: transparent;
}
html.js .nav-state-btn { display: inline-flex; }
html.js .nav-expand-btn { display: inline-flex; }
html.js[data-nav="hidden"] .nav-reopen { display: inline-flex; }
/* Expand-all uses drawn SVG signs inside the same family box
   as its chevron / close siblings — plus while any category is
   closed, minus once all are open (the script keeps
   aria-expanded truthful, including hand-toggled categories). */
.nav-control-svg {
  display: block;
  flex: none;
  width: 1.05rem;
  height: 1.05rem;
  fill: #ffb84d;
  stroke: #ffb84d;
}
.nav-expand-btn .expand-icons { display: inline-flex; }
.nav-expand-btn .expand-icon-minus { display: none; }
.nav-expand-btn[aria-expanded="true"] .expand-icon-plus { display: none; }
.nav-expand-btn[aria-expanded="true"] .expand-icon-minus { display: block; }
#nav-collapse .nav-control-svg { transition: transform 0.15s ease; }
html[data-nav="rail"] #nav-collapse .nav-control-svg { transform: scaleX(-1); }
.nav-reopen:hover { color: var(--text-bright); border-color: var(--accent); }
/* Glyph controls get feedback as a faint wash, not a box. */
.nav-state-btn:hover,
.nav-drawer-close:hover,
.nav-expand-btn:hover {
  color: var(--text-bright);
  background: rgba(255, 106, 26, 0.14);
  border-color: transparent;
}
.sidenav {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}
.sidenav a.navlink,
.sidebar .branch > summary {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  min-height: 2.35rem;
  padding: 0.42rem 0.55rem;
  border-radius: 3px;
  color: var(--text);
  font-size: 1rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  cursor: pointer;
}
.sidenav a.navlink:hover,
.sidebar .branch > summary:hover {
  color: var(--text-bright);
  background: #1b1b1b;
  text-decoration: none;
}
.sidenav a.navlink.active,
.sidebar .branch.active > summary {
  color: var(--text-bright);
  background: #1b1b1b;
  box-shadow: inset 3px 0 0 var(--accent);
}
.sidebar .branch[open] > summary { background: #1b1b1b; }
.nav-icon {
  flex: 0 0 1.35rem;
  width: 1.35rem;
  color: var(--success);
  line-height: 1;
  text-align: center;
}
/* Every category icon is drawn in the same slot and painted
   with the brand ramp from the shared gradient def; the ember
   fill/stroke here is the fallback if gradient paint fails. */
.nav-icon svg {
  display: block;
  width: 1.05em;
  height: 1.05em;
  margin: 0 auto;
  fill: #ffb84d;
  stroke: #ffb84d;
}
.nav-icon svg[hidden] { display: none; }
/* Theme toggle icons swap via data-theme (head script sets this before
   first paint, so no flash of both icons). */
html[data-theme="light"] .theme-icon-sun { display: none; }
html[data-theme="dark"] .theme-icon-moon { display: none; }
/* On the ember active pill the icons get a slightly brighter
   sweep so they never go muddy. */
.sidebar .branch.active > summary .nav-icon svg,
.sidenav a.navlink.active .nav-icon svg {
  filter: brightness(1.15);
}
.nav-label {
  min-width: 0;
  max-width: 12rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.sidebar .branch { position: relative; }
.sidebar .branch > summary::after {
  flex: none;
  margin-left: auto;
}
.sidebar .branch .menu {
  position: static;
  min-width: 0;
  margin: 0.15rem 0 0.35rem 2.55rem;
  padding: 0.15rem 0 0.15rem 0.4rem;
  background: transparent;
  border: 0;
  border-left: 1px solid #2a2a2a;
  border-radius: 0;
  box-shadow: none;
}
.sidebar .branch .menu a {
  display: block;
  padding: 0.32rem 0.45rem;
  border-radius: 3px;
}
.sidebar .branch .menu a.active {
  color: var(--text-bright);
  background-color: #2a1a0c;
  box-shadow: inset 2px 0 0 var(--accent);
}
.sidenav-utility {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  margin-top: 0.7rem;
  padding-top: 0.55rem;
  border-top: 1px solid #262626;
}
.sidebar-account {
  margin-top: auto;
  padding: 0.75rem 0.35rem 0;
  border-top: 1px solid #262626;
}
.sidebar-account .who {
  display: block;
  margin: 0 0 0.45rem;
  text-align: left;
  white-space: normal;
}
.sidebar-account .branch > summary {
  min-height: 2.2rem;
  font-size: 0.95rem;
}
.sidebar-account .branch .menu { margin-left: 0; }
.sidebar-account.has-character .sidebar-character { display: none; }
.sidebar-signout {
  display: inline-flex;
  margin-top: 0.45rem;
  color: var(--success);
}
html[data-nav="rail"] .sidebar-inner { overflow: visible; }
html[data-nav="rail"] .sidebar-account { display: none; }
html[data-nav="rail"] .sidebar-account-footer { display: flex; }
html[data-nav="rail"] .nav-label {
  max-width: 0;
  opacity: 0;
  transform: translateX(-0.25rem);
}
html[data-nav="rail"] .sidebar-brand { justify-content: center; padding-right: 0; padding-left: 0; }
html[data-nav="rail"] .sidebar-actions { margin-left: 0; }
html[data-nav="rail"] .nav-expand-btn { display: none; }
html[data-nav="rail"] #nav-hide { display: none; }
html[data-nav="rail"] .sidenav a.navlink,
html[data-nav="rail"] .sidebar-account-footer .navlink,
html[data-nav="rail"] .sidebar .branch > summary {
  justify-content: center;
  gap: 0;
  padding-right: 0.25rem;
  padding-left: 0.25rem;
}
html[data-nav="rail"] .sidebar .branch > summary::after { display: none; }
html[data-nav="rail"] .sidebar .branch .menu {
  position: absolute;
  top: 0;
  left: calc(100% + 0.55rem);
  min-width: 12rem;
  margin: 0;
  padding: 0.3rem;
  background: #111111;
  border: 1px solid #333333;
  border-radius: 3px;
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.55);
}
html[data-nav="rail"] .sidebar .branch .menu a { white-space: nowrap; }
/* Rail flyout discipline: a closed category never paints a
   panel, and the active-section pill (dark fill, ember left
   bar) belongs to the current page's category alone. A merely
   open flyout gets a faint ember wash instead, so a rail full
   of categories left open in the wide sidebar stops looking
   like every section is current at once. Wide screens only —
   the drawer below keeps its expanded-style presentation. */
@media (min-width: 861px) {
  html[data-nav="rail"] .sidebar .branch:not([open]) > .menu { display: none; }
  html[data-nav="rail"] .sidebar .branch[open]:not(.active) > summary {
    background: rgba(255, 106, 26, 0.14);
    box-shadow: none;
  }
}
.page-shell { min-width: 0; }
.topbar { min-height: 3.75rem; }
.wordmark-glyph {
  display: inline-block;
  height: 1.15em;
  width: auto;
  vertical-align: -0.06em;
  margin: 0 0.15em;
}
.topbar-wordmark { display: inline-block; }
.topbar-character {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  min-width: 0;
}
.topbar-portrait { flex: none; }
.topbar-character-name {
  max-width: 11rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.topbar-switcher { flex: none; }
.topbar-switcher > summary { white-space: nowrap; }
.nav-hamburger {
  display: none;
  align-items: center;
  justify-content: center;
  gap: 0.45rem;
  min-height: 2.35rem;
  padding: 0.35rem 0.5rem;
  line-height: 1;
  color: var(--text);
  background: transparent;
  border: 1px solid transparent;
  border-radius: 3px;
  cursor: pointer;
  font-family: "Univers Next Pro Condensed", "Univers Next Pro", sans-serif;
  font-size: 0.95rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
/* v0.3.07.008: the phone-bar hamburger floats bare like the
   sidebar glyph controls (the v0.3.07.007 borderless pass
   covered those; this closes the gap) — no resting box, just
   the gradient three-line icon on the same footprint, with a
   faint hover wash for feedback. */
.nav-hamburger:hover { background: rgba(255, 106, 26, 0.14); }
.topsearch { flex: 0 1 22rem; margin-left: 0; }
.searchwrap.topsearch-wrap { flex: 1 1 auto; width: 100%; }
.nav-hamburger:focus-visible,
.nav-state-btn:focus-visible,
.nav-reopen:focus-visible,
.nav-drawer-close:focus-visible,
.nav-expand-btn:focus-visible,
.sidebar .branch > summary:focus-visible {
  outline: 2px solid #ffb84d;
  outline-offset: 2px;
  box-shadow: 0 0 0 3px rgba(255, 106, 26, 0.35);
}
.nav-backdrop { display: none; }
.tw table {
  width: max-content;
  min-width: 100%;
}
.err { background: #3d1409; }
.ok { background: #2a1c08; }
.badge.kill { background: #2a1c08; }
.badge.loss { background: #3d1409; }
.suggest li.sel { background: #2a1a0c; }
tbody tr.yours td { background-color: #2a2015; }
.drag-placeholder { background: #1d1108; }
@supports not ((-webkit-background-clip: text) or (background-clip: text)) {
  h2,
  h3,
  .wordmark,
  .panel > h1:first-child > .gt {
    background: none;
    color: var(--success);
    -webkit-text-fill-color: currentColor;
  }
}
@media (max-width: 860px) {
  body { display: block; padding-top: 0; }
  html[data-nav="hidden"] .sidebar {
    display: block;
    overflow: visible;
    pointer-events: auto;
  }
  header { position: sticky; z-index: 90; }
  /* Drawer form: no backdrop blur over the page underneath
     (the 93% retained-color paint stays near-solid + crisp). */
  .sidebar {
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    width: min(20rem, calc(100vw - 3rem));
    height: 100dvh;
    z-index: 80;
    background: linear-gradient(rgba(21, 21, 21, 0.9), rgba(17, 17, 17, 0.9)) padding-box;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    transform: translateX(-105%);
    visibility: hidden;
    box-shadow: 18px 0 42px rgba(0, 0, 0, 0.55);
    transition: transform 0.22s ease, visibility 0s linear 0.22s;
  }
  .nav-drawer-checkbox:checked ~ .sidebar {
    transform: translateX(0);
    visibility: visible;
    transition-delay: 0s;
  }
  .sidebar-inner { padding-top: 3.7rem; }
  /* In drawer mode the navigation is always the full labeled
     list: the wide-screen rail/hidden choices never leak in,
     the state toggles make way for a real close control, and
     branch menus open inline instead of as rail flyouts. */
  .sidebar .nav-drawer-close { display: inline-flex; }
  html[data-nav="rail"] .sidebar .nav-expand-btn { display: inline-flex; }
  html[data-nav="rail"] .sidebar-inner { overflow-y: auto; }
  html[data-nav="rail"] .nav-label {
    display: block;
    max-width: 12rem;
    opacity: 1;
    transform: none;
  }
  html[data-nav="rail"] .sidebar-account { display: block; }
  .sidebar-account.has-character .sidebar-character { display: block; }
  html[data-nav="rail"] .sidebar-brand { justify-content: flex-start; padding-right: 0.35rem; padding-left: 0.35rem; }
  html[data-nav="rail"] .sidebar-actions { margin-left: auto; }
  html[data-nav="rail"] .sidenav a.navlink,
  html[data-nav="rail"] .sidebar .branch > summary {
    justify-content: flex-start;
    padding-right: 0.55rem;
    padding-left: 0.55rem;
  }
  html[data-nav="rail"] .sidebar .branch > summary::after { display: block; }
  html[data-nav="rail"] .sidebar .branch .menu {
    position: static;
    min-width: 0;
    margin: 0.15rem 0 0.35rem 2.55rem;
    padding: 0.15rem 0 0.15rem 0.4rem;
    background: transparent;
    border: 0;
    border-left: 1px solid #2a2a2a;
    box-shadow: none;
  }
  .nav-backdrop {
    position: fixed;
    inset: 0;
    z-index: 70;
    background: rgba(0, 0, 0, 0.66);
    cursor: pointer;
  }
  .nav-drawer-checkbox:checked ~ .nav-backdrop { display: block; }
  .nav-hamburger { display: inline-flex; }
  html.js[data-nav="hidden"] .nav-reopen { display: none; }
  .topbar {
    flex-wrap: nowrap;
    gap: 0.5rem;
    min-height: 3.2rem;
    padding: 0.45rem 0.6rem;
  }
  .topbar-wordmark {
    display: inline-block;
    font-size: 0.78rem;
    letter-spacing: 0.14em;
  }
  .topbar-character { display: none; }
  .topbar > .topsearch { order: 3; }
  .topbar > .page-sync { order: 4; }
  .topsearch {
    flex: 1 1 auto;
    min-width: 0;
    margin-left: 0;
  }
  .searchwrap.topsearch-wrap {
    flex: 1 1 auto;
    width: 100%;
    min-width: 0;
  }
  .page-sync { margin-left: 0; }
  .page-sync [data-page-sync-label] {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
  }
  main { margin: 0.65rem auto; padding: 0 0.6rem; }
  footer { padding: 0 0.6rem 1rem; }
}
/* Wide top bar: the wordmark holds the left corner and the
   page-sync indicator, search and character selector ride the
   right edge as one group with even gaps. Pushing from the
   wordmark (rendered on every page) keeps the group pinned
   whether or not the indicator happens to be showing. */
@media (min-width: 861px) {
  .topbar-wordmark { margin-right: auto; }
  .page-sync { margin-left: 0; }
  .topsearch { flex: 0 1 22rem; }
  /* v0.3.07.006: a slim ember divider between the search
     field and the character switcher, centred in the 1rem
     gap at roughly 60% of the bar height. */
  .topbar-character { position: relative; }
  .topbar-character::before {
    content: "";
    position: absolute;
    left: calc(-0.5rem - 0.5px);
    top: 50%;
    width: 1px;
    height: 2.25rem;
    transform: translateY(-50%);
    background: rgba(255, 106, 26, 0.25);
  }
}
@media (max-width: 719px) {
  .grid.home-grid > .card[data-widget="briefing"] { grid-column: span 2; }
  .fleet-tools input[type="search"] { max-width: 100%; }
}
@media (max-width: 560px) {
  .pchart .tick-mid { display: none; }
  .pchart text { font-size: 15px; }
  .legend-note { flex-basis: 100%; margin-left: 0; }
  .grid.home-grid { grid-template-columns: minmax(0, 1fr); }
  .grid.home-grid > .card[data-widget="briefing"] { grid-column: span 1; }
  .grid.home-grid > .span3,
  .grid.home-grid > .span6 { grid-column: span 1; }
  .grid { gap: 0.65rem; }
  .card { padding: 0.75rem 0.8rem 0.9rem; }
  .fleet-tools { gap: 0.4rem; }
  .fleet-tools input[type="search"] { width: 100%; }
  .topbar-wordmark { letter-spacing: 0.1em; }
}
@media (prefers-reduced-motion: reduce) {
  body,
  .sidebar,
  .nav-label,
  .sidenav a.navlink,
  .sidebar .branch > summary { transition: none !important; }
}

/* --- market category browser (v0.3.10) ------------------------
   Top-level market groups and their subgroups as glyph cards.
   Icons paint from the shared nav gradient; the solid flare
   gold here is the fallback when gradient paint fails, same as
   the nav icon set. */
.market-crumbs { margin: 0 0 0.4rem; }
.market-group-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(11.5rem, 1fr));
  gap: 0.55rem;
  margin: 0.6rem 0 0.8rem;
}
.market-group-card {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  min-height: 3.1rem;
  padding: 0.55rem 0.7rem;
  background: var(--row);
  border: 1px solid #262626;
  border-radius: 4px;
  color: var(--text);
}
.market-group-card:hover {
  background: var(--row-hover);
  color: var(--text-bright);
  text-decoration: none;
}
.market-group-icon {
  flex: 0 0 1.7rem;
  width: 1.7rem;
  color: var(--success);
  line-height: 1;
}
.market-group-icon svg {
  display: block;
  width: 1.7rem;
  height: 1.7rem;
  fill: #ffb84d;
  stroke: #ffb84d;
}
.market-group-name { min-width: 0; }

/* --- quick jump palette (v0.3.15) -----------------------------
   Ctrl+K overlay: a solid panel on an opaque surround (the two
   approved glass surfaces stay the only translucent ones). The
   ember ramp paints the panel's top edge and the group heads,
   matching the nav icon family. */
.quickjump-btn {
  flex: none;
  margin-left: 0.5rem;
  padding: 0.28rem 0.45rem;
  background: #0e0e0e;
  border: 1px solid #2a2a2a;
  border-radius: 4px;
  color: var(--muted-2);
  cursor: pointer;
  font: inherit;
}
.quickjump-btn:hover, .quickjump-btn:focus-visible {
  border-color: var(--accent);
  color: var(--text-bright);
  outline: none;
}
.quickjump-btn kbd {
  font: inherit;
  font-size: 0.78rem;
  letter-spacing: 0.04em;
}
.quickjump {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: #0d0503;
  overflow-y: auto;
}
.quickjump-panel {
  width: min(38rem, calc(100vw - 2rem));
  margin: 9vh auto 2rem;
  background: var(--panel);
  border: 1px solid #2a2a2a;
  border-top: 3px solid var(--accent);
  border-radius: 6px;
  box-shadow: 0 18px 48px rgba(0, 0, 0, 0.8);
  padding: 0.8rem;
  animation: quickjump-in 120ms ease-out;
}
@keyframes quickjump-in {
  from { opacity: 0; transform: translateY(-6px); }
  to { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .quickjump-panel { animation: none; }
}
.quickjump-panel input[type="search"] {
  width: 100%;
  font-size: 1rem;
  padding: 0.6rem 0.7rem;
}
.quickjump-results {
  margin: 0.6rem 0 0;
  padding: 0;
  list-style: none;
  max-height: 52vh;
  overflow-y: auto;
}
.quickjump-results li {
  padding: 0.5rem 0.6rem;
  border-radius: 3px;
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.quickjump-results li.sel { background: #2a1a0c; color: var(--text-bright); }
.quickjump-results li.qj-group {
  padding: 0.55rem 0.6rem 0.2rem;
  cursor: default;
  font-family: "Univers Next Pro Condensed", "Univers Next Pro", sans-serif;
  font-weight: 600;
  font-size: 0.78rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--success);
}
.quickjump-results li.qj-pending {
  color: var(--note);
  cursor: default;
}
.quickjump-results .qj-label {
  display: block;
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  color: var(--muted-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.quickjump-hint {
  margin: 0.55rem 0.1rem 0;
  font-size: 0.75rem;
  color: var(--muted-2);
}
body.quickjump-open { overflow: hidden; }
@media (max-width: 720px) {
  .quickjump-panel { margin-top: 4vh; }
  .quickjump-results { max-height: 60vh; }
  .quickjump-btn { margin-left: 0.35rem; }
}

/* --- fitting simulator (v0.3.21) --- */
.fit-head {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem 1rem;
  align-items: end;
  margin-bottom: 0.4rem;
}
.fit-head label { display: grid; gap: 0.25rem; font-size: 0.85rem; }
.fit-head select, .fit-charge select {
  background: var(--input-bg);
  border: 1px solid #2a2a2a;
  border-radius: 3px;
  color: var(--text);
  padding: 0.42rem 0.6rem;
  font: inherit;
}
html[data-theme="light"] .fit-head select, html[data-theme="light"] .fit-charge select {
  border-color: #d8cdb8;
}
.fit-head select:focus, .fit-charge select:focus {
  border-color: var(--accent);
  outline: none;
  box-shadow: 0 0 8px rgba(255, 106, 26, 0.35);
}
.fit-cols { display: flex; flex-wrap: wrap; gap: 1rem; align-items: flex-start; }
.fit-slots { flex: 1 1 20rem; min-width: min(18rem, 100%); }
.fit-stats {
  flex: 1 1 22rem;
  min-width: min(18rem, 100%);
  background: var(--panel);
  border: 1px solid #242424;
  border-radius: 4px;
  padding: 0.8rem 1rem;
}
.fit-stats > h4:first-child { margin-top: 0; color: var(--success); }
.fit-group { margin-bottom: 0.8rem; }
.fit-group > h4 { margin: 0 0 0.4rem; }
.fit-chips { display: flex; flex-wrap: wrap; gap: 0.35rem; }
.fit-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  background: var(--row-alt);
  border: 1px solid #2c2c2c;
  border-radius: 3px;
  padding: 0.15rem 0.4rem;
}
.fit-chip:hover { background: var(--row-hover); }
.fit-chip-name {
  background: none;
  border: none;
  color: var(--text);
  font: inherit;
  cursor: pointer;
  padding: 0;
}
.fit-chip-btn {
  background: #242424;
  border: 1px solid #3a3a3a;
  border-radius: 3px;
  color: var(--text);
  cursor: pointer;
  font: inherit;
  line-height: 1;
  padding: 0.1rem 0.35rem;
}
.fit-chip-qty { color: var(--success); }
.fit-qty {
  width: 4.2rem;
  background: #0e0e0e;
  border: 1px solid #2a2a2a;
  border-radius: 3px;
  color: var(--text);
  font: inherit;
  padding: 0.15rem 0.3rem;
}
.fit-slot-empty {
  background: transparent;
  border: 1px dashed #3a3a3a;
  border-radius: 3px;
  color: var(--muted);
  cursor: pointer;
  font: inherit;
  padding: 0.3rem 0.5rem;
}
.fit-slot-empty:hover { border-color: var(--accent); color: var(--text); }
.fit-bar-row { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.45rem; }
.fit-bar-label { flex: 0 0 5.2rem; font-size: 0.85rem; }
.fit-bar {
  flex: 1 1 auto;
  height: 0.6rem;
  background: #0a0a0a;
  border: 1px solid #2c2c2c;
  border-radius: 3px;
  overflow: hidden;
}
.fit-bar > span { display: block; height: 100%; background: var(--success); }
.fit-bar-row.over .fit-bar > span { background: var(--danger); }
.fit-bar-row.over .fit-bar-nums { color: var(--danger); }
.fit-bar-row.good .fit-bar-nums { color: var(--success); }
.fit-bar-nums { font-size: 0.85rem; white-space: nowrap; }
.fit-table { width: 100%; margin-bottom: 0.6rem; }
.fit-over { color: var(--danger); }
.fit-good { color: var(--success); }
.fit-note, .fit-notes { color: var(--note); }
.fit-notes { padding-left: 1.2rem; }
.fit-implants { margin: 0.4rem 0; color: var(--note); }
.fit-implants summary { cursor: pointer; }
.fit-implants ul { margin: 0.3rem 0 0; padding-left: 1.2rem; }
.fit-missing {
  border: 1px solid #4a3410;
  border-radius: 4px;
  padding: 0.6rem 0.8rem;
  margin-top: 0.6rem;
}
.fit-missing > h4 { margin: 0 0 0.4rem; color: var(--danger); }
.fit-missing ul { margin: 0; padding-left: 1.2rem; }
/* Visual fitting: ship render with module slots on arcs around it. */
/* The workbench is the tooltip's positioning context: tooltips
   anchor to slot icons inside it, never the page header. */
.fit-wb { position: relative; }
.fit-visual {
  position: relative;
  width: min(34rem, 100%);
  aspect-ratio: 1 / 1;
  margin: 0 auto 1rem;
  user-select: none;
  -webkit-user-select: none;
}
/* Distinct outer border ring around the whole display, ember. */
.fit-vring-outer {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 98%;
  aspect-ratio: 1 / 1;
  transform: translate(-50%, -50%);
  border: 2px solid rgba(255, 106, 26, 0.55);
  border-radius: 50%;
  box-shadow: 0 0 18px rgba(255, 106, 26, 0.35), inset 0 0 24px rgba(255, 106, 26, 0.10);
  pointer-events: none;
}
/* Bordered per-group arc segments behind the slot ring. */
.fit-vsegs {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}
.fit-vseg {
  fill: rgba(255, 106, 26, 0.07);
  stroke: rgba(255, 140, 40, 0.55);
  stroke-width: 0.7;
}
/* Undo/redo ride the visual's top-right corner, always at hand. */
.fit-vhistory {
  position: absolute;
  top: 0.45rem;
  right: 0.45rem;
  display: flex;
  gap: 0.3rem;
  z-index: 6;
}
.fit-vhist {
  width: 1.9rem;
  height: 1.9rem;
  border-radius: 50%;
  border: 1px solid rgba(255, 106, 26, 0.6);
  background: rgba(12, 10, 8, 0.85);
  color: var(--success);
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
  padding: 0;
  box-shadow: 0 0 8px rgba(255, 106, 26, 0.25);
}
.fit-vhist:hover:not(:disabled) { border-color: var(--success); color: var(--gold); }
.fit-vhist:disabled { opacity: 0.3; cursor: default; box-shadow: none; }
/* The ship is the centerpiece: circular showcase, ember gradient
   ring and glow — not a square thumbnail. */
.fit-vship {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 40%;
  aspect-ratio: 1 / 1;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  padding: 3px;
  background: linear-gradient(135deg, #ffd27a 0%, #ff6a1a 50%, #d63c14 100%);
  box-shadow: 0 0 30px rgba(255, 106, 26, 0.35), 0 0 10px rgba(214, 60, 20, 0.45);
  pointer-events: none;
}
.fit-vship img {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
  background: #0a0a0a;
}
/* Faint ember ring anchoring the slot circles. */
.fit-vring {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 88%;
  aspect-ratio: 1 / 1;
  transform: translate(-50%, -50%);
  border: 1px solid rgba(255, 106, 26, 0.16);
  border-radius: 50%;
  pointer-events: none;
}
/* Ember divider ticks between slot groups, radial on the ring. */
.fit-vsep {
  position: absolute;
  width: 3px;
  height: 1.15rem;
  border-radius: 2px;
  background: linear-gradient(180deg, #ffd27a 0%, #ff6a1a 50%, #d63c14 100%);
  box-shadow: 0 0 7px rgba(255, 106, 26, 0.6);
  pointer-events: none;
}
/* In-ring group captions, ember gradient text like the titles. */
.fit-vlabel {
  position: absolute;
  transform: translate(-50%, -50%);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-indent: 0.22em;
  white-space: nowrap;
  background: linear-gradient(90deg, #ffd27a 0%, #ff6a1a 60%, #d63c14 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  opacity: 0.85;
  pointer-events: none;
}
.fit-vslot {
  position: absolute;
  width: 2.9rem;
  height: 2.9rem;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  border: 2px dashed #3a3a3a;
  background: rgba(10, 10, 10, 0.72);
  color: var(--muted);
  cursor: pointer;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.2rem;
  touch-action: none;
}
.fit-vslot:hover { border-color: var(--accent); color: var(--text); }
.fit-vslot.filled { border-style: solid; border-color: #6b5a43; }
.fit-vslot.filled:hover { border-color: var(--accent); }
.fit-vslot.filled img { width: 84%; height: 84%; border-radius: 50%; pointer-events: none; }
/* Module states: in-game language. Offline modules go dark and
   desaturated; online-but-inactive dims slightly; overheated
   carries an ember glow (never green). */
.fit-vslot.st-offline { opacity: 0.55; }
.fit-vslot.st-offline img { filter: grayscale(1) brightness(0.55); }
.fit-vslot.st-online img { filter: brightness(0.78); }
.fit-vslot.st-overheated { border-color: #ff6a1a; }
.fit-vslot.st-overheated img { filter: saturate(1.25) brightness(1.05); }
.fit-vslot.st-overheated::after {
  content: ""; position: absolute; inset: -4px; border-radius: 50%;
  box-shadow: 0 0 12px rgba(255, 106, 26, 0.75), inset 0 0 8px rgba(255, 106, 26, 0.35);
  pointer-events: none;
}
/* Chip state visuals echo the slot ring. */
.fit-chip.st-offline { opacity: 0.55; }
.fit-chip.st-offline .fit-chip-name { filter: grayscale(1); }
.fit-chip.st-online { opacity: 0.85; }
.fit-chip.st-overheated { border-color: #ff6a1a; box-shadow: 0 0 8px rgba(255, 106, 26, 0.45); }
/* Loaded-charge badge: small icon tucked into the slot's corner.
   Tap it to jump to the weapon's ammunition select. */
.fit-vslot .fit-vammo {
  position: absolute;
  right: -3px;
  bottom: -3px;
  width: 1.2rem;
  height: 1.2rem;
  border-radius: 50%;
  border: 1px solid #ffb84d;
  background: #0a0a0a;
  overflow: hidden;
  box-shadow: 0 0 6px rgba(255, 184, 77, 0.55);
  cursor: pointer;
  padding: 0;
}
.fit-vslot .fit-vammo img { width: 100%; height: 100%; pointer-events: none; }
/* No silent taps: every add/remove flashes its target ember so the
   eye catches it within a frame of the re-render. */
@keyframes fit-flash {
  0% { box-shadow: 0 0 0 3px rgba(255, 184, 77, 0.95), 0 0 20px rgba(255, 106, 26, 0.85); }
  100% { box-shadow: 0 0 0 0 rgba(255, 184, 77, 0), 0 0 0 rgba(255, 106, 26, 0); }
}
.fit-vslot.flash { animation: fit-flash 0.7s ease-out; border-color: var(--success); }
.fit-group.flash h3, .fit-charge.flash { animation: fit-flash 0.7s ease-out; border-radius: 4px; }
select.flash { animation: fit-flash 0.7s ease-out; }
.fit-vslot.drop-ok {
  border-color: var(--success);
  border-style: solid;
  box-shadow: 0 0 10px rgba(255, 184, 77, 0.6);
}
.fit-vslot.drag-src { opacity: 0.35; }
/* Drag highlight: slots the dragged module could fit in glow
   ember/gold; the rest stay dim. Cleared on drop/dragend. */
.fit-vslot.drop-valid {
  border-color: var(--success);
  border-style: solid;
  box-shadow: 0 0 12px rgba(255, 184, 77, 0.55);
}
.fit-vslot.drop-dim { opacity: 0.3; }
/* Module quick-look tooltip: name, slot, meta, CPU/PG. Shown on
   hover (desktop) or tap (mobile); never navigates. Positioned by
   JS just outside the slot, away from the ship. */
.fit-tip {
  position: absolute;
  z-index: 60;
  background: rgba(14, 14, 14, 0.96);
  border: 1px solid var(--accent);
  border-radius: 4px;
  padding: 0.45rem 2rem 0.45rem 0.6rem;
  font-size: 0.8rem;
  line-height: 1.35;
  max-width: 12rem;
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.6), 0 0 12px rgba(255, 106, 26, 0.25);
}
.fit-tip-name { font-weight: 600; color: var(--text); margin-bottom: 0.15rem; }
.fit-tip-sub { color: var(--muted); font-size: 0.75rem; }
.fit-tip-stats { color: var(--muted); font-size: 0.75rem; white-space: nowrap; }
.fit-tip-x {
  position: absolute;
  top: 0.1rem;
  right: 0.3rem;
  background: none;
  border: none;
  color: var(--muted);
  font-size: 1rem;
  cursor: pointer;
  padding: 0.1rem 0.3rem;
}
.fit-tip-x:hover { color: var(--text); }
/* Tooltip module-state row: only the states this module can
   take, current one highlighted in ember. */
.fit-tip-states { display: flex; flex-wrap: wrap; gap: 0.25rem; margin-top: 0.4rem; }
.fit-tip-state {
  background: #1c1c1c; border: 1px solid #3a3a3a; border-radius: 3px;
  color: var(--text); font: inherit; font-size: 0.8rem; line-height: 1;
  padding: 0.45rem 0.6rem; min-height: 2rem; cursor: pointer;
}
.fit-tip-state:hover { border-color: var(--accent); }
.fit-tip-state.on {
  border-color: #ff6a1a; color: #ffd9a8;
  box-shadow: 0 0 8px rgba(255, 106, 26, 0.35);
}
.fit-picker {
  margin-top: 0.8rem;
  border: 1px solid #2c2c2c;
  border-radius: 4px;
  background: var(--panel);
  padding: 0.7rem;
}
.fit-picker-head { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; }
.fit-picker-head input[type="text"] { flex: 1 1 14rem; }
.fit-picker-list { list-style: none; margin: 0.6rem 0 0; padding: 0; max-height: 16rem; overflow-y: auto; }
.fit-picker-list li {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.4rem 0.5rem;
  border-radius: 3px;
  cursor: pointer;
  /* Vertical scroll stays native; a mostly-horizontal press
     becomes a pointer drag onto a slot. */
  touch-action: pan-y;
}
.fit-picker-list li:hover { background: var(--row-hover); }
.fit-picker-list .sug-label { color: var(--muted); font-size: 0.8rem; }
/* The module icon that follows the pointer mid-drag. */
.fit-drag-ghost {
  position: fixed;
  z-index: 200;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 2px solid #ffb84d;
  background: rgba(10, 10, 10, 0.9);
  box-shadow: 0 0 16px rgba(255, 106, 26, 0.7);
  pointer-events: none;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--success);
  font-size: 0.7rem;
}
.fit-drag-ghost img { width: 88%; height: 88%; border-radius: 50%; }
.fit-picker-hint { color: var(--muted); font-size: 0.8rem; }
/* Module search: its own prominent input, sticky above the
   workbench so it stays visible while fitting. */
.fit-modsearch {
  position: sticky;
  top: 4.25rem;
  z-index: 9;
  background: linear-gradient(to bottom, rgba(21, 21, 21, 0.97), rgba(14, 14, 14, 0.97));
  border: 1px solid #262626;
  border-radius: 6px;
  padding: 0.6rem 0.7rem 0.2rem;
  margin: 0.8rem 0;
}
.fit-modsearchwrap { display: block; width: 100%; }
.fit-modsearch .fit-searchrow { margin: 0.5rem 0 0.4rem; }
/* Save-to-EVE notices: confirmation and plain-spoken errors. */
.fit-notice {
  border: 1px solid var(--accent);
  border-radius: 4px;
  background: rgba(255, 106, 26, 0.08);
  padding: 0.5rem 0.7rem;
  margin: 0.6rem 0;
}
.fit-notice.err { border-color: var(--danger); background: rgba(198, 47, 16, 0.08); }
@media (max-width: 480px) {
  .fit-vship { width: 44%; }
  .fit-vslot { width: 2.3rem; height: 2.3rem; font-size: 1rem; }
  .fit-vlabel { font-size: 0.6rem; }
  .fit-modsearch { top: 3.9rem; }
}
/* Unified search row: family chips + filters. */
.fit-searchwrap { flex: 2 1 20rem; }
.fit-searchrow {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1rem;
  align-items: center;
  margin: 0.6rem 0;
}
.fit-famchips { display: flex; flex-wrap: wrap; gap: 0.3rem; }
.fit-famchips button {
  background: #141414;
  border: 1px solid #2c2c2c;
  border-radius: 999px;
  color: var(--muted);
  cursor: pointer;
  font: inherit;
  font-size: 0.8rem;
  padding: 0.25rem 0.7rem;
  touch-action: manipulation;
}
.fit-famchips button.on {
  border-color: var(--accent);
  color: var(--text);
  background: #1d1710;
}
.fit-check {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.85rem;
  color: var(--muted);
  cursor: pointer;
}
.fit-check.disabled { opacity: 0.45; cursor: default; }
.fit-check select { font: inherit; font-size: 0.85rem; }
/* Suggestion dropdown: kind groups, icons, keyboard nav. */
.suggest li.sug-kind {
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--accent);
  cursor: default;
  padding: 0.5rem 0.5rem 0.2rem;
}
.suggest li.sug-kind:hover { background: none; }
.suggest li.active { background: var(--row-hover); }
.suggest .sug-icon {
  width: 1.6rem;
  height: 1.6rem;
  border-radius: 3px;
  flex: 0 0 auto;
}
.suggest .sug-empty { color: var(--muted); cursor: default; }
.suggest .sug-empty:hover { background: none; }
.fit-picker-list .sug-icon {
  width: 1.6rem;
  height: 1.6rem;
  border-radius: 3px;
  flex: 0 0 auto;
}
.fit-picker-list li { align-items: center; }
/* ESI fittings list controls. */
.fit-esi-controls {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0.6rem 0;
}
.fit-esi-controls input[type="text"] { flex: 1 1 14rem; }
.fit-eft { margin-top: 1rem; }
.fit-eft textarea {
  width: 100%;
  background: #0e0e0e;
  border: 1px solid #2a2a2a;
  border-radius: 3px;
  color: var(--text);
  font: inherit;
  font-size: 0.85rem;
  padding: 0.5rem 0.6rem;
}
.fit-eft textarea:focus {
  border-color: var(--accent);
  outline: none;
  box-shadow: 0 0 8px rgba(255, 106, 26, 0.35);
}
.fit-charge { margin: 0.3rem 0; }

/* DPS/volley headline: the two numbers fitters look at first. */
.fit-headline {
  display: flex;
  gap: 2rem;
  align-items: baseline;
  margin: 0.6rem 0 0.8rem;
  padding: 0.7rem 1rem;
  border: 1px solid #2c2c2c;
  border-radius: 6px;
  background: rgba(255, 184, 77, 0.04);
}
.fit-headline-dps, .fit-headline-volley { display: flex; align-items: baseline; gap: 0.5rem; flex-wrap: wrap; }
.fit-headline-num {
  font-size: 1.9rem;
  font-weight: 700;
  color: var(--success);
  line-height: 1;
}
.fit-headline-label {
  font-size: 0.85rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted);
}
.fit-headline-sub { font-size: 0.78rem; color: var(--muted); flex-basis: 100%; }

/* Fit metadata + your-fits search in the editor header. */
.fit-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.8rem;
  align-items: flex-end;
  margin-top: 0.6rem;
}
.fit-meta-desc { flex: 2 1 16rem; }
.fit-meta-tags { flex: 1 1 10rem; }
.fit-meta label { display: flex; flex-direction: column; gap: 0.2rem; font-size: 0.8rem; color: var(--muted); }
.fit-meta input[type="text"] { width: 100%; }
.fit-yourfits {
  display: flex;
  flex-wrap: wrap;
  gap: 0.8rem;
  align-items: center;
  margin-top: 0.6rem;
}
.fit-yourfitswrap { flex: 1 1 18rem; position: relative; }
.fit-yourfitswrap .suggest { position: absolute; z-index: 50; }
.fit-saved { font-size: 0.8rem; color: var(--muted); }
.fit-tag {
  display: inline-block;
  background: rgba(255, 184, 77, 0.1);
  border: 1px solid #4a3d2c;
  border-radius: 3px;
  padding: 0.05rem 0.4rem;
  margin-right: 0.25rem;
  font-size: 0.75rem;
  color: var(--success);
}
#fit-undo:disabled, #fit-redo:disabled { opacity: 0.35; cursor: default; }

/* ============================================================
   v0.3.30: wide-screen fitting workbench.
   At >=1100px the workbench becomes a 3-column grid: module
   text lists LEFT, ship ring CENTER, stats panel RIGHT — all at
   the same height so stat changes read in real time without
   scrolling. .fit-cols flattens via display:contents so its
   children (.fit-slots, .fit-stats) become direct grid items
   alongside .fit-visual. When no ship is picked (.fit-visual
   absent), .fit-slots and .fit-stats take columns 1 and 3.
   Below 1100px the stacked layout is untouched.
   ============================================================ */
@media (min-width: 1100px) {
  .fit-wb {
    display: grid;
    grid-template-columns: minmax(15rem, 1fr) minmax(20rem, 1.35fr) minmax(17rem, 1fr);
    gap: 1.25rem;
    align-items: start;
  }
  /* Flatten the wrapper so its children join the grid. */
  .fit-wb > .fit-cols { display: contents; }
  .fit-wb > .fit-visual {
    grid-column: 2;
    grid-row: 1;
    width: 100%;
    max-width: 34rem;
    margin: 0;
    justify-self: center;
  }
  .fit-wb > .fit-cols > .fit-slots { grid-column: 1; grid-row: 1; }
  .fit-wb > .fit-cols > .fit-stats { grid-column: 3; grid-row: 1; }
  /* No ship picked yet: no empty middle column — the stats
     panel stretches over columns 2-3. */
  .fit-wb:not(:has(> .fit-visual)) > .fit-cols > .fit-stats { grid-column: 2 / 4; }
}

/* ============================================================
   v0.3.30: light theme.
   All page theming flows through the :root variables, so the
   light theme is a variable re-skin plus overrides for the
   handful of surfaces painted with hardcoded dark colors.
   Ember/gold accents are kept; positive states stay gold —
   never green. The explicit toggle (documentElement[data-theme])
   wins; with no explicit choice the OS prefers-color-scheme
   decides (media query below).
   ============================================================ */
html[data-theme="light"] {
  color-scheme: light;
  --text: #2a241d;
  --text-bright: #20180e;
  --accent: #ff6a1a;
  --success: #a86f14;   /* positive = deep gold, never green */
  --danger: #b02a0d;
  --gold: #9e6410;
  --muted: #6e5a42;
  --muted-2: #5f4c36;
  --note: #8a5f24;
  --panel: #fdfbf6;
  --panel-head: #f0e9da;
  --row: #f8f4ec;
  --row-alt: #f1ebdf;
  --row-hover: #e9e0cf;
  --input-bg: #ffffff;
}
html[data-theme="light"] body { background: #f4f1ea; }
html[data-theme="light"] body::before { display: none; }
/* Glass chrome: light paint, same blur recipe. */
html[data-theme="light"] header {
  background: linear-gradient(to bottom, rgba(247, 243, 235, 0.9), rgba(236, 229, 214, 0.9));
  border-bottom-color: #d9cfba;
  box-shadow: 0 1px 8px rgba(90, 70, 40, 0.25);
}
html[data-theme="light"] .sidebar {
  background: linear-gradient(rgba(247, 243, 235, 0.9), rgba(236, 229, 214, 0.9)) padding-box;
  border-right-color: #d9cfba;
}
html[data-theme="light"] footer {
  background: rgba(244, 241, 234, 0.85);
  border-top-color: #d9cfba;
  text-shadow: none;
}
html[data-theme="light"] header a.navlink,
html[data-theme="light"] .branch > summary,
html[data-theme="light"] header .who,
html[data-theme="light"] thead th { text-shadow: none; }
/* Surfaces painted with hardcoded dark colors. */
html[data-theme="light"] .card { background: #fdfbf6; border-color: #ddd2bd; }
html[data-theme="light"] .panel {
  background: linear-gradient(#fdfbf6, #f8f4ec) padding-box,
    linear-gradient(135deg, #e8d5b5 0%, #d9c19a 45%, #c9ad7f 100%) border-box;
  border: 1px solid transparent;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.8), 0 2px 14px rgba(0, 0, 0, 0.08);
}
html[data-theme="light"] input[type="text"],
html[data-theme="light"] input[type="search"],
html[data-theme="light"] .fit-qty,
html[data-theme="light"] .fit-eft textarea,
html[data-theme="light"] .fit-tip-state { background: #fffdf9; border-color: #d3c7ae; }
html[data-theme="light"] .suggest,
html[data-theme="light"] .branch .menu {
  background: #fffdf9;
  border-color: #d3c7ae;
  box-shadow: 0 10px 24px rgba(90, 70, 40, 0.22);
}
html[data-theme="light"] .branch .menu a { color: #5c4a33; }
html[data-theme="light"] .branch .menu a:hover { background: #f0e7d2; }
html[data-theme="light"] .branch .menu a.active,
html[data-theme="light"] .sidebar .branch .menu a.active { background-color: #f0dfbc; }
html[data-theme="light"] .branch .menu {
  background: #fdfbf6;
  border-color: #d9cfba;
}
html[data-theme="light"][data-nav="rail"] .sidebar .branch .menu {
  background: #fdfbf6;
  border-color: #d9cfba;
  box-shadow: 0 10px 24px rgba(90, 70, 40, 0.22);
}
html[data-theme="light"] .fit-modsearch {
  background: linear-gradient(to bottom, rgba(253, 251, 246, 0.97), rgba(248, 244, 236, 0.97));
  border-color: #d9cfba;
}
html[data-theme="light"] .sidebar .branch .menu a { border-color: #d3c7ae; }
html[data-theme="light"] .sidenav a.navlink:hover,
html[data-theme="light"] .sidebar .branch > summary:hover,
html[data-theme="light"] .sidenav a.navlink.active,
html[data-theme="light"] .sidebar .branch.active > summary,
html[data-theme="light"] .sidebar .branch[open] > summary { background: #ece3cf; }
html[data-theme="light"] .nav-state-btn,
html[data-theme="light"] .nav-reopen,
html[data-theme="light"] .nav-drawer-close,
html[data-theme="light"] .nav-expand-btn { background: #fffdf9; border-color: #d9b98a; }
/* Glyph chips keep a light paint so hover text stays readable. */
html[data-theme="light"] .foldbtn,
html[data-theme="light"] .cardremove,
html[data-theme="light"] .cardspan,
html[data-theme="light"] .modal-close,
html[data-theme="light"] .quickjump-btn { background: #fffdf9; border-color: #d3c7ae; }
/* The ember gradient button keeps its dark paint in light mode. */
html[data-theme="light"] .btn:hover { color: #fff6e6; }
/* Tables. */
html[data-theme="light"] table { border-color: #d9cfba; }
html[data-theme="light"] th,
html[data-theme="light"] td { border-top-color: #e4d9c2; border-bottom-color: #d9cfba; }
html[data-theme="light"] thead th { border-bottom-color: #d9cfba; }
html[data-theme="light"] tbody tr.yours td { background-color: #f3e3bd; }
html[data-theme="light"] .tw tbody tr.yours td:first-child { background: #f3e3bd; }
/* Alerts: light tints, dark text. */
html[data-theme="light"] .err { background: rgba(198, 47, 16, 0.08); color: #7a1e08; }
html[data-theme="light"] .ok { background: rgba(255, 184, 77, 0.2); color: #7a5410; }
/* Quickjump + fitting bits. */
html[data-theme="light"] .quickjump-results li.sel { background: #f0dfbc; }
html[data-theme="light"] .fit-stats { border-color: #ddd2bd; }
html[data-theme="light"] .fit-chip { border-color: #d3c7ae; }
html[data-theme="light"] .fit-chip-btn { background: #f0e9d8; border-color: #d3c7ae; }
html[data-theme="light"] .fit-bar { background: #e7ddc8; border-color: #d3c7ae; }
html[data-theme="light"] .fit-famchips button { background: #fffdf9; border-color: #d3c7ae; }
html[data-theme="light"] .fit-famchips button.on { background: #f5e3c2; }
html[data-theme="light"] .fit-headline { border-color: #d3c7ae; background: rgba(255, 184, 77, 0.1); }
html[data-theme="light"] .fit-slot-empty { border-color: #c9b992; }
html[data-theme="light"] .fit-vhist { background: rgba(255, 253, 249, 0.92); }
html[data-theme="light"] .fit-tip-state.on { color: #8a4d0e; }
/* Tooltips stay dark floating chips in both themes. */
html[data-theme="light"] .fit-tip { color: #faf3e6; }
html[data-theme="light"] .fit-tip-name { color: #fff6e6; }
html[data-theme="light"] .fit-tip-sub,
html[data-theme="light"] .fit-tip-stats { color: #b39a7d; }

/* v0.3.31.007: comprehensive light-mode surface overrides — every
   hardcoded dark background gets a light counterpart. */
html[data-theme="light"] .branch .menu a:hover { background: #f0e7d2; color: #20180e; }
html[data-theme="light"] .suggest { background: #fdfbf6; border-color: #d9cfba; }
html[data-theme="light"] .suggest li.sel { background: #f0dfbc; }
html[data-theme="light"] .draghandle { background: #f1ebdf; }
html[data-theme="light"] .modal-close { background: #f1ebdf; color: #5c4a33; }
html[data-theme="light"] .nav-expand-btn { background: #f1ebdf; }
html[data-theme="light"] .quickjump { background: #f4f1ea; }
html[data-theme="light"] .quickjump-panel { background: #fdfbf6; border-color: #d9cfba; }
html[data-theme="light"] .quickjump-btn { background: #f1ebdf; }
html[data-theme="light"] .fit-chip-btn { background: #f1ebdf; border-color: #d9cfba; color: #5c4a33; }
html[data-theme="light"] .fit-qty { background: #fdfbf6; }
html[data-theme="light"] .fit-bar { background: #e9e0cf; }
html[data-theme="light"] .fit-vship img { background: #f1ebdf; }
html[data-theme="light"] .fit-vslot .fit-vammo { background: #f1ebdf; }
html[data-theme="light"] .fit-tip-state { background: #f1ebdf; border-color: #d9cfba; color: #5c4a33; }
html[data-theme="light"] .fit-famchips button { background: #f1ebdf; border-color: #d9cfba; color: #5c4a33; }
html[data-theme="light"] .fit-famchips button.on { background: #e8d5b5; color: #20180e; }
html[data-theme="light"] .fit-eft textarea { background: #ffffff; border-color: #d8cdb8; color: #2a241d; }
html[data-theme="light"] .drag-placeholder { background: #f0e7d2; }
html[data-theme="light"] tbody tr.yours td { background-color: #f3e3bd; }


/* ============================================================
   v0.3.31: theme toggle + sign out footer.
   Bottom-of-menu icon buttons that stay visible in rail mode.
   ============================================================ */
.sidebar-account-footer {
  margin-top: auto;
  padding-top: 0.5rem;
  border-top: 1px solid #262626;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}
.sidebar-account-footer .navlink {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 0.6rem;
  min-height: 2.35rem;
  padding: 0.42rem 0.55rem;
  border-radius: 3px;
  color: var(--text);
  font-size: 1rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  cursor: pointer;
  text-decoration: none;
}
.sidebar-account-footer .navlink:hover {
  background: rgba(255,255,255,0.04);
  color: var(--text-bright);
}
#theme-toggle {
  background: transparent;
  border: none;
  border-radius: 0.4rem;
  color: var(--gold);
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
  font-family: inherit;
  text-align: left;
}
#theme-toggle:hover { color: var(--text-bright); background: rgba(255,255,255,0.04); }

/* ============================================================
   v0.3.32: character selector dropdown.
   Searchable dropdown replacing the horizontal character link list.
   ============================================================ */
.charselector {
  position: relative;
  max-width: 24rem;
  margin: 0.5rem 0;
}
.charselector-input {
  width: 100%;
  background: var(--input-bg);
  border: 1px solid #2a2a2a;
  border-radius: 3px;
  color: var(--text);
  padding: 0.42rem 0.6rem;
  font: inherit;
  cursor: pointer;
}
.charselector-input:focus {
  border-color: var(--accent);
  outline: none;
  box-shadow: 0 0 8px rgba(255, 106, 26, 0.35);
}
.charselector-dropdown {
  position: absolute;
  top: calc(100% + 0.25rem);
  left: 0;
  right: 0;
  z-index: 50;
  max-height: 16rem;
  overflow-y: auto;
  background: var(--input-bg);
  border: 1px solid #2a2a2a;
  border-radius: 3px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
}
.charselector-dropdown[hidden] { display: none; }
.charselector-option {
  display: block;
  padding: 0.5rem 0.6rem;
  color: var(--text);
  text-decoration: none;
  border-bottom: 1px solid rgba(255,255,255,0.05);
}
.charselector-option:last-child { border-bottom: none; }
.charselector-option:hover {
  background: var(--row-hover);
  color: var(--text-bright);
}
.charselector-option.active {
  background: rgba(255, 106, 26, 0.12);
  color: var(--gold);
}
.charselector-option[hidden] { display: none; }
.charselector-tags {
  font-size: 0.8em;
  color: var(--muted);
  margin-left: 0.4rem;
}
html[data-theme="light"] .charselector-input,
html[data-theme="light"] .charselector-dropdown {
  border-color: #d8cdb8;
}
html[data-theme="light"] .charselector-option {
  border-bottom-color: rgba(0,0,0,0.05);
}

/* ============================================================
   v0.3.32.004: light-mode sidebar separators.
   The utility/account section borders were hardcoded dark.
   ============================================================ */
html[data-theme="light"] .sidenav-utility,
html[data-theme="light"] .sidebar-account {
  border-top-color: #d9cfba;
}
