/* ================================================================
   EVE PI Tracker — style.css
   ================================================================ */

/* ── Theme tokens ────────────────────────────────────────────── */
/*
   All color-mix() derivations in the structural CSS below reference
   these tokens. Adding a new theme means overriding this block only.
   Nothing else changes.

   color-mix strategy:
     • Tinted backgrounds  → color-mix(in srgb, var(--color) N%, transparent)
     • Hover overlays      → color-mix(in srgb, var(--overlay) N%, transparent)
     • Ratio bar track     → color-mix(in srgb, black var(--bar-track-pct), transparent)
     • Section dividers    → color-mix(in srgb, black var(--divider-pct), transparent)

   --overlay is black on light surfaces (darken) and white on dark (lighten).
   --bar-track-pct / --divider-pct are both black-based but with different
   context-appropriate strengths — so they're explicit tokens, not derived.
*/

/* Light — default */
:root {
    /* Surfaces */
    --bg:         #f1f5f9;
    --card-bg:    #ffffff;
    --card-hover: #f8fafc;
    --header-bg:  #ffffff;

    /* Borders */
    --border:      #e2e8f0;
    --border-soft: #cbd5e1;

    /* Text hierarchy */
    --text:       #0f172a;
    --text-sub:   #1e293b;
    --text-muted: #475569;
    --text-dim:   #64748b;

    /* Material tier — muted (facility < 80% full) */
    --mat-p0-muted: #8b7bb5;
    --mat-p1-muted: #6b8fad;
    --mat-p2-muted: #b89a4a;

    /* Material tier — vibrant (facility ≥ 80% full) */
    --mat-p0: #7c3aed;
    --mat-p1: #2563eb;
    --mat-p2: #d97706;

    /* State: success / error / warning */
    --timer-fg:   #059669;
    --expired-fg: #dc2626;
    --warn:       #d97706;

    /* Primary button surface */
    --btn-primary-bg:           #dbeafe;
    --btn-primary-border:       #93c5fd;
    --btn-primary-color:        #1e40af;
    --btn-primary-hover-bg:     #bfdbfe;
    --btn-primary-hover-border: #60a5fa;

    /* Interaction overlay direction: light surfaces darken on hover */
    --overlay: black;

    /* Fill-bar empty track — both themes use black, different strengths */
    --bar-track-pct: 10%;

    /* Section divider tint — black at N% over the card background */
    --divider-pct: 4%;

    /* Card elevation */
    --card-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);

    /* Table rows whose entire element opacity is set (not just background) */
    --multi-opacity: 0.4;

    /* Sidebar planet type text — darker on light card backgrounds */
    --sidebar-default-color:   #64748b;
    --sidebar-lava-color:      #b91c1c;
    --sidebar-ice-color:       #1d4ed8;
    --sidebar-barren-color:    #b45309;
    --sidebar-gas-color:       #6d28d9;
    --sidebar-storm-color:     #4338ca;
    --sidebar-oceanic-color:   #0f766e;
    --sidebar-temperate-color: #15803d;
    --sidebar-plasma-color:    #c2410c;

    /* Layout */
    --header-height: 41px;
}

/* Dark */
[data-theme="dark"] {
    --bg:         #07090e;
    --card-bg:    #111827;
    --card-hover: #162032;
    --header-bg:  #0d1424;
    --border:      #1f2937;
    --border-soft: #374151;
    --text:       #f3f4f6;
    --text-sub:   #d1d5db;
    --text-muted: #9ca3af;
    --text-dim:   #6b7280;
    --mat-p0-muted: #5a4b75;
    --mat-p1-muted: #3d5a78;
    --mat-p2-muted: #75633d;
    --mat-p0: #a78bfa;
    --mat-p1: #60a5fa;
    --mat-p2: #fbbf24;
    --timer-fg:   #34d399;
    --expired-fg: #f87171;
    --warn:       #fbbf24;
    --btn-primary-bg:           #1d3a5f;
    --btn-primary-border:       #2d5a8f;
    --btn-primary-color:        #93c5fd;
    --btn-primary-hover-bg:     #243f6e;
    --btn-primary-hover-border: #3b7fc4;
    --overlay:       white;
    --bar-track-pct: 35%;
    --divider-pct:   30%;
    --card-shadow:   0 3px 10px rgba(0, 0, 0, 0.25);
    --multi-opacity: 0.35;
    --sidebar-default-color:   #94a3b8;
    --sidebar-lava-color:      #fca5a5;
    --sidebar-ice-color:       #93c5fd;
    --sidebar-barren-color:    #fcd34d;
    --sidebar-gas-color:       #c4b5fd;
    --sidebar-storm-color:     #a5b4fc;
    --sidebar-oceanic-color:   #5eead4;
    --sidebar-temperate-color: #86efac;
    --sidebar-plasma-color:    #fdba74;
}

