:root {
  color-scheme: dark;
  /* Chrome: the reference uses a near-black navy for the outermost surfaces and
     a slightly lifted navy for panels, so depth comes from luminance steps
     rather than borders alone. */
  --void: #070b14;
  --canvas: #0b1120;
  --surface: #111a2c;
  --surface-2: #16223a;
  --panel-deep: #0a101d;
  /* Text sits at three levels: primary, secondary, and a dim label colour. */
  --ink: #e8f0fa;
  --muted: #8296b3;
  --faint: #5d6f8c;
  --line: #24334f;
  --line-strong: #33456a;
  /* Accents: cyan is the interactive colour, amber the reward/highlight colour. */
  --cyan: #46d2ff;
  --cyan-dim: #1d90bd;
  --cyan-soft: rgba(70, 210, 255, 0.12);
  --amber: #f2a33c;
  --amber-soft: rgba(242, 163, 60, 0.14);
  --violet: #9b5cf6;
  --red: #ff5d6b;
  --green: #35d69b;
  --green-dark: #23a878;
  --mint: rgba(53, 214, 155, 0.14);

  /* Thumbnail well for item art.
     This was previously a LIGHT well (#eef2f7), on the reasoning that the generated renders
     were dark studio photographs (measured border luminance 27-56) and would lose their
     outline against a dark card. That reasoning held for photographs, but a light plate
     around dark art is exactly what makes each card look like a grey box with a pasted
     picture; the pale border in the screenshots is this variable.
     The art is now neon line art on a near-black field, so the well is dark and matches it. */
  --well: #101a2c;
  --well-edge: #22304a;
  --well-deep: #0b1220;

  /* Apex tier (Q5) shares its red with the core-crystal currency accent. The
     tier colours themselves live in shared/game-data.js as --quality. */
  --apex: #ff5d6b;
  --apex-line: rgba(255, 93, 107, 0.34);
  --apex-bg: rgba(255, 93, 107, 0.10);
  --shadow: 0 14px 34px rgba(0, 0, 0, 0.45);
  --glow-cyan: 0 0 18px rgba(70, 210, 255, 0.28);
  font-family: Inter, "Segoe UI", "Microsoft YaHei UI", sans-serif;
  font-synthesis: none;
}

* { box-sizing: border-box; }
html, body { min-height: 100%; margin: 0; background: var(--canvas); color: var(--ink); }
body { overflow-x: hidden; letter-spacing: 0; }
button, input { font: inherit; letter-spacing: 0; }
button { color: inherit; }
button:focus-visible, input:focus-visible { outline: 3px solid rgba(70, 210, 255, 0.45); outline-offset: 2px; }
.hidden { display: none !important; }
.desktop-only { display: none !important; }