/* ── Reset / Base ───────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }

/* Always reserve scrollbar gutter space — prevents the header from shifting
   left/right when switching between tabs with different content heights.
   On macOS with overlay scrollbars this is a no-op (no gutter to reserve). */
html { scrollbar-gutter: stable; }

/* Must beat any display: rule set by component CSS — placed near top. */
[hidden] { display: none !important; }

body {
    font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
    background-color: var(--bg);
    color: var(--text);
    margin: 0;
    min-height: 100vh;
    -webkit-font-smoothing: antialiased;
    /* Smooth theme transition — only surfaces and text, not layout */
    transition: background-color 0.2s, color 0.2s;
}

/* ── App Header ─────────────────────────────────────────────── */
.app-header {
    display: flex;
    align-items: stretch;
    justify-content: space-between;
    background: var(--header-bg);
    border-bottom: 1px solid var(--border);
    padding: 0 16px;
    height: var(--header-height);
    position: sticky;
    top: 0;
    z-index: 10;
    transition: background-color 0.2s, border-color 0.2s;
}

.app-brand {
    display: flex;
    align-items: center;
    margin: 0;
    font-size: 0.9rem;
    font-weight: 700;
    letter-spacing: 0.4px;
    color: var(--text);
    white-space: nowrap;
}

/* Groups tabs + controls so both can be toggled as one unit on mobile.
   On desktop this is just a transparent flex wrapper. */
.header-nav {
    display: flex;
    flex: 1;
    align-items: stretch;
    justify-content: space-between;
    min-width: 0;
}

/* Hamburger toggle — hidden on desktop, shown on mobile */
.header-menu-btn {
    display: none;
    flex-shrink: 0;
    font-size: 1.1rem;
}

.header-tabs {
    display: flex;
    align-items: stretch;
    margin: 0 24px;
}

.header-controls {
    display: flex;
    align-items: center;
    gap: 8px;
}

/* ── Tab buttons ─────────────────────────────────────────────── */
.tab-btn {
    background: none;
    border: none;
    border-bottom: 2px solid transparent;
    padding: 0 16px;
    font-size: 0.8rem;
    font-weight: 600;
    letter-spacing: 0.25px;
    color: var(--text-dim);
    cursor: pointer;
    transition: color 0.15s, border-color 0.15s;
    margin-bottom: -1px;
    white-space: nowrap;
}
.tab-btn:hover  { color: var(--text-muted); }
.tab-btn.active { color: var(--text); border-bottom-color: var(--mat-p1); }

/* ── Buttons ─────────────────────────────────────────────────── */
.btn {
    display: inline-flex;
    align-items: center;
    padding: 6px 12px;
    border-radius: 6px;
    font-size: 0.8rem;
    font-weight: 600;
    cursor: pointer;
    border: 1px solid transparent;
    transition: background-color 0.15s, border-color 0.15s, color 0.15s;
    white-space: nowrap;
    line-height: 1.4;
}

.btn-primary {
    background: var(--btn-primary-bg);
    border-color: var(--btn-primary-border);
    color: var(--btn-primary-color);
}
.btn-primary:hover:not(:disabled) {
    background: var(--btn-primary-hover-bg);
    border-color: var(--btn-primary-hover-border);
}
.btn-primary:disabled { opacity: 0.4; cursor: not-allowed; }

.btn-ghost {
    background: transparent;
    border-color: var(--border);
    color: var(--text-muted);
}
.btn-ghost:hover {
    background: color-mix(in srgb, var(--overlay) 4%, transparent);
    color: var(--text);
    border-color: var(--border-soft);
}

/* Compact square-ish button for icon/emoji content */
.btn-icon { padding: 5px 8px; font-size: 0.9rem; }

.btn-lg { padding: 10px 24px; font-size: 0.95rem; }

/* Hides the Refresh button while keeping its space reserved so the buttons
   beside it never shift position. Using a class instead of the `hidden`
   attribute avoids fighting [hidden]{display:none !important} in the reset. */
.btn-no-show {
    visibility: hidden !important;
    pointer-events: none;
}

/* ── Status Text ─────────────────────────────────────────────── */
.status-text {
    font-size: 0.78rem;
    padding: 3px 8px;
    border-radius: 4px;
}
.status-info    { color: var(--text-muted); }
.status-success { color: var(--timer-fg); }
.status-error   {
    color: var(--expired-fg);
    background: color-mix(in srgb, var(--expired-fg) 10%, transparent);
}

/* ── Main content area ──────────────────────────────────────── */
#app { padding: 12px 12px; }