.desktop-titlebar { position: fixed; inset: 0 0 auto; height: 34px; z-index: 1000; background: var(--panel-deep); color: var(--ink); align-items: center; border-bottom: 1px solid var(--line); user-select: none; }
.desktop-mode { padding-top: 34px; }
.desktop-mode .desktop-titlebar { display: flex !important; }
.desktop-mode .desktop-only { display: inline-flex !important; }
.desktop-drag { min-width: 0; flex: 1; height: 100%; display: flex; align-items: center; gap: 8px; padding-left: 11px; -webkit-app-region: drag; }
.desktop-drag b { font-size: 10px; }
.desktop-drag > span:last-child { color: var(--faint); font-size: 9px; border-left: 1px solid var(--line); padding-left: 9px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mini-brand-mark { width: 17px; height: 17px; display: grid; grid-template-columns: repeat(3, 1fr); gap: 2px; align-items: end; transform: skew(-8deg); }
.mini-brand-mark i { background: var(--green); height: 65%; }
.mini-brand-mark i:nth-child(2) { height: 100%; background: var(--line-strong); }
.mini-brand-mark i:nth-child(3) { height: 80%; background: var(--amber); }
.window-controls { height: 100%; display: flex; -webkit-app-region: no-drag; }
.window-controls button { width: 46px; height: 34px; border: 0; background: transparent; color: var(--muted); display: grid; place-items: center; cursor: pointer; }
.window-controls button:hover { background: var(--surface-2); color: #ffffff; }
.window-controls .window-close:hover { background: #bd3e46; }
.window-controls svg { width: 14px; height: 14px; }
.desktop-mode .login-overlay { top: 34px; }
.desktop-mode .topbar { top: 34px; }
.desktop-mode .sidebar { top: 106px; height: calc(100vh - 106px); }
.desktop-mode .ticker { top: 106px; }
.desktop-mode .stat-panel { top: 166px; }

.app-shell { min-height: 100vh; display: grid; grid-template: 72px 1fr / 88px 1fr; }
.topbar { grid-column: 1 / -1; display: flex; align-items: center; gap: 12px; padding: 0 20px; background: var(--surface); border-bottom: 1px solid var(--line); position: sticky; top: 0; z-index: 20; }
.brand { min-width: 236px; display: flex; align-items: center; gap: 11px; }
.brand > span:last-child { display: grid; line-height: 1.05; }
.brand b { font-size: 18px; letter-spacing: 0; }
.brand small { margin-top: 5px; color: var(--muted); font-size: 11px; }
.brand-mark { width: 34px; height: 34px; position: relative; display: inline-grid; grid-template-columns: repeat(3, 1fr); gap: 3px; align-items: end; transform: skew(-10deg); }
.brand-mark i { display: block; background: var(--green); border-radius: 1px; }
.brand-mark i:nth-child(1) { height: 58%; }
.brand-mark i:nth-child(2) { height: 100%; background: var(--ink); }
.brand-mark i:nth-child(3) { height: 76%; background: var(--amber); }
.server-chip { height: 34px; border: 0; border-left: 1px solid var(--line); padding: 0 0 0 18px; background: transparent; display: flex; align-items: center; gap: 8px; font-size: 11px; color: var(--muted); cursor: pointer; }
.server-chip b { color: var(--green-dark); }
.live-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--green); box-shadow: 0 0 0 4px rgba(53, 214, 155, 0.18); flex: 0 0 auto; }
.live-dot.offline { background: var(--red); box-shadow: 0 0 0 4px rgba(255, 93, 107, 0.18); }
.top-spacer { flex: 1; }
.resource-pill { height: 46px; min-width: 120px; padding: 0 13px; border: 1px solid var(--line); background: var(--surface-2); border-radius: 6px; display: flex; align-items: center; gap: 9px; text-align: left; }
button.resource-pill { cursor: pointer; }
.resource-pill svg { width: 20px; color: var(--green); }
.resource-pill.cores svg { color: var(--apex); }
.resource-pill.cores { border-color: var(--apex-line); background: var(--apex-bg); }
.resource-pill.credits svg { color: var(--amber); }
.resource-pill.research svg { color: var(--cyan); }
.resource-pill span { display: grid; min-width: 0; }
.resource-pill small { color: var(--muted); font-size: 9px; text-transform: uppercase; }
.resource-pill b { font-size: 14px; white-space: nowrap; }

.icon-button { width: 38px; height: 38px; padding: 0; border: 1px solid var(--line); background: var(--surface); border-radius: 5px; display: inline-grid; place-items: center; cursor: pointer; }
.icon-button svg { width: 18px; }
.icon-button:hover { border-color: var(--green); color: var(--green); }
.user-button { margin-left: 2px; }

.sidebar { grid-row: 2; background: var(--ink); color: var(--ink); display: flex; flex-direction: column; align-items: stretch; position: sticky; top: 72px; height: calc(100vh - 72px); z-index: 10; }
.sidebar nav { display: grid; gap: 4px; padding: 13px 8px; }
.sidebar button { border: 0; background: transparent; color: inherit; height: 64px; border-radius: 5px; display: grid; place-items: center; align-content: center; gap: 5px; cursor: pointer; font-size: 10px; }
.sidebar button svg { width: 21px; height: 21px; }
.sidebar button:hover { background: var(--surface-2); color: #ffffff; }
.sidebar button.active { background: var(--green); color: #ffffff; }
.sidebar-info { margin: auto 8px 12px; }

.main-stage { grid-column: 2; min-width: 0; }
.ticker { min-height: 43px; padding: 0 24px; background: var(--surface-2); border-bottom: 1px solid var(--line); display: flex; align-items: center; gap: 12px; font-size: 12px; position: sticky; top: 72px; z-index: 9; }
.ticker-label { color: var(--green-dark); display: flex; align-items: center; gap: 6px; font-weight: 700; text-transform: uppercase; }
.ticker-label svg { width: 16px; }
.ticker b { font-size: 13px; }
.ticker span { color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ticker time { margin-left: auto; font-variant-numeric: tabular-nums; font-weight: 700; color: var(--green-dark); }
.view { padding: 24px; max-width: 1600px; margin: 0 auto; }

.page-head { display: flex; align-items: end; gap: 16px; margin-bottom: 20px; }
.page-head > div:first-child { flex: 1; }
.eyebrow { color: var(--green-dark); text-transform: uppercase; font-size: 10px; font-weight: 800; }
.page-head h1 { font-size: 25px; margin: 4px 0 3px; line-height: 1.2; }
.page-head p { color: var(--muted); font-size: 13px; margin: 0; }
.head-actions { display: flex; gap: 8px; }

.primary, .secondary, .ghost, .danger { border: 1px solid transparent; min-height: 38px; padding: 0 14px; border-radius: 5px; display: inline-flex; align-items: center; justify-content: center; gap: 7px; cursor: pointer; font-weight: 700; font-size: 12px; }
.primary { background: var(--green); color: #ffffff; }
.primary:hover { background: var(--green-dark); }
.secondary { background: var(--surface); color: var(--ink); border-color: var(--line); }
.secondary:hover { border-color: var(--green); color: var(--green-dark); }
.ghost { background: transparent; border-color: var(--line); }
.danger { background: var(--surface); color: var(--red); border-color: #e9c4c4; }
.large { min-height: 47px; font-size: 13px; }
.full { width: 100%; }
button:disabled { opacity: 0.45; cursor: not-allowed; }
button svg { width: 16px; height: 16px; }

.world-band { background: var(--ink); color: #ffffff; min-height: 132px; border-radius: 6px; padding: 22px 24px; display: grid; grid-template-columns: 1.35fr repeat(3, minmax(120px, 0.55fr)); gap: 20px; align-items: center; box-shadow: var(--shadow); overflow: hidden; position: relative; }
.world-band::after { content: ""; position: absolute; right: -30px; top: -30px; width: 190px; height: 190px; border: 1px solid #39504a; transform: rotate(28deg); }
.world-primary { position: relative; z-index: 1; }
.world-primary small { color: #88aa9f; font-size: 10px; font-weight: 800; }
.world-primary b { display: block; font-size: 32px; margin: 5px 0 8px; font-variant-numeric: tabular-nums; }
.world-primary span { color: #9eaeaa; font-size: 12px; }
.world-metric { border-left: 1px solid #34423f; padding-left: 20px; position: relative; z-index: 1; }
.world-metric small { display: block; color: #8da09a; font-size: 10px; margin-bottom: 7px; }
.world-metric b { font-size: 20px; font-variant-numeric: tabular-nums; }
.world-metric em { color: #7bd7ad; font-size: 10px; font-style: normal; display: block; margin-top: 5px; }

.overview-layout { display: grid; grid-template-columns: minmax(0, 1fr) 330px; gap: 20px; margin-top: 20px; }
.section-head { display: flex; align-items: center; gap: 10px; margin: 0 0 11px; }
.section-head h2 { font-size: 15px; margin: 0; }
.section-head span { color: var(--muted); font-size: 11px; }
.section-head .spacer { flex: 1; }
.rig-grid { display: grid; grid-template-columns: repeat(2, minmax(260px, 1fr)); gap: 13px; }
.rig-card { background: var(--surface); border: 1px solid var(--line); border-radius: 6px; padding: 15px; min-height: 335px; box-shadow: 0 6px 16px rgba(26, 42, 38, 0.055); display: flex; flex-direction: column; }
.rig-card:hover { border-color: #aabdb6; }
.rig-card-head { display: flex; align-items: start; gap: 8px; }
.rig-card-head > div { min-width: 0; flex: 1; }
.rig-card-head h3 { font-size: 14px; margin: 0; overflow: hidden; text-overflow: ellipsis; }
.rig-card-head p { color: var(--muted); font-size: 10px; margin: 4px 0 0; }
.status-tag { color: var(--green-dark); background: var(--mint); font-size: 9px; font-weight: 800; padding: 4px 6px; border-radius: 3px; }
.rig-visual { --chassis-color: var(--green); height: 196px; margin: 13px auto 11px; width: 196px; background: #25302e; border: 5px solid #111817; border-right-width: 14px; box-shadow: 8px 9px 0 #cad3d0; position: relative; display: grid; grid-template-columns: 36px 1fr; padding: 11px 9px; gap: 7px; overflow: hidden; }
.rig-visual::before { content: ""; position: absolute; inset: 5px; border: 1px solid #4b5c57; }
.rig-fans { display: grid; gap: 5px; position: relative; z-index: 1; }
.fan { width: 31px; aspect-ratio: 1; border: 4px solid #3b4a46; border-radius: 50%; background: #101716; position: relative; animation: spinFan 1.8s linear infinite, fanGlow 2.2s ease-in-out infinite; }
.fan::before, .fan::after { content: ""; position: absolute; inset: 7px 2px; border-radius: 50%; background: var(--chassis-color); transform: rotate(45deg); }
.fan::after { transform: rotate(-45deg); }
.rig-board { border: 1px solid #455752; background: #18221f; position: relative; z-index: 1; }
.rig-board::before { content: ""; position: absolute; left: 9px; right: 9px; top: 15px; height: 33px; border: 4px solid var(--chassis-color); background: #232c29; }
.rig-board::after { content: ""; position: absolute; left: 7px; right: 7px; bottom: 14px; height: 8px; background: var(--chassis-color); box-shadow: 0 -14px 0 #61716c, 0 -28px 0 #3f504b; }
.chassis-light { position: absolute; right: 2px; top: 12px; bottom: 12px; width: 3px; background: var(--chassis-color); box-shadow: 0 0 8px var(--chassis-color); animation: chassisLight 1.8s ease-in-out infinite; z-index: 2; }
.chassis-scan { position: absolute; left: 5px; right: 5px; top: 5px; height: 2px; background: var(--chassis-color); box-shadow: 0 0 9px var(--chassis-color); opacity: 0.48; animation: chassisScan 2.8s linear infinite; z-index: 2; pointer-events: none; }
.chassis-q1 .chassis-light, .chassis-q1 .chassis-scan { opacity: 0.28; }
.chassis-q2 .fan { animation-duration: 1.55s, 2s; }
.chassis-q3 .fan { animation-duration: 1.25s, 1.8s; }
.chassis-q4 .fan { animation-duration: 1s, 1.5s; }
.chassis-q5 .fan { animation-duration: .78s, 1.2s; }
.chassis-q4 .chassis-light, .chassis-q5 .chassis-light { width: 4px; }
@keyframes spinFan { to { transform: rotate(360deg); } }
@keyframes fanGlow { 50% { box-shadow: 0 0 12px var(--chassis-color); } }
@keyframes chassisLight { 50% { opacity: 0.35; } }
@keyframes chassisScan { from { transform: translateY(0); } to { transform: translateY(128px); } }
.rig-stat-row { display: grid; grid-template-columns: 1fr 1fr; gap: 9px; border-top: 1px solid var(--line); padding-top: 11px; }
.rig-stat-row span { display: grid; gap: 2px; }
.rig-stat-row small { color: var(--muted); font-size: 9px; }
.rig-stat-row b { font-size: 13px; }
.meter { height: 5px; background: var(--panel-deep); overflow: hidden; margin-top: 5px; }
.meter i { display: block; height: 100%; background: var(--green); }
.meter.hot i { background: var(--red); }
.oc-row { margin-top: auto; padding-top: 12px; display: grid; grid-template-columns: auto 1fr auto; gap: 8px; align-items: center; font-size: 10px; color: var(--muted); }
.oc-row input { width: 100%; accent-color: var(--green); }
.empty-rig { border: 1px dashed var(--muted); min-height: 335px; background: rgba(70, 210, 255, 0.05); border-radius: 6px; display: grid; place-items: center; text-align: center; color: var(--muted); }
.empty-rig button { margin-top: 10px; }

.overview-rail { min-width: 0; }
.rail-block { border-top: 3px solid var(--ink); background: var(--surface); margin-bottom: 16px; }
.rail-title { padding: 12px 14px; display: flex; align-items: center; gap: 7px; border-bottom: 1px solid var(--line); }
.rail-title h2 { font-size: 13px; margin: 0; flex: 1; }
.rail-title span { color: var(--muted); font-size: 10px; }
.task-list { display: grid; }
.task-row { padding: 12px 14px; border-bottom: 1px solid var(--line); display: grid; grid-template-columns: 1fr auto; gap: 10px; }
.task-row:last-child { border-bottom: 0; }
.task-row b { font-size: 12px; }
.task-row p { color: var(--muted); margin: 3px 0 7px; font-size: 10px; }
.task-reward { font-size: 9px; color: var(--amber); font-weight: 700; }
.task-row button { width: 32px; height: 32px; border-radius: 4px; border: 1px solid var(--line); background: var(--surface); display: grid; place-items: center; align-self: center; cursor: pointer; }
.task-row button.ready { background: var(--green); color: #ffffff; border-color: var(--green); }

/* Achievements: read-only milestone list, rewards are paid automatically. */
.achievement-summary { padding: 10px 14px 0; display: grid; gap: 5px; }
.achievement-summary small { color: var(--muted); font-size: 9px; }
.achievement-list { display: grid; max-height: 320px; overflow-y: auto; }
.achievement-row { padding: 10px 14px; border-bottom: 1px solid var(--line); display: grid; grid-template-columns: auto 1fr auto; gap: 9px; align-items: start; }
.achievement-row:last-child { border-bottom: 0; }
.achievement-row.locked { opacity: .62; }
.achievement-mark { width: 22px; height: 22px; border-radius: 3px; border: 1px solid var(--line); background: var(--surface-2); display: grid; place-items: center; color: var(--muted); }
.achievement-mark svg { width: 13px; }
.achievement-row.unlocked .achievement-mark { color: #ffffff; background: var(--amber); border-color: var(--amber); }
.achievement-body { display: grid; gap: 3px; min-width: 0; }
.achievement-body b { font-size: 11px; }
.achievement-body p { color: var(--muted); margin: 0; font-size: 9px; }
.achievement-body small { color: var(--muted); font-size: 9px; }
.achievement-progress { height: 3px; background: var(--panel-deep); overflow: hidden; }
.achievement-progress i { display: block; height: 100%; background: var(--green); }
.achievement-row.unlocked .achievement-progress i { background: var(--amber); }
.achievement-reward { font-style: normal; font-size: 9px; font-weight: 700; color: var(--amber); white-space: nowrap; }
.toast.achievement { border-left-color: var(--amber); background: linear-gradient(90deg, color-mix(in srgb, var(--amber) 22%, var(--ink)), var(--ink)); }

/* Overview digest: headline progress plus a link into the full page. */
.achievement-digest-actions { padding: 11px 14px 13px; }
.achievement-digest-actions .full { width: 100%; }

/* Dedicated achievements page */
.achievement-overview { display: grid; grid-template-columns: minmax(200px, 1.4fr) repeat(3, minmax(150px, 1fr)); gap: 12px; margin-bottom: 16px; }
.achievement-overview-main { padding: 16px 18px; background: var(--ink); color: #ffffff; border-radius: 4px; display: grid; gap: 7px; }
.achievement-overview-main small { color: var(--muted); font-size: 9px; letter-spacing: .08em; }
.achievement-overview-main b { font-size: 30px; line-height: 1; }
.achievement-overview-main .meter { background: rgba(255, 255, 255, .18); margin-top: 2px; }
.achievement-overview-main .meter i { background: var(--amber); }
.achievement-overview-stat { padding: 16px 18px; background: var(--surface); border: 1px solid var(--line); border-radius: 4px; display: grid; gap: 6px; align-content: start; }
.achievement-overview-stat small { color: var(--muted); font-size: 9px; }
.achievement-overview-stat b { font-size: 19px; line-height: 1.1; }
.achievement-overview-stat em { color: var(--muted); font-style: normal; font-size: 9px; }

.achievement-grid { display: grid; grid-template-columns: repeat(3, minmax(240px, 1fr)); gap: 12px; }
.achievement-card { background: var(--surface); border: 1px solid var(--line); border-left: 4px solid var(--line); border-radius: 4px; padding: 14px; display: grid; gap: 9px; align-content: start; }
.achievement-card.unlocked { border-left-color: var(--amber); background: linear-gradient(180deg, color-mix(in srgb, var(--amber) 7%, #fff), #fff 46%); }
.achievement-card.locked { opacity: .88; }
.achievement-card header { display: grid; grid-template-columns: auto 1fr auto; gap: 10px; align-items: center; }
.achievement-card-mark { width: 30px; height: 30px; border-radius: 4px; border: 1px solid var(--line); background: var(--surface-2); display: grid; place-items: center; color: var(--muted); }
.achievement-card-mark svg { width: 16px; }
.achievement-card.unlocked .achievement-card-mark { background: var(--amber); border-color: var(--amber); color: #ffffff; }
.achievement-card header small { color: var(--muted); font-size: 9px; }
.achievement-card h3 { font-size: 13px; margin: 2px 0 0; }
.achievement-card header em { font-style: normal; font-size: 11px; font-weight: 700; color: var(--amber); white-space: nowrap; }
.achievement-card p { color: var(--muted); font-size: 10px; margin: 0; min-height: 26px; }
.achievement-card footer { display: flex; justify-content: space-between; gap: 8px; color: var(--muted); font-size: 9px; }
.achievement-card.unlocked footer time { color: var(--amber); font-weight: 700; }

/* Generated enamel badges. Locked categories are shown as a dimmed silhouette so
   the earned ones stand out without needing a second set of artwork. */
.achievement-badge { width: 34px; height: 34px; flex: 0 0 auto; display: grid; place-items: center; }
.achievement-badge img { width: 100%; height: 100%; object-fit: contain; }
.achievement-badge.locked img { filter: grayscale(1) brightness(1.5) opacity(.42); }
.achievement-badge.unlocked img { filter: drop-shadow(0 2px 4px color-mix(in srgb, var(--amber) 35%, transparent)); }
/* Slightly larger in the card header, where it replaces the old icon square. */
.achievement-card header .achievement-badge { width: 30px; height: 30px; }
.achievement-digest-badges { display: flex; gap: 7px; padding: 10px 14px 0; flex-wrap: wrap; }
.achievement-digest-badges .achievement-badge { width: 26px; height: 26px; }
.chat-list { height: 210px; overflow-y: auto; padding: 10px 13px; display: grid; align-content: start; gap: 9px; }
.chat-message { font-size: 11px; line-height: 1.35; word-break: break-word; }
.chat-message b { color: var(--green-dark); margin-right: 5px; }
.chat-message.system { color: var(--muted); border-left: 2px solid var(--amber); padding-left: 7px; }
.chat-form { display: grid; grid-template-columns: 1fr 36px; border-top: 1px solid var(--line); padding: 9px; gap: 7px; }
.chat-form input { min-width: 0; border: 1px solid var(--line); background: var(--panel-deep); padding: 0 9px; border-radius: 4px; font-size: 11px; }
.chat-form button { width: 36px; height: 34px; border: 0; background: var(--ink); color: #ffffff; border-radius: 4px; cursor: pointer; }

.toolbar { display: flex; align-items: center; gap: 9px; margin-bottom: 16px; flex-wrap: wrap; }
.search-box { min-width: 230px; flex: 1; max-width: 420px; position: relative; }
.search-box svg { position: absolute; width: 16px; left: 11px; top: 11px; color: var(--muted); }
.search-box input { width: 100%; height: 39px; border: 1px solid var(--line); background: var(--surface); border-radius: 5px; padding: 0 12px 0 35px; }
.segmented { display: inline-flex; border: 1px solid var(--line); background: var(--surface); border-radius: 5px; overflow: hidden; }
.segmented button { min-height: 36px; padding: 0 12px; border: 0; border-right: 1px solid var(--line); background: transparent; cursor: pointer; font-size: 11px; }
.segmented button:last-child { border-right: 0; }
.segmented button.active { background: var(--ink); color: #ffffff; }
.market-note { margin-left: auto; font-size: 11px; color: var(--muted); }
.market-note b { color: var(--ink); }
/* Three columns rather than four.
   The artwork is square, so a four-column card is wide and short and the image ends up
   limited by height - it drew at 130px inside a 292px card, which reads as a small picture
   floating in a lot of empty space. Fewer, taller cards let the square fill its frame and
   the hardware is actually visible. */
.part-grid { display: grid; grid-template-columns: repeat(3, minmax(220px, 1fr)); gap: 12px; }
/* Part card: artwork on the left, details on the right.
   The artwork is square, so in a wide-and-short stacked card it was limited by height and
   drew at a third of the available width, leaving most of the card empty. Laying the card
   out as two columns gives the square a fixed, meaningful size without making the card tall:
   with the image at 172px the drawing fills its frame and the hardware is legible. */
.part-card { background: var(--surface); border: 1px solid var(--line); border-radius: 6px; padding: 14px; min-width: 0; display: grid; grid-template-columns: auto minmax(0, 1fr); grid-template-areas: "art top" "art name" "art specs" "art bottom"; grid-template-rows: auto auto auto 1fr; column-gap: 14px; align-content: start; min-height: 230px; }
.part-card > .product-visual { grid-area: art; width: 172px; height: 172px; margin: 0; align-self: start; }
.part-card > .part-top { grid-area: top; }
.part-card > h3 { grid-area: name; }
.part-card > .spec-row { grid-area: specs; }
.part-card > .part-bottom { grid-area: bottom; align-self: end; }

/* The Steam panel lists the same cards but only the apex tier, and a single column of wide
   cards left the artwork small again, so it keeps the two-column form at a larger size. */
.part-card.part-chassis > .product-visual { width: 172px; height: 172px; }

/* Narrow screens cannot afford two columns inside a card, so it stacks again and the
   artwork returns to a full-width banner. */
@media (max-width: 900px) {
  .part-card { grid-template-columns: minmax(0, 1fr); grid-template-areas: "art" "top" "name" "specs" "bottom"; }
  .part-card > .product-visual { width: auto; height: 180px; margin: 0 0 9px; }
}
.part-card.locked { opacity: 0.62; }
/* Base artwork box, used by the market and inventory cards.
   The artwork is square and fitted with object-fit: contain, so the visible size is limited
   by whichever dimension is smaller. At 92px tall inside a ~292px wide card the image was
   capped by height and drew at 72px, occupying 26% of the width - the "only a third is
   showing" report. The height is set so the square fills most of the card instead. */
.product-visual { position: relative; height: 150px; margin: 0 0 9px; display: grid; place-items: center; overflow: hidden; background: var(--well); border: 1px solid var(--line); border-radius: 4px; }
.product-visual::before { content: ""; position: absolute; inset: 0; background: linear-gradient(135deg, transparent 48%, color-mix(in srgb, var(--quality) 8%, transparent) 49%, transparent 51%); pointer-events: none; }
.product-visual img { width: 100%; height: 100%; padding: 8px; object-fit: contain; position: relative; z-index: 1; }
/* Artwork fades in once decoded. The image must NOT start with the `hidden`
   attribute: IntersectionObserver never reports a display:none element, so a hidden
   image is never lazily loaded and never revealed, and the generated art silently
   never appears on any screen. */
.product-visual img { opacity: 0; transition: opacity .28s ease; }
.product-visual img.is-ready { opacity: 1; }
/* Artwork that was already decoded skips the fade. The world state is pushed every second
   and each push rebuilds these elements, so without this the fade replayed on every tick
   and the art appeared to blink continuously. */
.product-visual img.no-fade { transition: none; }
.chassis-product-visual { background: linear-gradient(135deg, var(--well-deep), var(--surface-2) 52%, var(--well-deep)); border-color: color-mix(in srgb, var(--quality) 48%, var(--line-strong)); }
.chassis-product-visual::before { background: linear-gradient(110deg, transparent 34%, color-mix(in srgb, var(--quality) 16%, transparent) 50%, transparent 66%); background-size: 220% 100%; animation: chassisImageSweep 5s linear infinite; }
.chassis-product-visual img { padding: 5px; filter: drop-shadow(0 4px 8px rgba(0, 0, 0, .35)); animation: chassisProductFloat 4.8s ease-in-out infinite; }
.chassis-product-visual.has-image img { object-fit: contain; }
/* Animated WebP chassis art carries its own motion; the drifting/sweeping CSS
   below would fight it, so keep the frame still and only keep the drop shadow. */
.chassis-product-visual.has-animation { animation: none; }
.chassis-product-visual.has-animation::before { animation: none; }
/* Steam-only login: one primary action plus an optional guest session. */
.login-note { margin: 0 0 14px; color: var(--muted); font-size: 11px; line-height: 1.6; }
.steam-login { display: grid; gap: 8px; margin-bottom: 6px; }
.steam-button {
  min-height: 46px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  border: 1px solid var(--line-strong);
  border-radius: 5px;
  /* Steam's own blue, so the button reads as "this is Steam". */
  background: linear-gradient(180deg, #1b6c9e, #12405f);
  color: #eaf6ff;
  font-weight: 800;
  font-size: 13px;
  cursor: pointer;
}
.steam-button:hover { background: linear-gradient(180deg, #2382bd, #16506f); }
.steam-button:disabled { opacity: .55; cursor: not-allowed; }
.steam-button svg { width: 17px; }
.steam-login .guest-button { width: 100%; }

/* Steam market panel: the market lives on Steam, so this states the rules and hands
   items over instead of rendering listings. */
.steam-market-panel {
  border: 1px solid var(--line);
  border-radius: 5px;
  padding: 16px 18px;
  margin-bottom: 16px;
  background: linear-gradient(180deg, var(--surface-2), var(--panel-deep));
}
.steam-market-head { display: flex; align-items: start; gap: 11px; margin-bottom: 10px; }
.steam-market-head svg { width: 22px; color: var(--cyan); flex: 0 0 auto; margin-top: 2px; }
.steam-market-head h2 { margin: 0 0 4px; font-size: 15px; }
.steam-market-head p { margin: 0; color: var(--muted); font-size: 11px; line-height: 1.6; }
.steam-market-rules { margin: 10px 0 0; padding-left: 18px; color: var(--muted); font-size: 10px; line-height: 1.8; }
/* AIC deposit: the currency becomes Steam items, whole units only. */
.steam-aic {
  margin-top: 14px;
  padding: 12px 14px;
  border: 1px solid var(--line-strong);
  border-left: 3px solid var(--cyan);
  border-radius: 4px;
  background: var(--panel-deep);
}
.steam-aic-copy { display: flex; align-items: start; gap: 10px; margin-bottom: 11px; }
.steam-aic-copy svg { width: 19px; color: var(--cyan); flex: 0 0 auto; margin-top: 2px; }
.steam-aic-copy h3 { margin: 0 0 3px; font-size: 13px; }
.steam-aic-copy p { margin: 0; color: var(--muted); font-size: 10px; line-height: 1.6; }
.steam-aic-form { display: flex; align-items: end; gap: 10px; flex-wrap: wrap; }
.steam-aic-form .field-label { margin: 0; display: grid; gap: 6px; }
.steam-aic-form input { width: 130px; height: 36px; }
.steam-aic-available { margin-right: auto; color: var(--muted); font-size: 10px; }
.steam-aic-available b { color: var(--ink); }
.steam-aic-warn { margin: 9px 0 0; color: var(--amber); font-size: 10px; }
.steam-market-owned { margin-top: 14px; border-top: 1px solid var(--line); padding-top: 12px; }
.steam-market-owned h3 { margin: 0 0 8px; font-size: 12px; }
.steam-item-list { display: grid; gap: 6px; margin: 0; padding: 0; list-style: none; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); }
.steam-item-list li { display: grid; gap: 2px; padding: 8px 10px; border: 1px solid var(--line); border-radius: 4px; background: var(--panel-deep); }
.steam-item-list b { font-size: 11px; }
.steam-item-list small { color: var(--faint); font-size: 9px; }

/* Core exchange: the sink that makes a recharge worth something. Kept visually separate from
   the purchase packages so it reads as "use what you have", not "buy more". */
.core-exchange { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line); }
.core-exchange h3 { margin: 0 0 5px; font-size: 13px; }
.core-exchange .settings-hint { margin: 0 0 10px; }
.core-exchange-row { display: flex; align-items: flex-end; gap: 9px; }
.core-exchange-row .field-label { flex: 1 1 auto; min-width: 0; margin: 0; }
.core-exchange #coreExchangePreview:empty { display: none; }
.core-exchange #coreExchangePreview { margin: 8px 0 0; }

/* Check-in: a month grid of day cells. Seven columns so a month reads as a calendar block rather
   than a long list, which makes gaps (missed days) immediately visible. */
.checkin-modal { max-width: 460px; }
.checkin-calendar {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 5px;
  margin: 12px 0 14px;
}
.checkin-day {
  display: grid;
  place-items: center;
  aspect-ratio: 1;
  min-height: 34px;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: var(--surface-2);
  font-size: 11px;
  color: var(--muted);
}
.checkin-day svg { width: 14px; height: 14px; }
.checkin-day.future { opacity: 0.45; }
.checkin-day.claimed {
  color: var(--green);
  border-color: color-mix(in srgb, var(--green) 55%, var(--line));
  background: color-mix(in srgb, var(--green) 14%, var(--surface-2));
}
.checkin-day.today { border-color: var(--cyan); color: var(--cyan); font-weight: 700; }
.checkin-day.available {
  border-color: var(--amber);
  color: var(--amber);
  background: color-mix(in srgb, var(--amber) 16%, var(--surface-2));
}
.checkin-foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.checkin-reward { display: flex; align-items: center; gap: 6px; font-size: 11px; color: var(--ink); }
.checkin-reward svg { width: 15px; height: 15px; color: var(--amber); }
.checkin-modal #checkinBonusNote { margin: 10px 0 0; }

/* A small badge on the nav entry, the only prompt to open the panel. */
.nav-badge {
  position: absolute;
  top: 6px;
  right: 8px;
  min-width: 14px;
  height: 14px;
  padding: 0 3px;
  border-radius: 7px;
  background: var(--amber);
  color: #10141c;
  font-size: 9px;
  line-height: 14px;
  text-align: center;
  font-weight: 700;
}
#mainNav button { position: relative; }

/* Settings dialog: language, server and provenance in one place. */
.settings-modal { max-width: 520px; }
.settings-section { padding: 14px 18px; border-bottom: 1px solid var(--line); }
.settings-section:last-child { border-bottom: 0; }
.settings-section h3 { margin: 0 0 5px; font-size: 13px; }
.settings-hint { margin: 0 0 11px; color: var(--muted); font-size: 10px; line-height: 1.6; }
.language-options { display: grid; gap: 7px; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
.language-option {
  position: relative;
  display: grid;
  gap: 3px;
  padding: 10px 12px;
  text-align: left;
  cursor: pointer;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: var(--surface-2);
  color: var(--ink);
}
.language-option:hover { border-color: var(--cyan); }
.language-option.active { border-color: var(--cyan); background: var(--cyan-soft); }
.language-option b { font-size: 12px; }
.language-option small { color: var(--muted); font-size: 9px; }
/* The tick marks the chosen language without shifting the label. */
.language-option svg { position: absolute; right: 9px; top: 50%; width: 15px; margin-top: -7px; color: var(--cyan); }
.settings-modal .server-url-field { margin: 0 0 8px; }
.settings-modal .client-update-row { margin-top: 12px; }
.settings-modal .modal-actions { margin-top: 12px; }

/* Compact artwork variants: the same generated render at the sizes the assembly
   screen, its picker and the installed-part chips need.
   
   These were sized for the old studio photographs, which read acceptably as a small dark
   thumbnail inside a light plate. The neon line art is detailed enough that a 54px box
   collapsed it into an unreadable smudge, and because the art is square and fitted with
   object-fit: contain, a short box limits the image by HEIGHT - so it occupied only a
   quarter of the card's width and left the rest empty. The heights below give the square a
   useful size while keeping the rows readable. */
.product-visual-thumb { height: 120px; margin: 0 0 8px; }
.product-visual-thumb img { padding: 6px; }
.product-visual-thumb .part-icon { width: 40px; height: 40px; }
.product-visual-thumb .part-icon svg { width: 22px; }
.product-visual-slot { height: 46px; margin: 0; width: 46px; flex: 0 0 auto; }
.product-visual-slot img { padding: 3px; }
.product-visual-slot .part-icon { width: 26px; height: 26px; }
.product-visual-slot .part-icon svg { width: 14px; }
.product-visual-slot.is-empty { display: grid; place-items: center; color: var(--green-dark); background: var(--surface-2); border-color: var(--line); }
.product-visual-slot.is-empty svg { width: 18px; }
.product-visual-slot.is-empty .part-icon { display: none; }
.product-visual-chip { display: inline-grid; width: 16px; height: 16px; margin: 0 4px 0 0; vertical-align: -3px; background: none; border: 0; }
.product-visual-chip img { padding: 0; }
.product-visual-chip .part-icon { display: none; }
/* The picker layout is defined above, next to .inventory-options; the older row-based rules
   that lived here have been removed rather than left to override it. */
.gpu-chip .product-visual-chip { display: inline-grid; }
.build-slot { grid-template-columns: 40px minmax(0, 1fr) auto; }
/* Machine card: the chassis artwork fills the frame.
   The card used to draw its own chassis in CSS - a scanline, fan discs, a board and a power
   light - and show the render behind it at 85% opacity. With the artwork now neon line art
   that produced two overlapping chassis in one frame, which read as a muddy double image.
   When a render exists the drawing steps aside entirely and the art stands alone; the CSS
   chassis remains the fallback for a machine whose chassis has no render. */
.rig-visual .product-visual-rig { position: absolute; inset: 0; z-index: 0; margin: 0; padding: 0; background: none; border: 0; border-radius: 0; width: auto; height: auto; }
.rig-visual .product-visual-rig img { padding: 0; object-fit: contain; opacity: 1; }
.rig-visual .product-visual-rig .part-icon { width: 34px; height: 34px; }
.rig-visual .product-visual-rig .product-image-source { display: none; }
.rig-visual:has(.product-visual-rig.has-image) .rig-board,
.rig-visual:has(.product-visual-rig.has-image) .rig-fans,
.rig-visual:has(.product-visual-rig.has-image) .chassis-scan,
.rig-visual:has(.product-visual-rig.has-image) .chassis-light { display: none; }
/* The frame and its offset block are part of the drawn chassis. Once the art is shown they
   only add a pale rectangle behind it - the light grey `box-shadow` is the band that was
   visible along the right and bottom of every machine card. */
.rig-visual:has(.product-visual-rig.has-image) { background: var(--well-deep); border: 1px solid var(--line-strong); box-shadow: none; padding: 0; }
.rig-visual:has(.product-visual-rig.has-image)::before { display: none; }
.chassis-product-visual.has-animation img { animation: none; padding: 2px; }.chassis-product-visual.has-animation .part-icon { animation: none; }
.chassis-product-visual .part-icon { color: var(--quality); border-color: color-mix(in srgb, var(--quality) 58%, var(--line-strong)); background: rgba(14, 22, 20, .84); box-shadow: 0 0 12px color-mix(in srgb, var(--quality) 35%, transparent); animation: chassisPartGlow 2s ease-in-out infinite; }
.product-visual .part-icon { width: 46px; height: 46px; position: absolute; z-index: 1; color: var(--quality); border-color: color-mix(in srgb, var(--quality) 48%, var(--line)); background: color-mix(in srgb, var(--quality) 7%, var(--surface-2)); }
.product-visual .part-icon svg { width: 25px; }
.product-visual.has-image .part-icon { display: none; }
.product-image-source { position: absolute; z-index: 2; right: 5px; bottom: 5px; padding: 3px 5px; color: #ffffff; background: rgba(16, 24, 22, .76); border-radius: 2px; font-size: 8px; text-decoration: none; }
.product-image-source:hover { background: var(--panel-deep); }
.part-top { display: flex; align-items: center; gap: 9px; }
.part-icon { width: 36px; height: 36px; border: 1px solid var(--line); background: var(--surface-2); display: grid; place-items: center; color: var(--green-dark); border-radius: 4px; flex: 0 0 auto; }
.part-icon svg { width: 19px; }
.part-tier { margin-left: auto; color: var(--amber); font-size: 9px; font-weight: 800; }
.quality-badge { margin-left: auto; border: 1px solid var(--quality); color: var(--quality); background: color-mix(in srgb, var(--quality) 8%, var(--surface-2)); font-size: 8px; font-weight: 800; padding: 4px 6px; border-radius: 3px; white-space: nowrap; }
.part-card h3 { font-size: 13px; margin: 12px 0 4px; min-height: 32px; line-height: 1.25; word-break: break-word; }
.part-brand { color: var(--muted); font-size: 10px; }
.spec-row { margin: 12px 0; padding: 9px 0; border-block: 1px solid var(--line); display: grid; grid-template-columns: repeat(3, 1fr); gap: 5px; }
.spec-row span { display: grid; font-size: 10px; }
.spec-row small { color: var(--muted); font-size: 8px; margin-bottom: 3px; }
.part-bottom { display: flex; align-items: center; gap: 8px; margin-top: auto; }
.part-price { flex: 1; }
.part-price b { display: block; font-size: 15px; }
.part-price small { color: var(--muted); font-size: 9px; }
.price-up { color: var(--red); }
.price-down { color: var(--green-dark); }
.part-bottom button { min-width: 68px; }
.market-mode-switch { display: flex; align-items: center; gap: 4px; border-bottom: 1px solid var(--line); margin-bottom: 16px; }
.market-mode-switch button { min-height: 43px; padding: 0 15px; border: 0; border-bottom: 3px solid transparent; background: transparent; color: var(--muted); font-weight: 700; font-size: 11px; cursor: pointer; display: inline-flex; align-items: center; gap: 7px; }
.market-mode-switch button.active { border-bottom-color: var(--green); color: var(--ink); }
.market-mode-switch .spacer { flex: 1; }
.merchant-lottery { display: grid; grid-template-columns: minmax(220px, 1fr) minmax(260px, 1.2fr); align-items: center; gap: 18px 22px; padding: 20px 0; border-block: 1px solid var(--line); }
.lottery-copy { display: flex; align-items: center; gap: 13px; min-width: 0; }
.lottery-mark { width: 42px; height: 42px; display: grid; place-items: center; flex: 0 0 auto; color: var(--green-dark); background: var(--mint); border: 1px solid color-mix(in srgb, var(--green) 30%, var(--surface-2)); border-radius: 5px; }
.lottery-mark svg { width: 21px; }
.lottery-copy small { color: var(--muted); font-size: 9px; }
.lottery-copy h2 { margin: 3px 0 4px; font-size: 16px; }
.lottery-copy p { margin: 0; color: var(--muted); font-size: 10px; line-height: 1.5; }
.lottery-odds { display: grid; grid-template-columns: repeat(5, minmax(48px, 1fr)); gap: 5px; }
.lottery-odds span { display: grid; gap: 5px; padding: 8px 6px; border-left: 2px solid var(--line); color: var(--muted); font-size: 9px; text-align: center; }
.lottery-odds span:nth-child(4) { border-left-color: var(--amber); }
.lottery-odds span:nth-child(5) { border-left-color: var(--red); }
.lottery-odds b { color: var(--ink); font-size: 12px; }
.lottery-pity { grid-column: 1 / -1; display: flex; align-items: center; gap: 20px; padding: 10px 12px; color: var(--muted); background: color-mix(in srgb, var(--amber) 8%, var(--surface-2)); border-left: 3px solid var(--amber); font-size: 10px; }
.lottery-pity b { color: var(--ink); }
.lottery-actions { grid-column: 1 / -1; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.lottery-actions > span { margin-right: auto; color: var(--muted); font-size: 10px; }
.lottery-actions > span b { margin-left: 6px; color: var(--ink); font-size: 14px; }
.lottery-actions button { display: inline-flex; align-items: center; gap: 7px; }
.lottery-actions button svg { width: 15px; }
.draw-button { white-space: nowrap; }
.synthesis-panel { display: grid; grid-template-columns: minmax(190px, .65fr) 1.35fr; gap: 16px; align-items: center; margin: 0 0 16px; padding: 14px 0; border-block: 1px solid var(--line); }
.synthesis-panel h3 { margin: 3px 0; font-size: 14px; }
.synthesis-panel p { margin: 0; color: var(--muted); font-size: 10px; line-height: 1.5; }
.synthesis-panel > div:first-child > small { color: var(--muted); font-size: 9px; }
.synthesis-options { display: flex; flex-wrap: wrap; gap: 7px; }
.synthesis-options button { display: grid; grid-template-columns: auto 1fr; align-items: center; gap: 2px 6px; text-align: left; }
.synthesis-options button svg { width: 15px; grid-row: span 2; }
.synthesis-options button small { grid-column: 2; color: var(--muted); font-size: 9px; }
.synthesis-empty { color: var(--muted); font-size: 10px; }
.trade-grid { display: grid; grid-template-columns: repeat(3, minmax(250px, 1fr)); gap: 12px; }
.trade-card { background: var(--surface); border: 1px solid var(--line); border-top: 3px solid var(--apex); border-radius: 5px; padding: 15px; min-width: 0; }
.trade-card.mine { border-top-color: var(--green); }
.trade-card-head { display: flex; align-items: start; gap: 9px; }
.trade-card-head > div { flex: 1; min-width: 0; }
.trade-card h3 { margin: 3px 0 4px; font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.trade-card p { margin: 0; color: var(--muted); font-size: 9px; }
.trade-price { margin: 17px 0 13px; padding-block: 12px; border-block: 1px solid var(--line); display: flex; align-items: end; }
.trade-price span { flex: 1; display: grid; gap: 3px; }
.trade-price small { color: var(--muted); font-size: 8px; }
.trade-price b { font-size: 20px; }
.trade-price em { font-size: 9px; font-style: normal; color: var(--muted); }
.trade-card-actions { display: flex; justify-content: flex-end; }
.aic-listing { border-top-color: var(--green); box-shadow: inset 3px 0 0 rgba(13, 143, 96, 0.22); }
.aic-badge { margin-left: auto; border: 1px solid var(--green); color: var(--green-dark); background: var(--mint); font-size: 8px; font-weight: 800; padding: 4px 6px; border-radius: 3px; }

.quality-card { position: relative; isolation: isolate; overflow: hidden; border-color: color-mix(in srgb, var(--quality) 54%, var(--line)); box-shadow: inset 3px 0 0 var(--quality), 0 0 8px color-mix(in srgb, var(--quality) 14%, transparent); }
.quality-card > * { position: relative; z-index: 1; }
.quality-card::after { content: ""; position: absolute; z-index: 0; left: -18%; top: 0; width: 18%; height: 2px; background: var(--quality); box-shadow: 0 0 11px var(--quality); opacity: .18; pointer-events: none; }
.quality-card .part-icon { border-color: color-mix(in srgb, var(--quality) 72%, var(--surface-2)); color: var(--quality); box-shadow: 0 0 8px color-mix(in srgb, var(--quality) 22%, transparent); }
.quality-card .quality-badge { filter: drop-shadow(0 0 4px color-mix(in srgb, var(--quality) 28%, transparent)); }
.quality-q1 { box-shadow: inset 3px 0 0 var(--quality), 0 0 7px color-mix(in srgb, var(--quality) 14%, transparent); }
.quality-q1::after { opacity: .2; animation: qualityScan 7s linear infinite; }
.quality-q2 { box-shadow: inset 3px 0 0 var(--quality), 0 4px 12px color-mix(in srgb, var(--quality) 15%, transparent); }
.quality-q2::after { opacity: .28; animation: qualityScan 6s linear infinite; }
.quality-q3::after { opacity: .42; animation: qualityScan 4.8s linear infinite; }
.quality-q4 { animation: qualityPulse 2.8s ease-in-out infinite; }
.quality-q4::after { opacity: .56; animation: qualityScan 3.6s linear infinite; }
.quality-q5 { animation: qualityPulse 1.9s ease-in-out infinite; }
.quality-q5::after { opacity: .76; height: 3px; animation: qualityScan 2.6s linear infinite; }
.part-chassis .part-icon { border-color: var(--quality); color: var(--quality); animation: chassisPartGlow 1.8s ease-in-out infinite; }
@keyframes qualityScan { from { left: -18%; } to { left: 100%; } }
@keyframes qualityPulse { 50% { box-shadow: inset 3px 0 0 var(--quality), 0 0 15px color-mix(in srgb, var(--quality) 38%, transparent); } }
@keyframes chassisPartGlow { 50% { box-shadow: inset 0 0 8px color-mix(in srgb, var(--quality) 18%, transparent), 0 0 9px color-mix(in srgb, var(--quality) 30%, transparent); } }
@keyframes chassisProductFloat { 0%, 100% { transform: translateY(2px) scale(.98); } 50% { transform: translateY(-2px) scale(1.02); } }
@keyframes chassisImageSweep { from { background-position: 120% 0; } to { background-position: -120% 0; } }

.workshop-layout { display: grid; grid-template-columns: 230px minmax(420px, 1fr) 300px; gap: 16px; align-items: start; }
.machine-list { background: var(--surface); border-top: 3px solid var(--ink); }
.machine-list-head { padding: 13px; border-bottom: 1px solid var(--line); display: flex; align-items: center; }
.machine-list-head b { font-size: 12px; flex: 1; }
.machine-list-head button { width: 30px; height: 30px; }
.machine-list-item { width: 100%; border: 0; border-bottom: 1px solid var(--line); background: var(--surface); padding: 12px 13px; text-align: left; cursor: pointer; display: grid; grid-template-columns: 1fr auto; gap: 4px; }
.machine-list-item.active { background: var(--mint); box-shadow: inset 3px 0 0 var(--green); }
.machine-list-item b { font-size: 11px; overflow: hidden; text-overflow: ellipsis; }
.machine-list-item span { color: var(--muted); font-size: 9px; grid-column: 1; }
.machine-list-item em { grid-row: 1 / 3; grid-column: 2; align-self: center; font-style: normal; font-size: 10px; color: var(--green-dark); }
.build-panel { background: var(--surface); border: 1px solid var(--line); border-radius: 6px; }
.build-name { padding: 13px; border-bottom: 1px solid var(--line); display: flex; gap: 9px; }
.build-name input { flex: 1; min-width: 0; height: 38px; border: 1px solid var(--line); border-radius: 4px; padding: 0 11px; font-weight: 700; }
.build-slots { display: grid; grid-template-columns: repeat(2, 1fr); padding: 12px; gap: 8px; }
.build-slot { min-height: 62px; background: var(--surface-2); border: 1px solid var(--line); border-radius: 4px; padding: 9px; display: grid; grid-template-columns: 32px 1fr auto; gap: 8px; align-items: center; text-align: left; cursor: pointer; }
.build-slot.active { border-color: var(--green); box-shadow: inset 0 0 0 1px var(--green); }
.build-slot > svg { width: 20px; color: var(--green-dark); }
.build-slot.quality-card > svg { color: var(--quality); filter: drop-shadow(0 0 4px var(--quality)); }
.build-slot span { min-width: 0; }
.build-slot small { color: var(--muted); font-size: 8px; display: block; }
.build-slot b { font-size: 10px; display: block; margin-top: 3px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.build-slot em { font-size: 10px; font-style: normal; color: var(--muted); }
.inventory-picker { border-top: 1px solid var(--line); padding: 12px; }
.inventory-picker-head { display: flex; align-items: center; margin-bottom: 9px; }
.inventory-picker-head b { font-size: 11px; flex: 1; }
.inventory-picker-head span { color: var(--muted); font-size: 9px; }
/* The picker is a grid of cards with the artwork above the label, not a list of rows.
   A row put a small square image beside a lot of empty width, so the art drew at a third of
   the space it had. A card per option lets the image fill its frame, which is what makes a
   model recognisable when choosing between them. */
.inventory-options { display: grid; grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); gap: 7px; max-height: 420px; overflow-y: auto; }
.inventory-option { display: grid; grid-template-rows: auto auto auto; gap: 4px; justify-items: stretch; text-align: left; cursor: pointer; min-width: 0; padding: 6px; border: 1px solid var(--line); background: var(--surface); border-radius: 4px; }
.inventory-option:hover { border-color: var(--green); }
.inventory-option:disabled { opacity: 0.45; }
.inventory-option > .product-visual-thumb { margin: 0; width: 100%; height: 118px; }
.inventory-option > b { display: block; min-width: 0; font-size: 10px; line-height: 1.3; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.inventory-option > span { display: flex; flex-direction: column; gap: 1px; font-size: 9px; color: var(--muted); }
.inventory-option > span strong { font-size: 9px; }
.gpu-stack { border-top: 1px solid var(--line); padding: 8px 12px; display: flex; flex-wrap: wrap; gap: 5px; }
.gpu-chip { font-size: 9px; border: 1px solid #b8c8c2; background: var(--mint); padding: 5px 7px; border-radius: 3px; cursor: pointer; }
.gpu-chip.quality-card { border-color: color-mix(in srgb, var(--quality) 58%, #b8c8c2); background: color-mix(in srgb, var(--quality) 8%, var(--surface-2)); }
.gpu-chip small { color: var(--quality); font-size: 8px; font-weight: 800; }
.build-actions { padding: 12px; border-top: 1px solid var(--line); display: flex; justify-content: flex-end; gap: 8px; }
.stat-panel { background: var(--ink); color: #ffffff; border-radius: 6px; padding: 16px; position: sticky; top: 132px; }
.stat-panel h2 { font-size: 13px; margin: 0 0 16px; }
.stat-primary { border-bottom: 1px solid #3a4845; padding-bottom: 15px; }
.stat-primary small { color: #8fa19b; font-size: 9px; }
.stat-primary b { display: block; font-size: 29px; margin-top: 4px; }
.stat-list { display: grid; gap: 12px; padding: 15px 0; }
.stat-item { display: flex; justify-content: space-between; gap: 8px; font-size: 10px; color: #9aacA6; }
.stat-item b { color: #ffffff; }
.validation-list { margin: 0; padding: 10px 0 0 16px; color: var(--red); font-size: 9px; line-height: 1.6; border-top: 1px solid #3a4845; }
.valid-build { color: #76d3a7; font-size: 10px; border-top: 1px solid #3a4845; padding-top: 11px; display: flex; gap: 6px; align-items: center; }

.tech-summary { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-bottom: 18px; }
.summary-cell { background: var(--surface); border-left: 3px solid var(--green); padding: 13px 15px; }
.summary-cell small { color: var(--muted); font-size: 9px; }
.summary-cell b { display: block; margin-top: 5px; font-size: 17px; }
.tech-board { display: grid; grid-template-columns: repeat(4, minmax(190px, 1fr)); grid-template-rows: repeat(5, minmax(110px, auto)); gap: 14px 22px; position: relative; min-width: 840px; }
.tech-scroll { overflow-x: auto; padding: 3px 3px 20px; }
.tech-node { border: 1px solid var(--line); border-left: 4px solid #98aaa4; background: var(--surface); border-radius: 5px; padding: 13px; text-align: left; cursor: pointer; position: relative; }
.tech-node::after { content: ""; position: absolute; right: -23px; top: 50%; width: 22px; height: 1px; background: var(--muted); }
.tech-node:nth-child(3n)::after { display: none; }
.tech-node.unlocked { border-left-color: var(--green); background: var(--mint); }
.tech-node.available { border-color: var(--amber); border-left-color: var(--amber); }
.tech-node.locked { opacity: 0.55; cursor: not-allowed; }
.tech-node small { color: var(--muted); font-size: 8px; text-transform: uppercase; }
.tech-node h3 { font-size: 12px; margin: 7px 0 5px; }
.tech-node p { color: var(--muted); font-size: 9px; margin: 0; line-height: 1.45; }
.tech-node b { display: block; margin-top: 9px; color: var(--amber); font-size: 10px; }

.rank-wrap { background: var(--surface); border-top: 3px solid var(--ink); overflow: hidden; }
.rank-table { width: 100%; border-collapse: collapse; font-size: 12px; }
.rank-table th { text-align: left; color: var(--muted); font-size: 9px; padding: 11px 14px; background: var(--panel-deep); border-bottom: 1px solid var(--line); }
.rank-table td { padding: 12px 14px; border-bottom: 1px solid var(--line); }
.rank-table tr:last-child td { border-bottom: 0; }
.rank-table tr.me { background: var(--mint); }
.rank-number { width: 70px; font-weight: 800; }
.rank-number.top { color: var(--amber); font-size: 16px; }
.player-name { display: flex; align-items: center; gap: 8px; font-weight: 700; }
.online-dot { width: 7px; height: 7px; border-radius: 50%; background: #b9c4c0; }
.online-dot.on { background: var(--green); }
.rank-compute { font-variant-numeric: tabular-nums; font-weight: 700; }

.login-overlay { position: fixed; inset: 0; background: var(--ink); display: grid; place-items: center; padding: 20px; z-index: 100; }
.login-overlay::before { content: "NEURAL / GRID / CN-01 / 01"; position: absolute; left: 24px; top: 24px; color: #52625e; font-size: 10px; }
.login-overlay::after { content: ""; position: absolute; width: min(70vw, 700px); height: min(70vw, 700px); border: 1px solid #33433f; transform: rotate(45deg); pointer-events: none; }
.login-panel { width: min(100%, 410px); background: var(--surface); border-radius: 6px; padding: 28px; box-shadow: 0 28px 80px rgba(0,0,0,0.35); position: relative; z-index: 1; }
.brand-login { min-width: 0; margin-bottom: 26px; }
.login-season { position: absolute; right: 28px; top: 34px; font-size: 9px; color: var(--muted); display: flex; gap: 7px; align-items: center; }
.login-panel h1 { margin: 0 0 16px; font-size: 22px; }
.login-panel .segmented { width: 100%; margin-bottom: 17px; }
.login-panel .segmented button { flex: 1; }
.login-panel form { display: grid; gap: 12px; }
.login-panel label, .field-label { display: grid; gap: 6px; font-size: 10px; font-weight: 700; color: var(--muted); }
.login-panel input, .field-label input { height: 43px; border: 1px solid var(--line); border-radius: 4px; padding: 0 11px; color: var(--ink); background: var(--surface-2); }
.form-error { min-height: 16px; margin: -2px 0; color: var(--red); font-size: 10px; }
.guest-button { width: 100%; margin-top: 10px; }
.latency-line { display: flex; justify-content: space-between; border-top: 1px solid var(--line); margin-top: 20px; padding-top: 13px; color: var(--muted); font-size: 9px; }
.latency-line b { color: var(--green-dark); }
.server-settings-link { border: 0; padding: 0; background: transparent; color: var(--muted); align-items: center; gap: 5px; cursor: pointer; font-size: 9px; }
.server-settings-link svg { width: 12px; }

.modal { width: min(92vw, 430px); border: 1px solid var(--line); border-radius: 6px; padding: 0; color: var(--ink); box-shadow: 0 25px 70px rgba(23,33,31,0.28); }
.modal::backdrop { background: rgba(15, 23, 21, 0.68); }
.modal-head { display: flex; align-items: center; padding: 16px 18px; border-bottom: 1px solid var(--line); }
.modal-head > div { flex: 1; }
.modal-head small { color: var(--green-dark); font-size: 8px; font-weight: 800; }
.modal-head h2 { margin: 4px 0 0; font-size: 17px; }
.wallet-quote { margin: 18px; display: grid; grid-template-columns: 1fr 1fr; border-block: 1px solid var(--line); }
.wallet-quote span { display: grid; gap: 5px; padding: 13px 0; font-size: 9px; color: var(--muted); }
.wallet-quote b { color: var(--ink); font-size: 15px; }
.modal > .field-label, .modal > .quick-amounts, .modal > .exchange-preview, .modal > .full { margin-inline: 18px; width: calc(100% - 36px); }
.field-label select { height: 43px; width: 100%; border: 1px solid var(--line); border-radius: 4px; padding: 0 10px; background: var(--surface-2); color: var(--ink); }
.server-url-field, .trade-part-field { margin-top: 18px !important; }
.server-test-result { margin: 10px 18px 16px; min-height: 16px; color: var(--muted); font-size: 10px; }
.server-endpoint-hint { margin: 8px 18px 0; color: var(--muted); font-size: 9px; line-height: 1.5; }
.server-url-field select { width: 100%; }
.server-test-result.ok { color: var(--green-dark); }
.server-test-result.error { color: var(--red); }
.client-update-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin: 14px 18px 0; padding-top: 13px; border-top: 1px solid var(--line); }
.client-update-row div { display: grid; gap: 4px; }
.client-update-row small { color: var(--muted); font-size: 9px; }
.client-update-row b { font-size: 11px; }
.modal-actions { display: flex; justify-content: flex-end; gap: 8px; border-top: 1px solid var(--line); padding: 13px 18px 18px; }
.quick-amounts { display: flex; margin-top: 8px; }
.quick-amounts button { flex: 1; height: 32px; border: 1px solid var(--line); border-right: 0; background: var(--surface); cursor: pointer; font-size: 10px; }
.quick-amounts button:last-child { border-right: 1px solid var(--line); }
.exchange-preview { color: var(--muted); font-size: 10px; text-align: right; }
.modal > .full { margin-bottom: 18px; }
.recharge-balance { margin: 18px 18px 12px; display: flex; align-items: center; justify-content: space-between; color: var(--muted); font-size: 10px; }
.recharge-balance b { color: #a42f43; font-size: 16px; }
/* The store carries eight tiers, which do not fit the 430px default dialog: at that width each
   card is about 92px and the bundled credit line wraps onto three rows. Widening the dialog is
   what lets four cards sit in a row with their text intact. */
.recharge-modal { max-width: 660px; width: min(94vw, 660px); }
.recharge-packages { margin: 0 18px 14px; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }
.recharge-link { margin: 0 18px 12px; display: flex; }
.recharge-link[hidden] { display: none; }
.recharge-link button { display: inline-flex; align-items: center; gap: 6px; }
.recharge-link svg { width: 13px; height: 13px; }
.recharge-package { position: relative; min-width: 0; min-height: 92px; padding: 11px 8px; border: 1px solid var(--apex-line); border-radius: 5px; background: var(--apex-bg); display: grid; align-content: space-between; gap: 10px; text-align: left; cursor: pointer; }
.recharge-package:hover { border-color: var(--apex); box-shadow: 0 5px 14px color-mix(in srgb, var(--apex) 14%, transparent); }
.recharge-package:disabled { opacity: .48; cursor: not-allowed; }
.recharge-package span { display: grid; gap: 3px; }
.recharge-package small { color: var(--muted); font-size: 8px; }
.recharge-package b { color: #a42f43; font-size: 12px; white-space: nowrap; }
/* The bundled credit gift is secondary to the cores, so it sits below at a smaller weight. */
.recharge-package i { font-style: normal; font-size: 8px; color: var(--muted); white-space: nowrap; }
.recharge-package strong { font-size: 11px; }
/* First-purchase tag: a corner ribbon, because six of eight tiers carry it and a full-width
   banner would make the store look like a permanent sale. */
.recharge-package.has-first-bonus { border-color: var(--green); }
.first-bonus-tag {
  position: absolute;
  top: -1px;
  right: 4px;
  padding: 2px 5px;
  border-radius: 0 0 4px 4px;
  background: var(--green);
  color: #10141c;
  font-size: 8px;
  font-style: normal;
  font-weight: 700;
  line-height: 1.4;
  letter-spacing: 0.02em;
}
.sandbox-notice { margin: 0 18px 18px; padding: 10px; border: 1px solid var(--amber-soft); background: var(--amber-soft); color: #755516; display: flex; align-items: center; gap: 8px; font-size: 10px; }
.sandbox-notice svg { width: 16px; flex: 0 0 auto; }
.sources-modal > p { color: var(--muted); font-size: 11px; line-height: 1.6; margin: 16px 18px; }
.source-list { margin: 0 18px 18px; border-top: 1px solid var(--line); max-height: 320px; overflow: auto; }
.source-list a { display: flex; align-items: center; gap: 8px; padding: 10px 0; border-bottom: 1px solid var(--line); color: var(--green-dark); font-size: 10px; text-decoration: none; }
.source-list a:hover { text-decoration: underline; }

.toast-stack { position: fixed; right: 18px; bottom: 18px; z-index: 200; display: grid; gap: 8px; width: min(360px, calc(100vw - 36px)); pointer-events: none; }
.toast { background: var(--ink); color: #ffffff; border-left: 4px solid var(--green); padding: 12px 14px; border-radius: 4px; box-shadow: var(--shadow); font-size: 11px; animation: toastIn 180ms ease-out; }
.toast.error { border-left-color: var(--red); }
.toast.warn { border-left-color: var(--amber); }
@keyframes toastIn { from { opacity: 0; transform: translateY(8px); } }

.empty-state { min-height: 260px; display: grid; place-items: center; align-content: center; text-align: center; color: var(--muted); }
.empty-state svg { width: 34px; height: 34px; margin-bottom: 8px; }
.empty-state b { color: var(--ink); font-size: 13px; }
.empty-state p { margin: 5px 0 12px; font-size: 10px; }

@media (max-width: 1180px) {
  .resource-pill { min-width: 102px; }
  .part-grid { grid-template-columns: repeat(3, minmax(210px, 1fr)); }
  .trade-grid { grid-template-columns: repeat(2, minmax(230px, 1fr)); }
  .rig-grid { grid-template-columns: repeat(2, minmax(220px, 1fr)); }
  .achievement-grid { grid-template-columns: repeat(2, minmax(220px, 1fr)); }
  .achievement-overview { grid-template-columns: 1fr 1fr; }
  .workshop-layout { grid-template-columns: 190px minmax(380px, 1fr); }
  .stat-panel { grid-column: 1 / -1; position: static; display: grid; grid-template-columns: 1.2fr 2fr; gap: 18px; }
}

@media (max-width: 880px) {
  .app-shell { grid-template: 64px 1fr 66px / 1fr; }
  .topbar { height: 64px; padding: 0 12px; }
  .brand { min-width: auto; }
  .brand b { font-size: 14px; }
  .brand small, .server-chip, .resource-pill.research, .user-button { display: none; }
  .brand-mark { width: 28px; height: 28px; }
  .resource-pill { min-width: 91px; height: 40px; padding: 0 9px; }
  .resource-pill b { font-size: 12px; }
  .resource-pill svg { width: 17px; }
  .sidebar { grid-row: 3; position: fixed; height: 66px; bottom: 0; top: auto; left: 0; right: 0; flex-direction: row; z-index: 30; }
  .sidebar nav { flex: 1; display: grid; grid-template-columns: repeat(6, 1fr); padding: 5px; gap: 2px; }
  .sidebar button { height: 56px; }
  .sidebar-info { display: none !important; }
  .main-stage { grid-column: 1; grid-row: 2; }
  .ticker { top: 64px; padding: 0 12px; }
  .ticker-label { font-size: 0; }
  .ticker-label svg { width: 15px; }
  .ticker span { display: none; }
  .view { padding: 14px 12px 82px; }
  .world-band { grid-template-columns: 1fr 1fr; padding: 18px; }
  .world-primary { grid-column: 1 / -1; }
  .world-primary b { font-size: 26px; }
  .world-metric { padding-left: 12px; }
  .overview-layout { grid-template-columns: 1fr; }
  .overview-rail { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
  .part-grid { grid-template-columns: repeat(2, minmax(180px, 1fr)); }
  .trade-grid { grid-template-columns: repeat(2, minmax(180px, 1fr)); }
  .achievement-grid { grid-template-columns: 1fr; }
  .achievement-overview { grid-template-columns: 1fr 1fr; }
  .workshop-layout { grid-template-columns: 1fr; }
  .machine-list { display: flex; overflow-x: auto; border-top: 0; }
  .machine-list-head { min-width: 120px; border-right: 1px solid var(--line); }
  .machine-list-item { min-width: 150px; border-right: 1px solid var(--line); border-bottom: 0; }
  .stat-panel { grid-column: auto; grid-template-columns: 1fr 1.4fr; }
}

@media (max-width: 560px) {
  .topbar { gap: 6px; }
  .top-spacer { display: none; }
  .brand { margin-right: auto; }
  .topbar .brand > span:last-child { display: none; }
  .resource-pill { min-width: 0; width: 86px; }
  .resource-pill.credits { width: 94px; }
  .page-head { align-items: start; }
  .page-head h1 { font-size: 21px; }
  .page-head p { display: none; }
  .head-actions .secondary span { display: none; }
  .world-band { gap: 14px 8px; }
  .world-metric:nth-of-type(3) { display: none; }
  .rig-grid, .part-grid { grid-template-columns: 1fr; }
  .trade-grid { grid-template-columns: 1fr; }
  .rig-card { min-height: 315px; }
  .overview-rail { grid-template-columns: 1fr; }
  .toolbar { align-items: stretch; }
  .search-box { min-width: 100%; max-width: none; }
  .segmented { max-width: 100%; overflow-x: auto; }
  .segmented button { flex: 0 0 auto; }
  .market-note { width: 100%; margin-left: 0; }
  .merchant-lottery { grid-template-columns: 1fr; gap: 16px; padding: 16px 0; }
  .lottery-odds { grid-template-columns: repeat(auto-fit, minmax(48px, 1fr)); }
  .lottery-pity { display: grid; grid-template-columns: 1fr 1fr; gap: 7px; }
  .lottery-pity span:first-child { grid-column: 1 / -1; }
  .lottery-actions { display: grid; grid-template-columns: 1fr 1fr; }
  .lottery-actions > span { grid-column: 1 / -1; }
  .lottery-actions button { justify-content: center; min-width: 0; padding-inline: 8px; }
  .lottery-actions button[data-merchant-draw="100"] { grid-column: 1 / -1; }
  .synthesis-panel { grid-template-columns: 1fr; }
  .build-slots, .inventory-options { grid-template-columns: 1fr; }
  .build-slot { min-width: 0; }
  .stat-panel { display: block; }
  .tech-summary { grid-template-columns: 1fr 1fr; }
  .rank-table th:nth-child(4), .rank-table td:nth-child(4) { display: none; }
  .login-panel { padding: 22px; }
  .login-season { display: none; }
  .ticker { font-size: 10px; }
  .recharge-packages { grid-template-columns: 1fr; }
}

@media (prefers-reduced-motion: reduce) {
  .fan, .chassis-light, .chassis-scan, .quality-q1::after, .quality-q2::after, .quality-q3::after, .quality-q4, .quality-q4::after, .quality-q5, .quality-q5::after, .part-chassis .part-icon, .chassis-product-visual img, .chassis-product-visual::before, .chassis-product-visual .part-icon { animation: none !important; }
}

/* ---------------------------------------------------------------------------
   Reference-derived chrome: angled metallic frames, dot-matrix texture and the
   cyan/amber accent split. Kept at the end so they win over the base rules.
   --------------------------------------------------------------------------- */
body {
  /* The CSS gradients stay as the base layer and as the fallback when the
     generated backdrop is missing; the artwork sits on top of them. The scrim is
     kept light: panels are opaque, so only the gutters show the artwork and it
     does not need heavy darkening to keep text readable. */
  background:
    linear-gradient(rgba(7, 11, 20, 0.12), rgba(7, 11, 20, 0.55)),
    url("./assets/ui/stage.jpg") center top / cover no-repeat fixed,
    radial-gradient(1200px 620px at 78% -12%, rgba(70, 210, 255, 0.10), transparent 62%),
    radial-gradient(900px 520px at 6% 108%, rgba(242, 163, 60, 0.07), transparent 60%),
    var(--canvas);
  background-color: var(--canvas);
}
/* Faint dot matrix over the whole stage, as in the reference backdrop. */
.app-shell::before {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background-image: radial-gradient(rgba(130, 150, 179, 0.16) 1px, transparent 1px);
  background-size: 22px 22px;
  opacity: .5;
}
/* Lift the stage above the dot matrix. :where() keeps specificity at zero so it
   cannot override a child's own position. The previous ".app-shell > *" form won
   that comparison and silently reset the topbar from sticky to relative, which let
   page content scroll over the resource pills. */
:where(.app-shell > *) { position: relative; z-index: 1; }
/* Restated with higher specificity so nothing generic can flatten them again. */
.app-shell > .topbar { position: sticky; z-index: 30; }
.app-shell > .ticker { position: sticky; z-index: 25; }

.topbar {
  background: linear-gradient(180deg, color-mix(in srgb, var(--surface-2) 88%, transparent), color-mix(in srgb, var(--panel-deep) 92%, transparent));
  backdrop-filter: blur(6px);
  border-bottom: 1px solid var(--line-strong);
  box-shadow: 0 1px 0 rgba(70, 210, 255, 0.10);
}
.brand b { color: var(--ink); letter-spacing: .04em; }
.brand small { color: var(--faint); letter-spacing: .16em; text-transform: uppercase; }
.brand-mark i:nth-child(1) { background: var(--cyan); }
.brand-mark i:nth-child(2) { background: var(--amber); }
.brand-mark i:nth-child(3) { background: var(--green); }

.resource-pill {
  background: linear-gradient(180deg, var(--surface-2), var(--panel-deep));
  border-color: var(--line);
}
.resource-pill:hover { border-color: var(--cyan); }
.resource-pill b { color: var(--ink); }
.resource-pill.cores { background: var(--apex-bg); border-color: var(--apex-line); }

.sidebar {
  background: linear-gradient(180deg, color-mix(in srgb, var(--panel-deep) 90%, transparent), color-mix(in srgb, var(--canvas) 72%, transparent));
  backdrop-filter: blur(6px);
  border-right: 1px solid var(--line);
}
.sidebar button { color: var(--muted); }
.sidebar button:hover { background: var(--surface-2); color: var(--ink); }
.sidebar button.active {
  background: linear-gradient(180deg, rgba(70, 210, 255, 0.20), rgba(70, 210, 255, 0.06));
  color: var(--cyan);
  box-shadow: inset 2px 0 0 var(--cyan), var(--glow-cyan);
}

.ticker {
  background: linear-gradient(90deg, rgba(242, 163, 60, 0.10), transparent 60%), color-mix(in srgb, var(--surface) 86%, transparent);
  backdrop-filter: blur(6px);
  border-bottom: 1px solid var(--line);
}
.ticker-label, .ticker time { color: var(--amber); }
.ticker b { color: var(--ink); }

/* Panels get an angled metallic edge instead of a flat border. */
.rail-block, .stat-panel, .machine-list, .synthesis-panel, .lottery-panel,
.tech-summary, .achievement-overview-stat, .market-toolbar, .rank-wrap {
  border-color: var(--line);
}
.page-head h1 { color: var(--ink); letter-spacing: .01em; }
.eyebrow { color: var(--cyan); letter-spacing: .18em; }

/* Section headers get a cyan tick, matching the reference's accent rules. */
.section-head h2, .rail-title h2 { color: var(--ink); }
.rail-title { border-bottom-color: var(--line); }
.rail-title svg { color: var(--cyan); }

/* Buttons: cyan for primary, outlined for secondary. */
.primary { background: linear-gradient(180deg, #4fd8ff, var(--cyan-dim)); color: #04121b; }
.primary:hover { background: linear-gradient(180deg, #6ee0ff, #24a3d0); }
.secondary { background: var(--surface-2); color: var(--ink); border-color: var(--line-strong); }
.secondary:hover { border-color: var(--cyan); color: var(--cyan); }
.ghost { border-color: var(--line-strong); color: var(--muted); }
.danger { background: transparent; color: var(--red); border-color: var(--apex-line); }

/* The item artwork is neon line art on a near-black field, so the thumbnail well is dark
   too. It used to be a light well (#eef2f7) because the art was a dark studio photograph and
   needed the contrast; against line art that only produced a pale frame around every card,
   which is what the "grey box" complaint was. The well base now matches the artwork's own
   background so the drawing sits inside the card rather than on a plate. */
.product-visual {
  background: linear-gradient(180deg, var(--well), var(--well-deep));
  border-color: var(--well-edge);
}
.product-visual::before { background: none; }
.chassis-product-visual {
  background: linear-gradient(135deg, var(--well-deep), var(--surface-2) 52%, var(--well-deep));
  border-color: var(--line-strong);
}
.part-card, .trade-card, .task-row, .achievement-card, .recharge-package, .merchant-lottery {
  background: var(--surface);
  border-color: var(--line);
}
.part-card:hover, .trade-card:hover, .achievement-card.unlocked { border-color: var(--line-strong); }
.part-brand { color: var(--cyan); letter-spacing: .06em; }

input, select, textarea {
  background: var(--panel-deep);
  border-color: var(--line-strong);
  color: var(--ink);
}
input::placeholder, textarea::placeholder { color: var(--faint); }
.field-label { color: var(--muted); }

.modal { background: var(--surface); border: 1px solid var(--line-strong); box-shadow: var(--shadow); }
.modal-head { border-bottom-color: var(--line); }
.modal-head h2 { color: var(--ink); }

.toast { background: var(--panel-deep); border: 1px solid var(--line-strong); color: var(--ink); }
.toast.error { border-left-color: var(--red); }
.toast.warn { border-left-color: var(--amber); }
.toast.achievement { border-left-color: var(--amber); background: linear-gradient(90deg, var(--amber-soft), var(--panel-deep)); }

.chat-message { color: var(--ink); }
.chat-message b { color: var(--cyan); }
.chat-list { background: var(--panel-deep); border-color: var(--line); }
.meter { background: var(--panel-deep); }
.meter i { background: linear-gradient(90deg, var(--cyan-dim), var(--cyan)); }

.meter, .achievement-progress { background: var(--panel-deep); }
.achievement-progress i { background: var(--cyan); }
.achievement-card.unlocked .achievement-progress i { background: var(--amber); }
.achievement-card.unlocked { border-left-color: var(--amber); background: linear-gradient(180deg, var(--amber-soft), var(--surface) 46%); }
.achievement-overview-main { background: linear-gradient(160deg, var(--surface-2), var(--panel-deep)); border: 1px solid var(--line-strong); }
.achievement-badge.locked img { filter: grayscale(1) brightness(1.15) opacity(.3); }

.button-ghost, .segmented button { background: var(--surface-2); color: var(--muted); border-color: var(--line); }
.segmented button.active { background: var(--cyan-soft); color: var(--cyan); border-color: var(--cyan); }

/* ---------------------------------------------------------------------------
   Panels that used --ink as a DEEP background in the light theme. That token is
   now the light text colour, so each needs its own navy surface, mirroring the
   reference's raised-panel treatment.
   --------------------------------------------------------------------------- */
.world-band {
  background:
    linear-gradient(135deg, rgba(70, 210, 255, 0.10), transparent 46%),
    linear-gradient(180deg, var(--surface-2), var(--panel-deep));
  border: 1px solid var(--line-strong);
  box-shadow: inset 0 1px 0 rgba(70, 210, 255, 0.12);
}
.world-band::after { border-color: rgba(70, 210, 255, 0.16) !important; }
.world-primary small { color: var(--cyan); }
.world-primary b { color: var(--ink); }
.world-metric { border-left-color: var(--line-strong); }
.world-metric small { color: var(--faint); }
.world-metric b { color: var(--ink); }

.stat-panel {
  background: linear-gradient(180deg, var(--surface-2), var(--panel-deep));
  border: 1px solid var(--line-strong);
}
.stat-item { border-bottom-color: var(--line); }
.stat-item span { color: var(--faint); }
.stat-item b { color: var(--ink); }

.login-overlay {
  /* Generated title-screen backdrop, with the gradient kept underneath as the
     fallback and a scrim so the form stays readable over the artwork. */
  background:
    radial-gradient(120% 90% at 50% 40%, rgba(11, 17, 32, 0.30), rgba(7, 11, 20, 0.80)),
    url("./assets/ui/login.jpg") center center / cover no-repeat,
    radial-gradient(900px 500px at 74% -6%, rgba(70, 210, 255, 0.14), transparent 60%),
    radial-gradient(700px 460px at 10% 106%, rgba(242, 163, 60, 0.10), transparent 58%),
    var(--canvas);
}
.login-panel { background: var(--surface); border: 1px solid var(--line-strong); box-shadow: var(--shadow); }

.chat-form button { background: var(--cyan); color: #04121b; }
.chat-form button:hover { background: #6ee0ff; }

/* Progress tracks were a light grey literal. */
.meter, .achievement-progress { background: var(--panel-deep); }
.stat-bar, .temp-bar { background: var(--panel-deep); }

/* Small status dots read better brighter on a dark field. */
.online-dot { background: var(--faint); }
.online-dot.on { background: var(--green); }

/* Multi-slot picker: the board's slot count and how many are filled. */
.slot-hint {
  margin: 0 0 8px;
  color: var(--muted);
  font-size: 9px;
  line-height: 1.5;
}
.slot-hint.full { color: var(--amber); }
.stack-label {
  display: block;
  width: 100%;
  margin-bottom: 4px;
  color: var(--faint);
  font-size: 9px;
  letter-spacing: .06em;
}

/* Empty-state drop zone: a dashed cyan outline instead of a white wash. */
.empty-rig { border: 1px dashed var(--line-strong); background: rgba(70, 210, 255, 0.04); }
.empty-rig:hover { border-color: var(--cyan); background: var(--cyan-soft); }

/* ---------------------------------------------------------------------------
   Technology board. The grid is sized from the data at render time (see
   renderTech), so adding a branch only needs a new row of nodes.
   --------------------------------------------------------------------------- */
.tech-board {
  display: grid;
  gap: 14px 22px;
  position: relative;
}
/* The summary row now covers eight metrics, so it wraps rather than staying at
   a fixed three columns. */
.tech-summary { grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); }

/* ---------------------------------------------------------------------------
   Technology layering: each node shows its progress toward the layer cap, the
   per-layer effect, and the price of the next layer.
   --------------------------------------------------------------------------- */
.tech-node { display: flex; flex-direction: column; gap: 5px; text-align: left; }
.tech-node .tech-layers {
  display: block;
  height: 4px;
  margin-top: 2px;
  background: var(--panel-deep);
  border-radius: 2px;
  overflow: hidden;
}
.tech-node .tech-layers i {
  display: block;
  height: 100%;
  background: linear-gradient(90deg, var(--cyan-dim), var(--cyan));
  transition: width .25s ease;
}
.tech-node.unlocked .tech-layers i { background: linear-gradient(90deg, var(--amber), #ffcf87); }
.tech-node em {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  font-style: normal;
  font-size: 9px;
  color: var(--muted);
}
.tech-node em span { color: var(--faint); }
.tech-node b { margin-top: 2px; }
.tech-node.unaffordable b { color: var(--red); }
.tech-node:disabled { cursor: not-allowed; }
.tech-hint {
  margin: 10px 0 14px;
  padding: 9px 12px;
  color: var(--muted);
  font-size: 10px;
  line-height: 1.6;
  background: var(--surface-2);
  border-left: 3px solid var(--cyan);
  border-radius: 3px;
}