/* ── Empty State ─────────────────────────────────────────────── */
.empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 14px;
    min-height: 60vh;
    text-align: center;
}
.empty-icon  { font-size: 2.8rem; }
.empty-title { font-size: 1.35rem; font-weight: 700; margin: 0; }
.empty-desc  {
    font-size: 0.88rem;
    color: var(--text-muted);
    margin: 0;
    max-width: 340px;
    line-height: 1.5;
}

/* ── Dashboard Grid ─────────────────────────────────────────── */
/*
   Column count is set explicitly via data-char-count so the grid never
   auto-wraps. Columns scale proportionally (1fr each) instead of having
   a fixed minimum that can overflow at moderate viewport widths.
   Without data-char-count the grid falls back to a single column.
*/
.dashboard {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 12px;
    max-width: 1920px;
    margin-left: 12px;
}
.dashboard[data-char-count="2"] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.dashboard[data-char-count="3"] { grid-template-columns: repeat(3, minmax(0, 1fr)); }

/* ── Character Column ───────────────────────────────────────── */
.character-column {
    display: flex;
    flex-direction: column;
    gap: 8px;
    min-width: 0;
}

.char-header {
    display: flex;
    align-items: center;
    gap: 8px;
    background: var(--header-bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 8px 10px;
}

.char-portrait {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    border: 1px solid var(--border-soft);
    flex-shrink: 0;
    background: var(--border);
}

/* Wraps both header rows; takes the flex-grow space between portrait and ✕. */
.char-name-wrap {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

/* ── Row 1: name (left, grows) + ISK balance (right, fixed) ── */
.char-name-row {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
}

.char-name {
    flex: 1;
    min-width: 0;
    font-size: 0.8rem;
    font-weight: 700;
    letter-spacing: 0.6px;
    text-transform: uppercase;
    color: var(--text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ISK balance placeholder — right side of row 1.
   Populated by updateCharacterMeta() once wallet ESI data arrives. */
.char-balance {
    flex-shrink: 0;
}

/* Wallet badge: "Wallet:  3.247B  ISK" — label + amount + symbol */
.char-isk-badge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    white-space: nowrap;
}

/* "Wallet:" prefix label */
.char-isk-label {
    font-size: 0.62rem;
    font-weight: 600;
    color: var(--text-dim);
    letter-spacing: 0.02em;
}

/* Small amber "ISK" pill badge — sits after the amount */
.char-isk-sym {
    font-size: 0.52rem;
    font-weight: 800;
    letter-spacing: 0.8px;
    color: var(--mat-p2);
    background: color-mix(in srgb, var(--mat-p2) 14%, transparent);
    border: 1px solid color-mix(in srgb, var(--mat-p2) 28%, transparent);
    border-radius: 3px;
    padding: 1px 3px;
    line-height: 1.3;
}

.char-isk-amt {
    font-size: 0.75rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: var(--mat-p2);
}

/* ── Row 2: active ship + location ──────────────────────────── */
/* Empty by default; min-height keeps header height stable while ESI loads. */
.char-meta {
    display: flex;
    align-items: center;
    font-size: 0.7rem;
    min-height: 14px;
    gap: 0;
    overflow: hidden;
    white-space: nowrap;
}

.char-ship {
    color: var(--text-muted);
    white-space: nowrap;
}

.char-meta-sep {
    color: var(--border-soft);
    flex-shrink: 0;
    padding: 0 3px;
}

/* Location: system name + security status + structure type */
.char-loc {
    display: inline-flex;
    align-items: center;
    overflow: hidden;
    min-width: 0;
}

.char-loc-sys {
    color: var(--text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Security status — color-coded by class.
   Padding provides the visual gap between system name and structure type. */
.char-sec {
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    flex-shrink: 0;
    padding: 0 3px;
}
.sec-high { color: var(--timer-fg); }
.sec-low  { color: var(--warn); }
.sec-null { color: var(--expired-fg); }

.char-loc-type {
    color: var(--text-dim);
    flex-shrink: 0;
    opacity: 0.8;
}

.char-remove {
    background: none;
    border: none;
    color: var(--text-dim);
    font-size: 0.72rem;
    cursor: pointer;
    padding: 2px 5px;
    border-radius: 4px;
    line-height: 1;
    flex-shrink: 0;
    margin-left: 8px;   /* extra breathing room between wallet and ✕ */
    transition: color 0.15s;
}
.char-remove:hover { color: var(--expired-fg); }

.col-loading, .col-error {
    padding: 18px;
    text-align: center;
    border: 1px solid var(--border);
    border-radius: 8px;
    font-size: 0.82rem;
}
.col-loading { color: var(--text-dim); }
.col-error   {
    color: var(--expired-fg);
    background: color-mix(in srgb, var(--expired-fg) 10%, transparent);
}

/* ── Planet Card ─────────────────────────────────────────────── */
.planet-card {
    display: flex;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    overflow: hidden;
    box-shadow: var(--card-shadow);
    transition: background-color 0.15s, border-color 0.15s;
    min-width: 0;
}
.planet-card:hover {
    background: var(--card-hover);
    border-color: var(--border-soft);
}

/* ── Planet Type Sidebar ─────────────────────────────────────── */
.sidebar {
    width: 26px;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.58rem;
    font-weight: 700;
    letter-spacing: 1.5px;
    text-transform: uppercase;
    writing-mode: vertical-rl;
    transform: rotate(180deg);
    border-right: 1px solid var(--border);
    background: linear-gradient(180deg, rgba(100,116,139,0.18) 0%, rgba(100,116,139,0.04) 100%);
    color: var(--sidebar-default-color);
}

.planet-card[data-type="lava"]      .sidebar { background: linear-gradient(180deg, rgba(239,68,68,0.2)  0%, rgba(239,68,68,0.04)  100%); color: var(--sidebar-lava-color); }
.planet-card[data-type="ice"]       .sidebar { background: linear-gradient(180deg, rgba(59,130,246,0.2) 0%, rgba(59,130,246,0.04) 100%); color: var(--sidebar-ice-color); }
.planet-card[data-type="barren"]    .sidebar { background: linear-gradient(180deg, rgba(245,158,11,0.2) 0%, rgba(245,158,11,0.04) 100%); color: var(--sidebar-barren-color); }
.planet-card[data-type="gas"]       .sidebar { background: linear-gradient(180deg, rgba(139,92,246,0.2) 0%, rgba(139,92,246,0.04) 100%); color: var(--sidebar-gas-color); }
.planet-card[data-type="storm"]     .sidebar { background: linear-gradient(180deg, rgba(99,102,241,0.2) 0%, rgba(99,102,241,0.04) 100%); color: var(--sidebar-storm-color); }
.planet-card[data-type="oceanic"]   .sidebar { background: linear-gradient(180deg, rgba(20,184,166,0.2) 0%, rgba(20,184,166,0.04) 100%); color: var(--sidebar-oceanic-color); }
.planet-card[data-type="temperate"] .sidebar { background: linear-gradient(180deg, rgba(34,197,94,0.2)  0%, rgba(34,197,94,0.04)  100%); color: var(--sidebar-temperate-color); }
.planet-card[data-type="plasma"]    .sidebar { background: linear-gradient(180deg, rgba(249,115,22,0.2) 0%, rgba(249,115,22,0.04) 100%); color: var(--sidebar-plasma-color); }

/* ── Card Content Area ──────────────────────────────────────── */
.content-wrapper {
    display: flex;
    flex: 1;
    padding: 10px 10px;
    gap: 10px;
    min-width: 0;
}

.v-divider {
    width: 1px;
    background: var(--border);
    flex-shrink: 0;
}

/* ── Facility Column (Storage / Launchpad) ──────────────────── */
.facility-col {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-width: 0;
}

.facility-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    height: 20px;
    margin-bottom: 4px;
}

.facility-title {
    font-size: 0.8rem;
    font-weight: 700;
    color: var(--text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.facility-title.warn { color: var(--warn); }

.facility-meta {
    font-size: 0.68rem;
    color: var(--text-dim);
    white-space: nowrap;
    margin-left: 6px;
    flex-shrink: 0;
}
.facility-meta.urgent { color: var(--expired-fg); }

/* ── Fill Bar ────────────────────────────────────────────────── */
.ratio-bar {
    height: 4px;
    background: color-mix(in srgb, black var(--bar-track-pct), transparent);
    border-radius: 2px;
    overflow: hidden;
    display: flex;
    margin-bottom: 6px;
    flex-shrink: 0;
}

.ratio-seg { height: 100%; }

.ratio-seg.mat-p0 { background: var(--mat-p0-muted); }
.ratio-seg.mat-p1 { background: var(--mat-p1-muted); }
.ratio-seg.mat-p2 { background: var(--mat-p2-muted); }

.ratio-bar.high-fill .ratio-seg.mat-p0 { background: var(--mat-p0); }
.ratio-bar.high-fill .ratio-seg.mat-p1 { background: var(--mat-p1); }
.ratio-bar.high-fill .ratio-seg.mat-p2 { background: var(--mat-p2); }

/* ── Resource List ──────────────────────────────────────────── */
.resource-list {
    display: flex;
    flex-direction: column;
    gap: 3px;
}

.resource-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: 0.78rem;
    padding-left: 10px;
    position: relative;
    gap: 4px;
}

.resource-item::before {
    content: '';
    position: absolute;
    left: 0;
    top: 50%;
    transform: translateY(-50%);
    width: 4px;
    height: 4px;
    border-radius: 50%;
}
.resource-item.mat-p0::before { background: var(--mat-p0); }
.resource-item.mat-p1::before { background: var(--mat-p1); }
.resource-item.mat-p2::before { background: var(--mat-p2); }

/* P0 with extractor count: swap the coloured dot for the number.
   width/height/border-radius revert the dot geometry; the text
   content is positioned in the same 10px left gutter. */
.resource-item.mat-p0[data-headcount]::before {
    content:       attr(data-headcount);
    background:    transparent;
    border-radius: 0;
    width:         auto;
    height:        auto;
    font-size:     0.63rem;
    font-weight:   700;
    color:         var(--mat-p0);
    line-height:   1;
}

/* P1 and P2 are the products that matter — full text brightness */
.resource-item.mat-p1 .resource-name,
.resource-item.mat-p2 .resource-name { color: var(--text); }
.resource-item.mat-p1 .resource-qty,
.resource-item.mat-p2 .resource-qty  { color: var(--text-muted); }

/* P0 is raw input — de-emphasise so P1/P2 reads as the primary info */
.resource-item.mat-p0 .resource-name   { color: var(--text-dim); }
.resource-item.mat-p0 .resource-qty    { color: var(--text-dim); }
.resource-item.mat-p0 .resource-qty strong { color: var(--text-muted); }

.resource-name {
    flex: 1;
    min-width: 0;
    color: var(--text-sub);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.resource-qty {
    flex-shrink: 0;
    color: var(--text-muted);
    font-family: ui-monospace, 'Cascadia Code', monospace;
    font-size: 0.75rem;
    text-align: right;
    white-space: nowrap;
}
.resource-qty strong {
    display: inline-block;
    width: 34px;
    color: var(--text);
    font-weight: 600;
    text-align: right;
}

/* ── P0 → P1 chain indentation ──────────────────────────────── */
/* P1 items paired with their P0 source appear indented with a └ connector,
   making the extraction → processing chain visible at a glance. */
.resource-item--child {
    padding-left: 22px;   /* 10px base for dot + 12px indent */
    opacity: 0.9;
}
.resource-item--child::before {
    left: 12px;           /* shift tier dot to match indent */
}
.resource-item--child .resource-name::before {
    content: '└ ';
    color: var(--text-dim);
    font-size: 0.8em;
}

/* ── P1 imbalance warning ────────────────────────────────────── */
/* ▼ on the high P1 (accumulating), ▲ on the low one (add heads). */
.resource-item.p1-warn .resource-name { color: var(--mat-p2); }
.p1-warn-marker {
    color: var(--mat-p2);
    font-size: 0.72em;
    margin-left: 2px;
}

/* ── ISK/day rate ────────────────────────────────────────────── */
.isk-rate {
    margin-top: 6px;
    padding-top: 5px;
    border-top: 1px solid var(--border);
    font-size: 0.73rem;
    font-weight: 700;
    color: var(--mat-p2);
    letter-spacing: 0.15px;
    white-space: nowrap;
}

/* ── Extractor Column ───────────────────────────────────────── */
.ext-col {
    display: flex;
    flex-direction: column;
    justify-content: space-around;
    width: 78px;
    flex-shrink: 0;
    padding-left: 4px;
}

.ext-box {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.ext-label {
    font-size: 0.59rem;
    color: var(--text-dim);
    text-transform: uppercase;
    font-weight: 700;
    letter-spacing: 0.5px;
}

.ext-timer {
    font-family: ui-monospace, 'Cascadia Code', monospace;
    font-size: 0.78rem;
    font-weight: 600;
    padding: 2px 6px;
    border-radius: 4px;
    background: color-mix(in srgb, var(--timer-fg) 12%, transparent);
    color: var(--timer-fg);
    text-align: center;
    width: fit-content;
}
.ext-timer.warn {
    background: color-mix(in srgb, var(--warn) 12%, transparent);
    color: var(--warn);
}
.ext-timer.urgent {
    background: color-mix(in srgb, var(--expired-fg) 10%, transparent);
    color: var(--expired-fg);
}
.ext-timer.expired {
    background: color-mix(in srgb, var(--expired-fg) 10%, transparent);
    color: var(--expired-fg);
}

/* ── Prices View ─────────────────────────────────────────────── */
.prices-view { max-width: 920px; }

.price-topbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 14px;
}

.price-updated-text {
    font-size: 0.74rem;
    color: var(--text-dim);
    white-space: nowrap;
}

.price-filter-btn { font-size: 0.74rem; padding: 4px 10px; flex-shrink: 0; }
.price-filter-btn--active {
    background: color-mix(in srgb, var(--mat-p2) 10%, transparent);
    border-color: var(--mat-p2);
    color: var(--mat-p2);
}

/* ── Prices: table ──────────────────────────────────────────── */
.price-table-wrap {
    border: 1px solid var(--border);
    border-radius: 8px;
    overflow: hidden;
    overflow-x: auto;
}

.price-table {
    width: 100%;
    border-collapse: collapse;
}

.price-th {
    background: var(--header-bg);
    padding: 7px 12px;
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.8px;
    text-transform: uppercase;
    color: var(--text-dim);
    cursor: pointer;
    user-select: none;
    white-space: nowrap;
    border-bottom: 1px solid var(--border);
    transition: color 0.12s;
}
.price-th:hover   { color: var(--text-muted); }
.price-th--active { color: var(--text-sub); }
.price-th--left   { text-align: left; }
.price-th--right  { text-align: right; }

.th-sort-arrow { color: var(--mat-p1); font-size: 0.72rem; margin-left: 2px; }

.price-row {
    border-bottom: 1px solid var(--border);
    transition: background 0.1s;
}
.price-row:last-child { border-bottom: none; }
.price-row:hover      { background: color-mix(in srgb, var(--overlay) 2.5%, transparent); }

.price-row--launchpad {
    border-left: 3px solid var(--timer-fg);
    background: color-mix(in srgb, var(--timer-fg) 6%, transparent);
}
.price-row--launchpad:hover { background: color-mix(in srgb, var(--timer-fg) 10%, transparent); }
.price-row--launchpad .price-item-name { font-weight: 700; color: var(--timer-fg); }
.price-row--launchpad .price-qty-badge { color: var(--timer-fg); }

.price-row--owned {
    border-left: 3px solid var(--mat-p2);
    background: color-mix(in srgb, var(--mat-p2) 6%, transparent);
}
.price-row--owned:hover { background: color-mix(in srgb, var(--mat-p2) 10%, transparent); }
.price-row--owned .price-item-name { font-weight: 700; color: var(--mat-p2); }

.price-row--multi { opacity: var(--multi-opacity); }
.price-row--multi:hover { opacity: 0.75; transition: opacity 0.15s; }

.price-section-divider {
    padding: 5px 16px;
    font-size: 0.65rem;
    font-weight: 700;
    letter-spacing: 1px;
    text-transform: uppercase;
    color: var(--text-dim);
    background: color-mix(in srgb, black var(--divider-pct), transparent);
    border-top: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
}

/* ── Prices: cells ──────────────────────────────────────────── */
.price-td { padding: 5px 12px; vertical-align: middle; }
.price-td--name { min-width: 155px; }
.price-td--num {
    text-align: right;
    font-family: ui-monospace, 'Cascadia Code', monospace;
    font-size: 0.78rem;
    color: var(--text-dim);
    white-space: nowrap;
}
.price-td--sorted { color: var(--text-sub); }

.price-name-wrap { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.price-item-name { color: var(--text-sub); font-size: 0.82rem; }

.price-qty-badge {
    font-size: 0.7rem;
    font-family: ui-monospace, 'Cascadia Code', monospace;
    color: var(--mat-p2);
    opacity: 0.75;
    white-space: nowrap;
}

.price-state-msg {
    display: block;
    padding: 36px 16px;
    text-align: center;
    font-size: 0.84rem;
    color: var(--text-dim);
}
.price-state-error { color: var(--expired-fg); }

.price-empty-cell {
    padding: 36px 16px;
    text-align: center;
    font-size: 0.84rem;
    color: var(--text-dim);
    font-style: italic;
}

/* ── Summary Panel ───────────────────────────────────────────── */
#summary-panel {
    margin-top: 8px;
    margin-left: 12px;
    display: flex;
    flex-direction: row;
    gap: 16px;
    align-items: flex-start;
    flex-wrap: wrap;
}

/* ── Station Assets panel ───────────────────────────────────── */

.summary-heading--flex {
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.assets-refresh-btn {
    background: none;
    border: none;
    color: var(--text-dim);
    cursor: pointer;
    font-size: 0.9rem;
    padding: 0 0 0 10px;
    line-height: 1;
    transition: color 0.15s;
}
.assets-refresh-btn:hover   { color: var(--text); }
.assets-refresh-btn:disabled { opacity: 0.4; cursor: default; }

.sum-assets-grid {
    display: grid;
    grid-template-columns: 1fr auto auto auto;
    column-gap: 16px;
    row-gap: 4px;
    align-items: baseline;
    font-size: 0.82rem;
}
.sum-assets-grid .sum-isk--amarr { color: var(--text-muted); font-weight: 500; }

/* Gas sub-label row — spans all 4 columns */
.assets-sub-label {
    grid-column: 1 / -1;
    font-size: 0.65rem;
    font-weight: 600;
    letter-spacing: 0.4px;
    text-transform: uppercase;
    color: var(--text-dim);
    margin-top: 6px;
    padding-top: 6px;
    border-top: 1px solid var(--border);
}

.assets-status {
    font-size: 0.78rem;
    color: var(--text-dim);
    font-style: italic;
    margin: 4px 0;
    min-width: 220px;
}
.assets-status--err { color: var(--expired-fg); font-style: normal; }

.assets-timestamp {
    margin-top: 8px;
    font-size: 0.68rem;
    color: var(--text-dim);
    font-style: italic;
}

.summary-wrapper {
    display: flex;
    gap: 16px;
    flex-wrap: wrap;
}

.summary-section {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 14px 18px;
}

.summary-heading {
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.8px;
    text-transform: uppercase;
    color: var(--text-dim);
    margin-bottom: 10px;
    padding-bottom: 8px;
    border-bottom: 1px solid var(--border);
}

.sum-inv-grid {
    display: grid;
    grid-template-columns: 1fr auto auto auto;
    column-gap: 16px;
    row-gap: 4px;
    align-items: baseline;
    font-size: 0.82rem;
}

.sum-inv-grid .sum-divider { grid-column: 1 / -1; }
.sum-divider {
    height: 1px;
    background: var(--border);
    margin: 3px 0;
}

.sum-name        { color: var(--text-muted); }
.sum-total-label { color: var(--text); font-weight: 600; }
.sum-total-value { color: var(--mat-p2); font-weight: 700; font-size: 0.88rem; text-align: right; }

.sum-col-header {
    font-size: 0.67rem;
    font-weight: 600;
    letter-spacing: 0.4px;
    text-transform: uppercase;
    color: var(--text-dim);
    text-align: right;
}
.sum-col-header--left { text-align: left; }

.sum-amount,
.sum-count {
    font-variant-numeric: tabular-nums;
    color: var(--text-dim);
    text-align: right;
    font-size: 0.78rem;
}

.sum-isk {
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    color: var(--text);
    text-align: right;
}

.sum-rate {
    font-variant-numeric: tabular-nums;
    font-weight: 700;
    color: var(--mat-p2);
    text-align: right;
    font-size: 0.88rem;
}

/* Best-case row: same grid columns as Total but visually muted (theoretical ceiling) */
.sum-name--best { font-style: italic; color: var(--text-dim); }

/* ── Responsive ─────────────────────────────────────────────── */

/* 3 characters: revert to 2 columns before text becomes unreadable.
   Tweak this value — raise it to switch earlier, lower it to hold
   3 columns longer. At this threshold each card is ~430px wide,
   which is the comfortable minimum for the facility column text. */
@media (max-width: 1350px) {
    .dashboard[data-char-count="3"] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 600px) {
    #app { padding: 10px; }
    /* Override all data-char-count variants — single column on mobile */
    .dashboard,
    .dashboard[data-char-count="2"],
    .dashboard[data-char-count="3"] { grid-template-columns: 1fr; gap: 12px; }
    .app-brand { font-size: 0.82rem; }
    .price-topbar { flex-direction: column; align-items: flex-start; gap: 8px; }
    .price-td, .price-th { padding-left: 10px; padding-right: 10px; }

    /* ── Hamburger menu ──────────────────────────────────────────
       The header-nav (tabs + controls) collapses into a fixed
       dropdown below the header. Tapping ☰ toggles it open/closed. */
    .header-menu-btn { display: inline-flex; }

    /* Collapsed by default; JS adds .open to show it */
    .header-nav {
        display: none;
        position: fixed;
        top: var(--header-height);
        left: 0;
        right: 0;
        z-index: 9;
        flex-direction: column;
        background: var(--header-bg);
        border-bottom: 1px solid var(--border);
        box-shadow: var(--card-shadow);
        padding-bottom: 8px;
    }
    .header-nav.open { display: flex; }

    /* Tabs: vertical list, left border replaces the bottom underline */
    .header-tabs {
        flex-direction: column;
        align-items: stretch;
        margin: 4px 0 0;
    }
    .tab-btn {
        text-align: left;
        padding: 12px 20px;
        font-size: 0.88rem;
        margin-bottom: 0;
        border-bottom: none;
        border-left: 3px solid transparent;
    }
    .tab-btn:hover  { border-left-color: var(--border); }
    .tab-btn.active { border-left-color: var(--mat-p1); border-bottom-color: transparent; }

    /* Controls: horizontal row below the tab list */
    .header-controls {
        flex-wrap: wrap;
        padding: 10px 16px 2px;
        border-top: 1px solid var(--border);
        gap: 8px;
    }
}

@media (prefers-reduced-motion: reduce) {
    .planet-card, .btn, body, .app-header { transition: none; }
}

/* ══════════════════════════════════════════════════════════════
   PI Network — production chain visualization
   ══════════════════════════════════════════════════════════════ */

/* ── View wrapper ────────────────────────────────────────────── */
.network-view {
    padding: 16px 20px 40px;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.net-hint {
    text-align: center;
    font-size: 0.7rem;
    color: var(--text-dim);
    letter-spacing: 0.01em;
}

.net-footer {
    text-align: center;
    font-size: 0.68rem;
    color: var(--text-dim);
    margin-top: 2px;
}

/* ── Bordered container (also the canvas parent) ─────────────── */
.net-wrap {
    position: relative;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 10px;
    overflow: hidden;
}

/* Canvas sits behind the column text (z-index: 1 vs columns z-index: 2) */
#net-canvas {
    position: absolute;
    inset: 0;
    pointer-events: none;
    z-index: 1;
}

/* ── Column grid ─────────────────────────────────────────────── */
.net-columns {
    display: grid;
    grid-template-columns: 0.8fr 1.1fr 1fr 1.3fr 1.35fr 1.15fr;
    position: relative;
    z-index: 2;
}

.net-col {
    padding: 14px 8px 20px;
    border-right: 1px solid var(--border);
    display: flex;
    flex-direction: column;
}

.net-col:last-child { border-right: none; }

/* ── Column header ───────────────────────────────────────────── */
.net-col-header {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    text-align: center;
    height: 56px;
    margin-bottom: 10px;
    padding-bottom: 8px;
    border-bottom: 1px solid var(--border);
    gap: 4px;
}

.net-col-header h3 {
    font-size: 0.78rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
    margin: 0;
}

.net-tier-meta {
    font-size: 0.66rem;
    font-weight: 600;
    color: var(--text-dim);
    line-height: 1.35;
}

.net-tier-time {
    color: var(--text-muted);
    font-weight: 700;
}

/* ── Item list ───────────────────────────────────────────────── */
/* padding: 0 resets the browser's default ul padding-left (40px),
   which would otherwise shift all items to the right of the column centre. */
.net-items {
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 3px;
    margin: 0;
    padding: 0;
}

.net-items li {
    text-align: center;
    color: var(--text);
    transition: color 0.12s;
}

.net-items li span {
    display: inline-block;
    font-size: 0.75rem;
    font-weight: 500;
    color: inherit;
    padding: 2px 5px;
    border-radius: 4px;
    cursor: pointer;
    user-select: none;
    white-space: nowrap;
    transition: opacity 0.15s, background 0.12s;
}

.net-items li span:hover {
    background: color-mix(in srgb, var(--overlay) 6%, transparent);
}

/* Selected item: bolder label */
.net-items li.net-current span {
    font-weight: 700;
}

/* ── Pinned (sticky) mode ────────────────────────────────────── */
/* Dim everything; only linked items stay visible */
.net-wrap.net-pinned .net-items li:not(.net-current):not(.net-linked) span {
    opacity: 0.15;
}

.net-wrap.net-pinned .net-items li.net-linked span,
.net-wrap.net-pinned .net-items li.net-current span {
    opacity: 1;
}

/* ── Responsive ──────────────────────────────────────────────── */
@media (max-width: 960px) {
    .net-columns {
        grid-template-columns: 1fr 1fr 1fr;
    }
    /* Right border removed for the 3rd and 6th columns */
    .net-col:nth-child(3),
    .net-col:nth-child(6) { border-right: none; }
    /* Top border for the second row of columns */
    .net-col:nth-child(n+4) { border-top: 1px solid var(--border); }
}

@media (max-width: 600px) {
    /* Horizontal scroll — same pattern as the prices table.
       The full 6-column chain stays intact; user swipes to read it. */
    .net-wrap { overflow-x: auto; overflow-y: hidden; }
    /* Canvas line positions are meaningless when scrolled — hide it */
    #net-canvas { display: none; }
    /* Restore the original 6-column layout; min-width keeps columns readable */
    .net-columns {
        grid-template-columns: 0.8fr 1.1fr 1fr 1.3fr 1.35fr 1.15fr;
        min-width: 680px;
    }
    /* Undo the 3-column border adjustments set by the 960px breakpoint */
    .net-col:nth-child(3)   { border-right: 1px solid var(--border); }
    .net-col:nth-child(6)   { border-right: none; }
    .net-col:nth-child(n+4) { border-top: none; }
}