Skip to content

Instantly share code, notes, and snippets.

@Avi-E-Koenig
Last active July 11, 2026 11:01
Show Gist options
  • Select an option

  • Save Avi-E-Koenig/1cb9368130bd786614fe071ea4a5f4e6 to your computer and use it in GitHub Desktop.

Select an option

Save Avi-E-Koenig/1cb9368130bd786614fe071ea4a5f4e6 to your computer and use it in GitHub Desktop.
Abyssal Basing Survey — Oijamon Sector (EVE Online): 28 large, quiet 0.6–0.7 high-sec systems ranked by 24h activity + gate distance
<!DOCTYPE html>
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><style>:root{color-scheme:light}body{margin:0;padding:0;font:14px -apple-system,BlinkMacSystemFont,sans-serif;background:#faf9f5;color:#141413}img{max-width:100%}</style></head><body>
<title>Abyssal Basing Survey — Oijamon Sector</title>
<style>
:root {
/* Light theme — "printed star atlas / nav chart on the light table" */
--ground: #e9ebf3;
--panel: #ffffff;
--panel-2: #f4f5fb;
--line: #d6d9e6;
--line-soft: #e6e8f1;
--ink: #171a29;
--ink-2: #3b3f57;
--muted: #616682;
--accent: #6d3fd1;
--accent-soft: rgba(109, 63, 209, 0.12);
--safe: #12875a;
--safe-soft: rgba(18, 135, 90, 0.13);
--caution: #9a6b12;
--caution-soft: rgba(154, 107, 18, 0.14);
--hostile: #c8304a;
--hostile-soft: rgba(200, 48, 74, 0.12);
--sec6: #8a7a00;
--sec6-soft: rgba(160, 145, 0, 0.14);
--sec7: #2f7d1e;
--sec7-soft: rgba(47, 125, 30, 0.13);
--shadow: 0 1px 2px rgba(20, 22, 40, 0.06), 0 8px 28px rgba(20, 22, 40, 0.07);
--grid-plot: rgba(23, 26, 41, 0.07);
}
@media (prefers-color-scheme: dark) {
:root {
--ground: #0a0e16;
--panel: #10141f;
--panel-2: #161b29;
--line: #262c40;
--line-soft: #1b2030;
--ink: #e4e4f0;
--ink-2: #b7bad0;
--muted: #868aa6;
--accent: #b28cff;
--accent-soft: rgba(178, 140, 255, 0.15);
--safe: #46c98f;
--safe-soft: rgba(70, 201, 143, 0.13);
--caution: #e6b23c;
--caution-soft: rgba(230, 178, 60, 0.14);
--hostile: #f0596b;
--hostile-soft: rgba(240, 89, 107, 0.14);
--sec6: #dedb2b;
--sec6-soft: rgba(222, 219, 43, 0.12);
--sec7: #86d94a;
--sec7-soft: rgba(134, 217, 74, 0.12);
--shadow: 0 1px 0 rgba(255, 255, 255, 0.02), 0 14px 40px rgba(0, 0, 0, 0.5);
--grid-plot: rgba(228, 228, 240, 0.08);
}
}
/* Explicit theme toggle must win in both directions */
:root[data-theme="light"] {
--ground: #e9ebf3; --panel: #ffffff; --panel-2: #f4f5fb; --line: #d6d9e6;
--line-soft: #e6e8f1; --ink: #171a29; --ink-2: #3b3f57; --muted: #616682;
--accent: #6d3fd1; --accent-soft: rgba(109, 63, 209, 0.12);
--safe: #12875a; --safe-soft: rgba(18, 135, 90, 0.13);
--caution: #9a6b12; --caution-soft: rgba(154, 107, 18, 0.14);
--hostile: #c8304a; --hostile-soft: rgba(200, 48, 74, 0.12);
--sec6: #8a7a00; --sec6-soft: rgba(160, 145, 0, 0.14);
--sec7: #2f7d1e; --sec7-soft: rgba(47, 125, 30, 0.13);
--shadow: 0 1px 2px rgba(20, 22, 40, 0.06), 0 8px 28px rgba(20, 22, 40, 0.07);
--grid-plot: rgba(23, 26, 41, 0.07);
}
:root[data-theme="dark"] {
--ground: #0a0e16; --panel: #10141f; --panel-2: #161b29; --line: #262c40;
--line-soft: #1b2030; --ink: #e4e4f0; --ink-2: #b7bad0; --muted: #868aa6;
--accent: #b28cff; --accent-soft: rgba(178, 140, 255, 0.15);
--safe: #46c98f; --safe-soft: rgba(70, 201, 143, 0.13);
--caution: #e6b23c; --caution-soft: rgba(230, 178, 60, 0.14);
--hostile: #f0596b; --hostile-soft: rgba(240, 89, 107, 0.14);
--sec6: #dedb2b; --sec6-soft: rgba(222, 219, 43, 0.12);
--sec7: #86d94a; --sec7-soft: rgba(134, 217, 74, 0.12);
--shadow: 0 1px 0 rgba(255, 255, 255, 0.02), 0 14px 40px rgba(0, 0, 0, 0.5);
--grid-plot: rgba(228, 228, 240, 0.08);
}
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
margin: 0;
background: var(--ground);
color: var(--ink);
font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
line-height: 1.55;
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
}
.mono { font-family: ui-monospace, "SF Mono", "Cascadia Code", "JetBrains Mono", "Roboto Mono", Menlo, Consolas, monospace; font-variant-numeric: tabular-nums; }
.wrap { max-width: 1080px; margin: 0 auto; padding: clamp(20px, 4vw, 44px) clamp(16px, 4vw, 40px) 72px; }
.eyebrow {
font-family: ui-monospace, "SF Mono", "Cascadia Code", Menlo, Consolas, monospace;
font-size: 11.5px; letter-spacing: 0.22em; text-transform: uppercase;
color: var(--accent); font-weight: 600; display: inline-flex; align-items: center; gap: 10px;
}
.eyebrow::before { content: ""; width: 22px; height: 1px; background: var(--accent); opacity: 0.6; }
h1 {
font-size: clamp(28px, 5.2vw, 46px);
line-height: 1.04; letter-spacing: -0.025em; font-weight: 800;
margin: 18px 0 0; text-wrap: balance; max-width: 20ch;
}
.lede { margin: 16px 0 0; max-width: 62ch; color: var(--ink-2); font-size: clamp(15px, 1.7vw, 17px); }
/* origin + readout strip */
.readout {
margin-top: 28px; display: grid; gap: 1px; background: var(--line);
border: 1px solid var(--line); border-radius: 12px; overflow: hidden;
grid-template-columns: repeat(4, 1fr);
}
.readout .cell { background: var(--panel); padding: 15px 18px; }
.readout .k { font-family: ui-monospace, Menlo, monospace; font-size: 10.5px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted); }
.readout .v { font-family: ui-monospace, Menlo, monospace; font-variant-numeric: tabular-nums; font-size: clamp(19px, 2.6vw, 25px); font-weight: 600; margin-top: 5px; letter-spacing: -0.01em; }
.readout .v small { font-size: 13px; color: var(--muted); font-weight: 500; }
.readout .v.accent { color: var(--accent); }
section { margin-top: clamp(40px, 6vw, 64px); }
.sec-head { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin-bottom: 18px; }
h2 { font-size: clamp(20px, 3vw, 26px); letter-spacing: -0.02em; font-weight: 750; margin: 0; }
.sec-note { color: var(--muted); font-size: 13.5px; max-width: 48ch; }
.panel { background: var(--panel); border: 1px solid var(--line); border-radius: 14px; box-shadow: var(--shadow); }
/* scatter plot */
.plot-wrap { padding: 8px 8px 4px; overflow-x: auto; }
svg.plot { display: block; width: 100%; height: auto; min-width: 560px; }
.plot text { font-family: ui-monospace, Menlo, Consolas, monospace; fill: var(--muted); }
.axis-line { stroke: var(--line); stroke-width: 1; }
.grid-line { stroke: var(--grid-plot); stroke-width: 1; }
.axis-title { fill: var(--ink-2); font-size: 12px; letter-spacing: 0.02em; }
.zone { fill: var(--accent-soft); stroke: var(--accent); stroke-width: 1; stroke-dasharray: 3 4; opacity: 0.9; }
.zone-label { fill: var(--accent); font-size: 10px; letter-spacing: 0.16em; opacity: 0.85; }
.origin-label { fill: var(--accent); font-size: 10.5px; letter-spacing: 0.1em; font-weight: 600; }
.dot { stroke: var(--panel); stroke-width: 1.5; cursor: pointer; transition: transform .12s ease; transform-box: fill-box; transform-origin: center; }
.dot:hover, .dot:focus-visible { transform: scale(1.35); outline: none; }
.dot.clear { fill: var(--safe); }
.dot.caution { fill: var(--caution); }
.dot.hostile { fill: var(--hostile); }
.pt-label { fill: var(--ink-2); font-size: 10.5px; font-weight: 500; letter-spacing: 0.01em; pointer-events: none; }
.pt-label.hostile { fill: var(--hostile); }
.legend { display: flex; flex-wrap: wrap; gap: 8px 20px; padding: 10px 18px 16px; }
.legend span { display: inline-flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--ink-2); }
.legend i { width: 11px; height: 11px; border-radius: 50%; display: inline-block; }
.tip {
position: fixed; pointer-events: none; z-index: 40; opacity: 0; transition: opacity .1s ease;
background: var(--panel-2); border: 1px solid var(--line); border-radius: 10px; padding: 11px 13px;
box-shadow: var(--shadow); max-width: 240px; transform: translate(-50%, calc(-100% - 14px));
}
.tip h4 { margin: 0; font-size: 14px; font-weight: 700; letter-spacing: -0.01em; display: flex; align-items: center; gap: 7px; }
.tip .region { color: var(--muted); font-weight: 400; font-size: 11.5px; }
.tip dl { margin: 9px 0 0; display: grid; grid-template-columns: auto auto; gap: 3px 14px; font-family: ui-monospace, Menlo, monospace; font-size: 11.5px; font-variant-numeric: tabular-nums; }
.tip dt { color: var(--muted); }
.tip dd { margin: 0; text-align: right; color: var(--ink); }
.tip .verdict { margin-top: 9px; font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; font-family: ui-monospace, Menlo, monospace; font-weight: 600; }
/* shortlist cards */
.cards { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }
.card { background: var(--panel); border: 1px solid var(--line); border-radius: 14px; padding: 18px 18px 20px; box-shadow: var(--shadow); position: relative; overflow: hidden; }
.card::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px; background: var(--safe); }
.card .rank { font-family: ui-monospace, Menlo, monospace; font-size: 10.5px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted); }
.card h3 { margin: 6px 0 2px; font-size: 21px; letter-spacing: -0.02em; }
.card .where { color: var(--muted); font-size: 12.5px; font-family: ui-monospace, Menlo, monospace; }
.card .metrics { display: flex; gap: 18px; margin: 15px 0 13px; flex-wrap: wrap; }
.card .metric .n { font-family: ui-monospace, Menlo, monospace; font-variant-numeric: tabular-nums; font-size: 20px; font-weight: 600; letter-spacing: -0.02em; }
.card .metric .n small { font-size: 11px; color: var(--muted); font-weight: 500; }
.card .metric .l { font-family: ui-monospace, Menlo, monospace; font-size: 9.5px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); margin-top: 2px; }
.card p { margin: 0; font-size: 13.5px; color: var(--ink-2); line-height: 1.5; }
/* table */
.table-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: 14px; box-shadow: var(--shadow); }
table { border-collapse: collapse; width: 100%; min-width: 760px; background: var(--panel); }
thead th {
position: sticky; top: 0; background: var(--panel-2); z-index: 2;
font-family: ui-monospace, Menlo, monospace; font-size: 10px; letter-spacing: 0.11em; text-transform: uppercase;
color: var(--muted); font-weight: 600; text-align: right; padding: 12px 14px; white-space: nowrap;
border-bottom: 1px solid var(--line); cursor: pointer; user-select: none;
}
thead th.left { text-align: left; }
thead th[aria-sort] .arrow { color: var(--accent); }
thead th .arrow { margin-left: 5px; opacity: 0.55; }
tbody td { padding: 11px 14px; text-align: right; border-bottom: 1px solid var(--line-soft); font-family: ui-monospace, Menlo, monospace; font-variant-numeric: tabular-nums; font-size: 13px; white-space: nowrap; }
tbody tr:last-child td { border-bottom: none; }
tbody tr.pick { background: var(--safe-soft); }
tbody tr:hover td { background: color-mix(in srgb, var(--accent) 6%, transparent); }
td.left { text-align: left; }
.sysname { font-family: ui-sans-serif, system-ui, sans-serif; font-weight: 650; font-size: 14px; letter-spacing: -0.01em; }
.sysname .star { color: var(--safe); margin-right: 5px; }
.region { color: var(--muted); font-size: 11px; font-family: ui-monospace, Menlo, monospace; }
.chip { display: inline-block; padding: 2px 8px; border-radius: 999px; font-size: 11px; font-weight: 600; font-family: ui-monospace, Menlo, monospace; border: 1px solid transparent; }
.chip.s6 { color: var(--sec6); background: var(--sec6-soft); border-color: color-mix(in srgb, var(--sec6) 35%, transparent); }
.chip.s7 { color: var(--sec7); background: var(--sec7-soft); border-color: color-mix(in srgb, var(--sec7) 35%, transparent); }
.threat { display: inline-flex; align-items: center; gap: 7px; justify-content: flex-end; }
.threat .dotc { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.threat.clear { color: var(--safe); } .threat.clear .dotc { background: var(--safe); }
.threat.caution { color: var(--caution); } .threat.caution .dotc { background: var(--caution); }
.threat.hostile { color: var(--hostile); } .threat.hostile .dotc { background: var(--hostile); }
.threat .kv { color: var(--muted); font-size: 11px; }
.bar { display: inline-flex; align-items: center; gap: 9px; justify-content: flex-end; }
.bar .track { width: 46px; height: 5px; border-radius: 3px; background: var(--line); overflow: hidden; }
.bar .fill { height: 100%; background: var(--accent); border-radius: 3px; }
.bar.traffic .fill { background: var(--muted); }
/* method */
.method { display: grid; gap: 18px; grid-template-columns: 1.15fr 1fr; }
.method .panel { padding: 20px 22px; }
.method h3 { margin: 0 0 12px; font-size: 13px; font-family: ui-monospace, Menlo, monospace; letter-spacing: 0.12em; text-transform: uppercase; color: var(--accent); }
.steps { margin: 0; padding: 0; list-style: none; display: grid; gap: 13px; }
.steps li { display: grid; grid-template-columns: auto 1fr; gap: 12px; font-size: 13.5px; color: var(--ink-2); }
.steps .n { font-family: ui-monospace, Menlo, monospace; color: var(--accent); font-size: 12px; font-weight: 600; padding-top: 1px; }
.steps b { color: var(--ink); font-weight: 650; }
.caveats { margin: 0; padding: 0; list-style: none; display: grid; gap: 11px; }
.caveats li { font-size: 13px; color: var(--ink-2); padding-left: 18px; position: relative; line-height: 1.5; }
.caveats li::before { content: "!"; position: absolute; left: 0; top: 0; color: var(--caution); font-family: ui-monospace, monospace; font-weight: 700; font-size: 12px; }
footer { margin-top: 56px; padding-top: 22px; border-top: 1px solid var(--line); color: var(--muted); font-size: 12px; font-family: ui-monospace, Menlo, monospace; display: flex; flex-wrap: wrap; gap: 6px 20px; justify-content: space-between; }
footer a { color: var(--accent); text-decoration: none; }
footer a:hover { text-decoration: underline; }
a:focus-visible, th:focus-visible, .dot:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
@media (max-width: 760px) {
.readout { grid-template-columns: repeat(2, 1fr); }
.method { grid-template-columns: 1fr; }
}
@media (prefers-reduced-motion: reduce) {
* { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
}
.reveal { animation: rise .6s cubic-bezier(.2,.7,.2,1) both; }
@keyframes rise { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
</style>
<div class="wrap">
<header class="reveal">
<span class="eyebrow">Astrogation · Abyssal Basing Survey</span>
<h1>A quiet, cavernous berth to run the Abyss from</h1>
<p class="lede">
Twenty-eight high-security systems (0.6–0.7) with a star-to-outer-celestial
radius over 40&nbsp;AU — enough room to tuck a safe beyond the 14.3&nbsp;AU
d-scan reach of gates and stations. Ranked by real activity and gate distance from
<b>Oijamon</b>, so size never gets mistaken for safety.
</p>
<div class="readout">
<div class="cell"><div class="k">Origin</div><div class="v accent mono">OIJAMON <small>0.8</small></div></div>
<div class="cell"><div class="k">Candidates screened</div><div class="v mono">28</div></div>
<div class="cell"><div class="k">Clear last 24&nbsp;h</div><div class="v mono">21<small> / 28</small></div></div>
<div class="cell"><div class="k">Radius floor</div><div class="v mono">40<small> AU</small></div></div>
</div>
</header>
<section aria-labelledby="field-h">
<div class="sec-head">
<h2 id="field-h">The candidate field</h2>
<p class="sec-note">Up and to the left is the geometric ideal — large and close. Colour is the
24-hour kill record, and it’s what separates a good chart position from an actual home.</p>
</div>
<div class="panel">
<div class="plot-wrap">
<svg class="plot" viewBox="0 0 820 470" role="img" aria-label="Scatter plot of candidate systems: horizontal axis is jumps from Oijamon, vertical axis is system radius in AU, colour is 24-hour threat level."><rect class="zone" x="62" y="26" width="411.75" height="231.76470588235293" rx="3"></rect><text class="zone-label" x="70" y="41">GEOMETRICALLY IDEAL</text><line class="grid-line" x1="62" y1="26" x2="62" y2="420"></line><text x="62" y="440" text-anchor="middle" font-size="11">0</text><line class="grid-line" x1="290.75" y1="26" x2="290.75" y2="420"></line><text x="290.75" y="440" text-anchor="middle" font-size="11">10</text><line class="grid-line" x1="519.5" y1="26" x2="519.5" y2="420"></line><text x="519.5" y="440" text-anchor="middle" font-size="11">20</text><line class="grid-line" x1="748.25" y1="26" x2="748.25" y2="420"></line><text x="748.25" y="440" text-anchor="middle" font-size="11">30</text><line class="grid-line" x1="62" y1="396.8235294117647" x2="794" y2="396.8235294117647"></line><text x="52" y="400.8235294117647" text-anchor="end" font-size="11">40</text><line class="grid-line" x1="62" y1="280.94117647058823" x2="794" y2="280.94117647058823"></line><text x="52" y="284.94117647058823" text-anchor="end" font-size="11">50</text><line class="grid-line" x1="62" y1="165.05882352941174" x2="794" y2="165.05882352941174"></line><text x="52" y="169.05882352941174" text-anchor="end" font-size="11">60</text><line class="grid-line" x1="62" y1="49.176470588235304" x2="794" y2="49.176470588235304"></line><text x="52" y="53.176470588235304" text-anchor="end" font-size="11">70</text><line class="axis-line" x1="62" y1="420" x2="794" y2="420"></line><line class="axis-line" x1="62" y1="26" x2="62" y2="420"></line><text class="axis-title" x="428" y="462" text-anchor="middle">JUMPS FROM OIJAMON → closer is better</text><text class="axis-title" x="16" y="223" text-anchor="middle" transform="rotate(-90 16 223)">SYSTEM RADIUS (AU) → bigger is better</text><text class="origin-label" x="65" y="414">◄ OIJAMON</text><circle class="dot clear" cx="290.75" cy="219.5235294117647" r="5" tabindex="0" role="img" aria-label="Jakanerva, radius 55.3 AU, 10 jumps from Oijamon, Clear"></circle><circle class="dot clear" cx="290.75" cy="220.68235294117645" r="7" tabindex="0" role="img" aria-label="Liukikka, radius 55.2 AU, 10 jumps from Oijamon, Clear"></circle><text class="pt-label" x="300.75" y="212.68235294117645" text-anchor="start">Liukikka</text><circle class="dot clear" cx="336.5" cy="384.0764705882353" r="5" tabindex="0" role="img" aria-label="Aharalel, radius 41.1 AU, 12 jumps from Oijamon, Clear"></circle><circle class="dot clear" cx="405.125" cy="293.68823529411765" r="5" tabindex="0" role="img" aria-label="Saana, radius 48.9 AU, 15 jumps from Oijamon, Clear"></circle><circle class="dot clear" cx="428" cy="170.8529411764706" r="5" tabindex="0" role="img" aria-label="Barkrik, radius 59.5 AU, 16 jumps from Oijamon, Clear"></circle><circle class="dot clear" cx="428" cy="194.02941176470588" r="5" tabindex="0" role="img" aria-label="Archavoinet, radius 57.5 AU, 16 jumps from Oijamon, Clear"></circle><circle class="dot clear" cx="428" cy="343.5176470588235" r="5" tabindex="0" role="img" aria-label="Madomi, radius 44.6 AU, 16 jumps from Oijamon, Clear"></circle><circle class="dot clear" cx="428" cy="359.7411764705882" r="7" tabindex="0" role="img" aria-label="Knophtikoo, radius 43.2 AU, 16 jumps from Oijamon, Clear"></circle><text class="pt-label" x="438" y="351.7411764705882" text-anchor="start">Knophtikoo</text><circle class="dot clear" cx="450.875" cy="159.26470588235293" r="5" tabindex="0" role="img" aria-label="Murini, radius 60.5 AU, 17 jumps from Oijamon, Clear"></circle><circle class="dot clear" cx="473.75" cy="64.24117647058819" r="7" tabindex="0" role="img" aria-label="Nehkiah, radius 68.7 AU, 18 jumps from Oijamon, Clear"></circle><text class="pt-label" x="483.75" y="80.24117647058819" text-anchor="start">Nehkiah</text><circle class="dot clear" cx="473.75" cy="117.54705882352948" r="5" tabindex="0" role="img" aria-label="Gedugaud, radius 64.1 AU, 18 jumps from Oijamon, Clear"></circle><circle class="dot clear" cx="473.75" cy="246.1764705882353" r="5" tabindex="0" role="img" aria-label="Jaschercis, radius 53 AU, 18 jumps from Oijamon, Clear"></circle><circle class="dot clear" cx="496.625" cy="265.8764705882353" r="5" tabindex="0" role="img" aria-label="Quier, radius 51.3 AU, 19 jumps from Oijamon, Clear"></circle><circle class="dot clear" cx="496.625" cy="326.13529411764705" r="5" tabindex="0" role="img" aria-label="Sehmosh, radius 46.1 AU, 19 jumps from Oijamon, Clear"></circle><circle class="dot clear" cx="496.625" cy="331.92941176470583" r="5" tabindex="0" role="img" aria-label="Yeder, radius 45.6 AU, 19 jumps from Oijamon, Clear"></circle><circle class="dot clear" cx="542.375" cy="306.4352941176471" r="5" tabindex="0" role="img" aria-label="Airshaz, radius 47.8 AU, 21 jumps from Oijamon, Clear"></circle><circle class="dot clear" cx="588.125" cy="89.73529411764707" r="7" tabindex="0" role="img" aria-label="Ronne, radius 66.5 AU, 23 jumps from Oijamon, Clear"></circle><text class="pt-label" x="598.125" y="105.73529411764707" text-anchor="start">Ronne</text><circle class="dot clear" cx="588.125" cy="316.86470588235295" r="5" tabindex="0" role="img" aria-label="Esescama, radius 46.9 AU, 23 jumps from Oijamon, Clear"></circle><circle class="dot clear" cx="633.875" cy="232.2705882352941" r="5" tabindex="0" role="img" aria-label="Ulerah, radius 54.2 AU, 25 jumps from Oijamon, Clear"></circle><circle class="dot clear" cx="725.375" cy="392.18823529411765" r="5" tabindex="0" role="img" aria-label="Weraroix, radius 40.4 AU, 29 jumps from Oijamon, Clear"></circle><circle class="dot clear" cx="748.25" cy="327.29411764705884" r="5" tabindex="0" role="img" aria-label="Pirohdim, radius 46 AU, 30 jumps from Oijamon, Clear"></circle><circle class="dot caution" cx="565.25" cy="180.12352941176468" r="5" tabindex="0" role="img" aria-label="Sahdil, radius 58.7 AU, 22 jumps from Oijamon, Caution"></circle><circle class="dot caution" cx="565.25" cy="300.6411764705883" r="5" tabindex="0" role="img" aria-label="Horaka, radius 48.3 AU, 22 jumps from Oijamon, Caution"></circle><circle class="dot caution" cx="130.625" cy="213.7294117647059" r="5" tabindex="0" role="img" aria-label="Kaimon, radius 55.8 AU, 3 jumps from Oijamon, Caution"></circle><text class="pt-label" x="140.625" y="205.7294117647059" text-anchor="start">Kaimon</text><circle class="dot hostile" cx="245" cy="360.9" r="6.5" tabindex="0" role="img" aria-label="Vaankalen, radius 43.1 AU, 8 jumps from Oijamon, Hostile"></circle><text class="pt-label hostile" x="255" y="352.9" text-anchor="start">Vaankalen</text><circle class="dot hostile" cx="245" cy="43.382352941176464" r="6.5" tabindex="0" role="img" aria-label="Mitsolen, radius 70.5 AU, 8 jumps from Oijamon, Hostile"></circle><text class="pt-label hostile" x="255" y="59.382352941176464" text-anchor="start">Mitsolen</text><circle class="dot hostile" cx="473.75" cy="366.6941176470588" r="6.5" tabindex="0" role="img" aria-label="Teonusude, radius 42.6 AU, 18 jumps from Oijamon, Hostile"></circle><text class="pt-label hostile" x="483.75" y="358.6941176470588" text-anchor="start">Teonusude</text><circle class="dot hostile" cx="313.625" cy="232.2705882352941" r="6.5" tabindex="0" role="img" aria-label="Korsiki, radius 54.2 AU, 11 jumps from Oijamon, Hostile"></circle><text class="pt-label hostile" x="323.625" y="224.2705882352941" text-anchor="start">Korsiki</text></svg>
</div>
<div class="legend" aria-hidden="true">
<span><i style="background:var(--safe)"></i> Clear — no kills in 24&nbsp;h</span>
<span><i style="background:var(--caution)"></i> Caution — 1–4 kills</span>
<span><i style="background:var(--hostile)"></i> Hostile — 5+ kills</span>
</div>
</div>
</section>
<section aria-labelledby="berth-h">
<div class="sec-head">
<h2 id="berth-h">Recommended berths</h2>
<p class="sec-note">Safe over 24&nbsp;hours, genuinely large, and reachable from Oijamon without wandering the map.</p>
</div>
<div class="cards" id="cards"><div class="card"><div class="rank">Berth · 0.6 sec</div>
<h3>Liukikka</h3><div class="where">Lonetrek</div>
<div class="metrics">
<div class="metric"><div class="n mono">55.2<small> AU</small></div><div class="l">Radius</div></div>
<div class="metric"><div class="n mono">10</div><div class="l">Jumps out</div></div>
<div class="metric"><div class="n mono">25<small>/h</small></div><div class="l">Traffic</div></div>
</div>
<p>Closest large system that’s truly idle — 10 jumps out, ~25 ships an hour, nothing lost in a day.</p></div><div class="card"><div class="rank">Berth · 0.7 sec</div>
<h3>Knophtikoo</h3><div class="where">Domain</div>
<div class="metrics">
<div class="metric"><div class="n mono">43.2<small> AU</small></div><div class="l">Radius</div></div>
<div class="metric"><div class="n mono">16</div><div class="l">Jumps out</div></div>
<div class="metric"><div class="n mono">10<small>/h</small></div><div class="l">Traffic</div></div>
</div>
<p>Lowest traffic of the safe set: barely 10 ships an hour drifting through a 43&nbsp;AU pocket.</p></div><div class="card"><div class="rank">Berth · 0.6 sec</div>
<h3>Nehkiah</h3><div class="where">Tash-Murkon</div>
<div class="metrics">
<div class="metric"><div class="n mono">68.7<small> AU</small></div><div class="l">Radius</div></div>
<div class="metric"><div class="n mono">18</div><div class="l">Jumps out</div></div>
<div class="metric"><div class="n mono">52<small>/h</small></div><div class="l">Traffic</div></div>
</div>
<p>The second-biggest system in the whole survey at 68.7&nbsp;AU, and clean over 24&nbsp;hours.</p></div><div class="card"><div class="rank">Berth · 0.7 sec</div>
<h3>Ronne</h3><div class="where">The Bleak Lands</div>
<div class="metrics">
<div class="metric"><div class="n mono">66.5<small> AU</small></div><div class="l">Radius</div></div>
<div class="metric"><div class="n mono">23</div><div class="l">Jumps out</div></div>
<div class="metric"><div class="n mono">36<small>/h</small></div><div class="l">Traffic</div></div>
</div>
<p>The deadest system found — zero NPC <em>and</em> zero player kills — with 66&nbsp;AU to vanish into.</p></div></div>
</section>
<section aria-labelledby="read-h">
<div class="sec-head">
<h2 id="read-h">Full readout</h2>
<p class="sec-note">All 28, safest first. Tap a column to re-sort. ★ marks a recommended berth.</p>
</div>
<div class="table-wrap">
<table>
<thead>
<tr>
<th class="left" data-key="name" data-type="str" tabindex="0">System</th>
<th data-key="secDisp" data-type="num" tabindex="0">Sec</th>
<th data-key="au" data-type="num" aria-sort="none" tabindex="0">Radius&nbsp;AU</th>
<th data-key="jumps_from_oijamon" data-type="num" tabindex="0">Jumps&nbsp;←&nbsp;Oij</th>
<th data-key="jumps" data-type="num" tabindex="0">Traffic&nbsp;/h</th>
<th data-key="npc_kills" data-type="num" tabindex="0">NPC&nbsp;/h</th>
<th data-key="k24" data-type="num" tabindex="0">Kills&nbsp;24h</th>
</tr>
</thead>
<tbody id="tbody">
<tr class="">
<td class="left"><span class="sysname">Jakanerva</span><br><span class="region">The Forge</span></td>
<td><span class="chip s7">0.7</span></td>
<td><span class="bar"><span class="track"><span class="fill" style="width:78%"></span></span>55.3</span></td>
<td>10</td>
<td><span class="bar traffic"><span class="track"><span class="fill" style="width:100%"></span></span>363</span></td>
<td>74</td>
<td><span class="threat clear"><span class="dotc"></span>Clear</span></td>
</tr>
<tr class="pick">
<td class="left"><span class="sysname"><span class="star">★</span>Liukikka</span><br><span class="region">Lonetrek</span></td>
<td><span class="chip s6">0.6</span></td>
<td><span class="bar"><span class="track"><span class="fill" style="width:78%"></span></span>55.2</span></td>
<td>10</td>
<td><span class="bar traffic"><span class="track"><span class="fill" style="width:8%"></span></span>25</span></td>
<td>110</td>
<td><span class="threat clear"><span class="dotc"></span>Clear</span></td>
</tr>
<tr class="">
<td class="left"><span class="sysname">Aharalel</span><br><span class="region">Kador</span></td>
<td><span class="chip s6">0.6</span></td>
<td><span class="bar"><span class="track"><span class="fill" style="width:58%"></span></span>41.1</span></td>
<td>12</td>
<td><span class="bar traffic"><span class="track"><span class="fill" style="width:20%"></span></span>60</span></td>
<td>115</td>
<td><span class="threat clear"><span class="dotc"></span>Clear</span></td>
</tr>
<tr class="">
<td class="left"><span class="sysname">Saana</span><br><span class="region">Domain</span></td>
<td><span class="chip s6">0.6</span></td>
<td><span class="bar"><span class="track"><span class="fill" style="width:69%"></span></span>48.9</span></td>
<td>15</td>
<td><span class="bar traffic"><span class="track"><span class="fill" style="width:13%"></span></span>40</span></td>
<td>82</td>
<td><span class="threat clear"><span class="dotc"></span>Clear</span></td>
</tr>
<tr class="">
<td class="left"><span class="sysname">Barkrik</span><br><span class="region">Metropolis</span></td>
<td><span class="chip s6">0.6</span></td>
<td><span class="bar"><span class="track"><span class="fill" style="width:84%"></span></span>59.5</span></td>
<td>16</td>
<td><span class="bar traffic"><span class="track"><span class="fill" style="width:84%"></span></span>253</span></td>
<td>616</td>
<td><span class="threat clear"><span class="dotc"></span>Clear</span></td>
</tr>
<tr class="">
<td class="left"><span class="sysname">Archavoinet</span><br><span class="region">Placid</span></td>
<td><span class="chip s6">0.6</span></td>
<td><span class="bar"><span class="track"><span class="fill" style="width:82%"></span></span>57.5</span></td>
<td>16</td>
<td><span class="bar traffic"><span class="track"><span class="fill" style="width:8%"></span></span>23</span></td>
<td>239</td>
<td><span class="threat clear"><span class="dotc"></span>Clear</span></td>
</tr>
<tr class="">
<td class="left"><span class="sysname">Madomi</span><br><span class="region">Genesis</span></td>
<td><span class="chip s6">0.6</span></td>
<td><span class="bar"><span class="track"><span class="fill" style="width:63%"></span></span>44.6</span></td>
<td>16</td>
<td><span class="bar traffic"><span class="track"><span class="fill" style="width:100%"></span></span>300</span></td>
<td>102</td>
<td><span class="threat clear"><span class="dotc"></span>Clear</span></td>
</tr>
<tr class="pick">
<td class="left"><span class="sysname"><span class="star">★</span>Knophtikoo</span><br><span class="region">Domain</span></td>
<td><span class="chip s7">0.7</span></td>
<td><span class="bar"><span class="track"><span class="fill" style="width:61%"></span></span>43.2</span></td>
<td>16</td>
<td><span class="bar traffic"><span class="track"><span class="fill" style="width:3%"></span></span>10</span></td>
<td>36</td>
<td><span class="threat clear"><span class="dotc"></span>Clear</span></td>
</tr>
<tr class="">
<td class="left"><span class="sysname">Murini</span><br><span class="region">Kador</span></td>
<td><span class="chip s6">0.6</span></td>
<td><span class="bar"><span class="track"><span class="fill" style="width:86%"></span></span>60.5</span></td>
<td>17</td>
<td><span class="bar traffic"><span class="track"><span class="fill" style="width:34%"></span></span>103</span></td>
<td>48</td>
<td><span class="threat clear"><span class="dotc"></span>Clear</span></td>
</tr>
<tr class="pick">
<td class="left"><span class="sysname"><span class="star">★</span>Nehkiah</span><br><span class="region">Tash-Murkon</span></td>
<td><span class="chip s6">0.6</span></td>
<td><span class="bar"><span class="track"><span class="fill" style="width:97%"></span></span>68.7</span></td>
<td>18</td>
<td><span class="bar traffic"><span class="track"><span class="fill" style="width:17%"></span></span>52</span></td>
<td>116</td>
<td><span class="threat clear"><span class="dotc"></span>Clear</span></td>
</tr>
<tr class="">
<td class="left"><span class="sysname">Gedugaud</span><br><span class="region">Metropolis</span></td>
<td><span class="chip s7">0.7</span></td>
<td><span class="bar"><span class="track"><span class="fill" style="width:91%"></span></span>64.1</span></td>
<td>18</td>
<td><span class="bar traffic"><span class="track"><span class="fill" style="width:66%"></span></span>197</span></td>
<td>50</td>
<td><span class="threat clear"><span class="dotc"></span>Clear</span></td>
</tr>
<tr class="">
<td class="left"><span class="sysname">Jaschercis</span><br><span class="region">Everyshore</span></td>
<td><span class="chip s6">0.6</span></td>
<td><span class="bar"><span class="track"><span class="fill" style="width:75%"></span></span>53.0</span></td>
<td>18</td>
<td><span class="bar traffic"><span class="track"><span class="fill" style="width:49%"></span></span>146</span></td>
<td>63</td>
<td><span class="threat clear"><span class="dotc"></span>Clear</span></td>
</tr>
<tr class="">
<td class="left"><span class="sysname">Quier</span><br><span class="region">Everyshore</span></td>
<td><span class="chip s7">0.7</span></td>
<td><span class="bar"><span class="track"><span class="fill" style="width:73%"></span></span>51.3</span></td>
<td>19</td>
<td><span class="bar traffic"><span class="track"><span class="fill" style="width:14%"></span></span>41</span></td>
<td>126</td>
<td><span class="threat clear"><span class="dotc"></span>Clear</span></td>
</tr>
<tr class="">
<td class="left"><span class="sysname">Sehmosh</span><br><span class="region">Tash-Murkon</span></td>
<td><span class="chip s6">0.6</span></td>
<td><span class="bar"><span class="track"><span class="fill" style="width:65%"></span></span>46.1</span></td>
<td>19</td>
<td><span class="bar traffic"><span class="track"><span class="fill" style="width:19%"></span></span>56</span></td>
<td>139</td>
<td><span class="threat clear"><span class="dotc"></span>Clear</span></td>
</tr>
<tr class="">
<td class="left"><span class="sysname">Yeder</span><br><span class="region">Tash-Murkon</span></td>
<td><span class="chip s6">0.6</span></td>
<td><span class="bar"><span class="track"><span class="fill" style="width:65%"></span></span>45.6</span></td>
<td>19</td>
<td><span class="bar traffic"><span class="track"><span class="fill" style="width:9%"></span></span>26</span></td>
<td>18</td>
<td><span class="threat clear"><span class="dotc"></span>Clear</span></td>
</tr>
<tr class="">
<td class="left"><span class="sysname">Airshaz</span><br><span class="region">Domain</span></td>
<td><span class="chip s7">0.7</span></td>
<td><span class="bar"><span class="track"><span class="fill" style="width:68%"></span></span>47.8</span></td>
<td>21</td>
<td><span class="bar traffic"><span class="track"><span class="fill" style="width:3%"></span></span>8</span></td>
<td>3</td>
<td><span class="threat clear"><span class="dotc"></span>Clear</span></td>
</tr>
<tr class="pick">
<td class="left"><span class="sysname"><span class="star">★</span>Ronne</span><br><span class="region">The Bleak Lands</span></td>
<td><span class="chip s7">0.7</span></td>
<td><span class="bar"><span class="track"><span class="fill" style="width:94%"></span></span>66.5</span></td>
<td>23</td>
<td><span class="bar traffic"><span class="track"><span class="fill" style="width:12%"></span></span>36</span></td>
<td>0</td>
<td><span class="threat clear"><span class="dotc"></span>Clear</span></td>
</tr>
<tr class="">
<td class="left"><span class="sysname">Esescama</span><br><span class="region">Devoid</span></td>
<td><span class="chip s6">0.6</span></td>
<td><span class="bar"><span class="track"><span class="fill" style="width:67%"></span></span>46.9</span></td>
<td>23</td>
<td><span class="bar traffic"><span class="track"><span class="fill" style="width:43%"></span></span>130</span></td>
<td>20</td>
<td><span class="threat clear"><span class="dotc"></span>Clear</span></td>
</tr>
<tr class="">
<td class="left"><span class="sysname">Ulerah</span><br><span class="region">Devoid</span></td>
<td><span class="chip s7">0.7</span></td>
<td><span class="bar"><span class="track"><span class="fill" style="width:77%"></span></span>54.2</span></td>
<td>25</td>
<td><span class="bar traffic"><span class="track"><span class="fill" style="width:1%"></span></span>4</span></td>
<td>40</td>
<td><span class="threat clear"><span class="dotc"></span>Clear</span></td>
</tr>
<tr class="">
<td class="left"><span class="sysname">Weraroix</span><br><span class="region">Solitude</span></td>
<td><span class="chip s6">0.6</span></td>
<td><span class="bar"><span class="track"><span class="fill" style="width:57%"></span></span>40.4</span></td>
<td>29</td>
<td><span class="bar traffic"><span class="track"><span class="fill" style="width:5%"></span></span>14</span></td>
<td>44</td>
<td><span class="threat clear"><span class="dotc"></span>Clear</span></td>
</tr>
<tr class="">
<td class="left"><span class="sysname">Pirohdim</span><br><span class="region">Derelik</span></td>
<td><span class="chip s6">0.6</span></td>
<td><span class="bar"><span class="track"><span class="fill" style="width:65%"></span></span>46.0</span></td>
<td>30</td>
<td><span class="bar traffic"><span class="track"><span class="fill" style="width:1%"></span></span>2</span></td>
<td>1</td>
<td><span class="threat clear"><span class="dotc"></span>Clear</span></td>
</tr>
<tr class="">
<td class="left"><span class="sysname">Sahdil</span><br><span class="region">Domain</span></td>
<td><span class="chip s7">0.7</span></td>
<td><span class="bar"><span class="track"><span class="fill" style="width:83%"></span></span>58.7</span></td>
<td>22</td>
<td><span class="bar traffic"><span class="track"><span class="fill" style="width:16%"></span></span>48</span></td>
<td>6</td>
<td><span class="threat caution"><span class="dotc"></span>1<span class="kv">s</span> 0<span class="kv">p</span></span></td>
</tr>
<tr class="">
<td class="left"><span class="sysname">Horaka</span><br><span class="region">Molden Heath</span></td>
<td><span class="chip s6">0.6</span></td>
<td><span class="bar"><span class="track"><span class="fill" style="width:69%"></span></span>48.3</span></td>
<td>22</td>
<td><span class="bar traffic"><span class="track"><span class="fill" style="width:14%"></span></span>42</span></td>
<td>136</td>
<td><span class="threat caution"><span class="dotc"></span>1<span class="kv">s</span> 0<span class="kv">p</span></span></td>
</tr>
<tr class="">
<td class="left"><span class="sysname">Kaimon</span><br><span class="region">The Citadel</span></td>
<td><span class="chip s7">0.7</span></td>
<td><span class="bar"><span class="track"><span class="fill" style="width:79%"></span></span>55.8</span></td>
<td>3</td>
<td><span class="bar traffic"><span class="track"><span class="fill" style="width:53%"></span></span>159</span></td>
<td>289</td>
<td><span class="threat caution"><span class="dotc"></span>2<span class="kv">s</span> 0<span class="kv">p</span></span></td>
</tr>
<tr class="">
<td class="left"><span class="sysname">Vaankalen</span><br><span class="region">The Forge</span></td>
<td><span class="chip s6">0.6</span></td>
<td><span class="bar"><span class="track"><span class="fill" style="width:61%"></span></span>43.1</span></td>
<td>8</td>
<td><span class="bar traffic"><span class="track"><span class="fill" style="width:11%"></span></span>32</span></td>
<td>178</td>
<td><span class="threat hostile"><span class="dotc"></span>9<span class="kv">s</span> 0<span class="kv">p</span></span></td>
</tr>
<tr class="">
<td class="left"><span class="sysname">Mitsolen</span><br><span class="region">The Forge</span></td>
<td><span class="chip s6">0.6</span></td>
<td><span class="bar"><span class="track"><span class="fill" style="width:100%"></span></span>70.5</span></td>
<td>8</td>
<td><span class="bar traffic"><span class="track"><span class="fill" style="width:31%"></span></span>93</span></td>
<td>166</td>
<td><span class="threat hostile"><span class="dotc"></span>17<span class="kv">s</span> 0<span class="kv">p</span></span></td>
</tr>
<tr class="">
<td class="left"><span class="sysname">Teonusude</span><br><span class="region">Molden Heath</span></td>
<td><span class="chip s6">0.6</span></td>
<td><span class="bar"><span class="track"><span class="fill" style="width:60%"></span></span>42.6</span></td>
<td>18</td>
<td><span class="bar traffic"><span class="track"><span class="fill" style="width:72%"></span></span>217</span></td>
<td>298</td>
<td><span class="threat hostile"><span class="dotc"></span>22<span class="kv">s</span> 2<span class="kv">p</span></span></td>
</tr>
<tr class="">
<td class="left"><span class="sysname">Korsiki</span><br><span class="region">The Forge</span></td>
<td><span class="chip s6">0.6</span></td>
<td><span class="bar"><span class="track"><span class="fill" style="width:77%"></span></span>54.2</span></td>
<td>11</td>
<td><span class="bar traffic"><span class="track"><span class="fill" style="width:93%"></span></span>278</span></td>
<td>621</td>
<td><span class="threat hostile"><span class="dotc"></span>26<span class="kv">s</span> 1<span class="kv">p</span></span></td>
</tr></tbody>
</table>
</div>
</section>
<section aria-labelledby="method-h">
<div class="sec-head"><h2 id="method-h">How this was found</h2></div>
<div class="method">
<div class="panel">
<h3>Data pipeline</h3>
<ol class="steps">
<li><span class="n">01</span><span><b>Physical size</b> from the Fuzzwork SDE <span class="mono">radius</span> field — metres from the star to the outermost celestial (Jita reads 24&nbsp;AU, a good sanity check).</span></li>
<li><span class="n">02</span><span><b>Live traffic &amp; NPC kills</b> from public ESI <span class="mono">system_jumps</span> / <span class="mono">system_kills</span> — a one-hour aggregate.</span></li>
<li><span class="n">03</span><span><b>24-hour player kills</b> from zKillboard, split into ship and pod losses by victim hull.</span></li>
<li><span class="n">04</span><span><b>Gate distance</b> by breadth-first search over the jump graph from Oijamon.</span></li>
</ol>
</div>
<div class="panel">
<h3>Read this with caution</h3>
<ul class="caveats">
<li>Size buys room for a safe — it does <b>not</b> stop a hunter probing your Abyssal trace directly.</li>
<li>ESI traffic is a single hour; the 24&nbsp;h kill record is a single day. Sample across your real play window before trusting it.</li>
<li>Distance is any-security routing — a path may dip through lowsec. A high-sec-only route isn’t guaranteed.</li>
<li>Player structures (Upwell) are invisible to this data, so a busy hidden Astrahus wouldn’t show here.</li>
</ul>
</div>
</div>
</section>
<footer>
<span>Snapshot 2026-07-10 · SDE 13:01 UTC · ESI hour to 15:55 UTC · zKB 24h</span>
<span>Source: <a href="https://github.com/Avi-E-Koenig/EVE-Mind/blob/main/research/ESI/abyss-home-finder.md">research/ESI/abyss-home-finder.md</a></span>
</footer>
</div>
<div class="tip" id="tip" role="status" aria-live="polite"></div>
<script>
const DATA = [
{name:"Jakanerva",sec:0.743,au:55.3,region:"The Forge",jumps:363,npc_kills:74,jumps_from_oijamon:10,s:0,p:0},
{name:"Liukikka",sec:0.564,au:55.2,region:"Lonetrek",jumps:25,npc_kills:110,jumps_from_oijamon:10,s:0,p:0},
{name:"Aharalel",sec:0.567,au:41.1,region:"Kador",jumps:60,npc_kills:115,jumps_from_oijamon:12,s:0,p:0},
{name:"Saana",sec:0.553,au:48.9,region:"Domain",jumps:40,npc_kills:82,jumps_from_oijamon:15,s:0,p:0},
{name:"Barkrik",sec:0.562,au:59.5,region:"Metropolis",jumps:253,npc_kills:616,jumps_from_oijamon:16,s:0,p:0},
{name:"Archavoinet",sec:0.621,au:57.5,region:"Placid",jumps:23,npc_kills:239,jumps_from_oijamon:16,s:0,p:0},
{name:"Madomi",sec:0.587,au:44.6,region:"Genesis",jumps:300,npc_kills:102,jumps_from_oijamon:16,s:0,p:0},
{name:"Knophtikoo",sec:0.693,au:43.2,region:"Domain",jumps:10,npc_kills:36,jumps_from_oijamon:16,s:0,p:0},
{name:"Murini",sec:0.596,au:60.5,region:"Kador",jumps:103,npc_kills:48,jumps_from_oijamon:17,s:0,p:0},
{name:"Nehkiah",sec:0.615,au:68.7,region:"Tash-Murkon",jumps:52,npc_kills:116,jumps_from_oijamon:18,s:0,p:0},
{name:"Gedugaud",sec:0.736,au:64.1,region:"Metropolis",jumps:197,npc_kills:50,jumps_from_oijamon:18,s:0,p:0},
{name:"Jaschercis",sec:0.613,au:53.0,region:"Everyshore",jumps:146,npc_kills:63,jumps_from_oijamon:18,s:0,p:0},
{name:"Quier",sec:0.734,au:51.3,region:"Everyshore",jumps:41,npc_kills:126,jumps_from_oijamon:19,s:0,p:0},
{name:"Sehmosh",sec:0.570,au:46.1,region:"Tash-Murkon",jumps:56,npc_kills:139,jumps_from_oijamon:19,s:0,p:0},
{name:"Yeder",sec:0.631,au:45.6,region:"Tash-Murkon",jumps:26,npc_kills:18,jumps_from_oijamon:19,s:0,p:0},
{name:"Airshaz",sec:0.727,au:47.8,region:"Domain",jumps:8,npc_kills:3,jumps_from_oijamon:21,s:0,p:0},
{name:"Ronne",sec:0.724,au:66.5,region:"The Bleak Lands",jumps:36,npc_kills:0,jumps_from_oijamon:23,s:0,p:0},
{name:"Esescama",sec:0.613,au:46.9,region:"Devoid",jumps:130,npc_kills:20,jumps_from_oijamon:23,s:0,p:0},
{name:"Ulerah",sec:0.681,au:54.2,region:"Devoid",jumps:4,npc_kills:40,jumps_from_oijamon:25,s:0,p:0},
{name:"Weraroix",sec:0.581,au:40.4,region:"Solitude",jumps:14,npc_kills:44,jumps_from_oijamon:29,s:0,p:0},
{name:"Pirohdim",sec:0.629,au:46.0,region:"Derelik",jumps:2,npc_kills:1,jumps_from_oijamon:30,s:0,p:0},
{name:"Sahdil",sec:0.707,au:58.7,region:"Domain",jumps:48,npc_kills:6,jumps_from_oijamon:22,s:1,p:0},
{name:"Horaka",sec:0.619,au:48.3,region:"Molden Heath",jumps:42,npc_kills:136,jumps_from_oijamon:22,s:1,p:0},
{name:"Kaimon",sec:0.686,au:55.8,region:"The Citadel",jumps:159,npc_kills:289,jumps_from_oijamon:3,s:2,p:0},
{name:"Vaankalen",sec:0.647,au:43.1,region:"The Forge",jumps:32,npc_kills:178,jumps_from_oijamon:8,s:9,p:0},
{name:"Mitsolen",sec:0.634,au:70.5,region:"The Forge",jumps:93,npc_kills:166,jumps_from_oijamon:8,s:17,p:0},
{name:"Teonusude",sec:0.586,au:42.6,region:"Molden Heath",jumps:217,npc_kills:298,jumps_from_oijamon:18,s:22,p:2},
{name:"Korsiki",sec:0.643,au:54.2,region:"The Forge",jumps:278,npc_kills:621,jumps_from_oijamon:11,s:26,p:1}
];
const PICKS = ["Liukikka","Knophtikoo","Nehkiah","Ronne"];
const WHY = {
Liukikka:"Closest large system that&rsquo;s truly idle &mdash; 10 jumps out, ~25 ships an hour, nothing lost in a day.",
Knophtikoo:"Lowest traffic of the safe set: barely 10 ships an hour drifting through a 43&nbsp;AU pocket.",
Nehkiah:"The second-biggest system in the whole survey at 68.7&nbsp;AU, and clean over 24&nbsp;hours.",
Ronne:"The deadest system found &mdash; zero NPC <em>and</em> zero player kills &mdash; with 66&nbsp;AU to vanish into."
};
DATA.forEach(d => {
d.k24 = d.s + d.p;
d.secDisp = Math.round(d.sec * 10) / 10;
d.tier = d.k24 === 0 ? "clear" : d.k24 <= 4 ? "caution" : "hostile";
d.pick = PICKS.includes(d.name);
});
const TIER_LABEL = { clear: "Clear", caution: "Caution", hostile: "Hostile" };
const NS = "http://www.w3.org/2000/svg";
const el = (t, a = {}) => { const n = document.createElementNS(NS, t); for (const k in a) n.setAttribute(k, a[k]); return n; };
/* ---- scatter ---- */
(function plot() {
const svg = document.querySelector("svg.plot");
svg.innerHTML = ""; // idempotent: avoid double-render if DOM was pre-serialized
const W = 820, H = 470, L = 62, R = 26, T = 26, B = 50;
const x0 = L, x1 = W - R, y0 = H - B, y1 = T;
const XMAX = 32, YMIN = 38, YMAX = 72;
const sx = v => x0 + (v / XMAX) * (x1 - x0);
const sy = v => y0 + ((v - YMIN) / (YMAX - YMIN)) * (y1 - y0);
// ideal zone: close (<=18 jumps) & large (>=52 AU)
svg.appendChild(el("rect", { class: "zone", x: sx(0), y: sy(YMAX), width: sx(18) - sx(0), height: sy(52) - sy(YMAX), rx: 3 }));
const zl = el("text", { class: "zone-label", x: sx(0) + 8, y: sy(YMAX) + 15 }); zl.textContent = "GEOMETRICALLY IDEAL"; svg.appendChild(zl);
// gridlines + axis ticks
for (const gx of [0, 10, 20, 30]) {
svg.appendChild(el("line", { class: "grid-line", x1: sx(gx), y1: y1, x2: sx(gx), y2: y0 }));
const t = el("text", { x: sx(gx), y: y0 + 20, "text-anchor": "middle", "font-size": 11 }); t.textContent = gx; svg.appendChild(t);
}
for (const gy of [40, 50, 60, 70]) {
svg.appendChild(el("line", { class: "grid-line", x1: x0, y1: sy(gy), x2: x1, y2: sy(gy) }));
const t = el("text", { x: x0 - 10, y: sy(gy) + 4, "text-anchor": "end", "font-size": 11 }); t.textContent = gy; svg.appendChild(t);
}
svg.appendChild(el("line", { class: "axis-line", x1: x0, y1: y0, x2: x1, y2: y0 }));
svg.appendChild(el("line", { class: "axis-line", x1: x0, y1: y1, x2: x0, y2: y0 }));
const ax = el("text", { class: "axis-title", x: (x0 + x1) / 2, y: H - 8, "text-anchor": "middle" }); ax.textContent = "JUMPS FROM OIJAMON → closer is better"; svg.appendChild(ax);
const ay = el("text", { class: "axis-title", x: 16, y: (y0 + y1) / 2, "text-anchor": "middle", transform: `rotate(-90 16 ${(y0 + y1) / 2})` }); ay.textContent = "SYSTEM RADIUS (AU) → bigger is better"; svg.appendChild(ay);
// origin anchor
const ol = el("text", { class: "origin-label", x: sx(0) + 3, y: y0 - 6 }); ol.textContent = "◄ OIJAMON"; svg.appendChild(ol);
const labelSet = new Set([...PICKS, "Mitsolen", "Korsiki", "Teonusude", "Vaankalen", "Kaimon"]);
// draw hostile last so red sits on top
[...DATA].sort((a, b) => a.k24 - b.k24).forEach(d => {
const cx = sx(d.jumps_from_oijamon), cy = sy(d.au);
const r = d.pick ? 7 : d.tier === "hostile" ? 6.5 : 5;
const c = el("circle", { class: "dot " + d.tier, cx, cy, r, tabindex: "0", role: "img", "aria-label": `${d.name}, radius ${d.au} AU, ${d.jumps_from_oijamon} jumps from Oijamon, ${TIER_LABEL[d.tier]}` });
c.addEventListener("mouseenter", e => showTip(d, e.target));
c.addEventListener("mousemove", e => moveTip(e));
c.addEventListener("mouseleave", hideTip);
c.addEventListener("focus", () => showTipAt(d, c));
c.addEventListener("blur", hideTip);
svg.appendChild(c);
if (labelSet.has(d.name)) {
const up = d.au > 66 ? 16 : -11;
const tx = el("text", { class: "pt-label" + (d.tier === "hostile" ? " hostile" : ""), x: cx + 10, y: cy + (up < 0 ? -8 : 16), "text-anchor": "start" });
tx.textContent = d.name; svg.appendChild(tx);
}
});
})();
/* ---- tooltip ---- */
const tip = document.getElementById("tip");
function tipHTML(d) {
return `<h4>${d.name} <span class="region">${d.region}</span></h4>
<dl>
<dt>Radius</dt><dd>${d.au} AU</dd>
<dt>Security</dt><dd>${d.secDisp.toFixed(1)}</dd>
<dt>From Oijamon</dt><dd>${d.jumps_from_oijamon} jumps</dd>
<dt>Traffic</dt><dd>${d.jumps}/h</dd>
<dt>NPC kills</dt><dd>${d.npc_kills}/h</dd>
<dt>Kills 24h</dt><dd>${d.s} ship · ${d.p} pod</dd>
</dl>
<div class="verdict" style="color:var(--${d.tier === 'clear' ? 'safe' : d.tier})">${TIER_LABEL[d.tier]}${d.pick ? " · recommended" : ""}</div>`;
}
let lastEvt = null;
function showTip(d, node) { tip.innerHTML = tipHTML(d); tip.style.opacity = "1"; if (lastEvt) moveTip(lastEvt); else showTipAt(d, node); }
function showTipAt(d, node) {
tip.innerHTML = tipHTML(d); tip.style.opacity = "1";
const b = node.getBoundingClientRect();
tip.style.left = (b.left + b.width / 2) + "px";
tip.style.top = b.top + "px";
}
function moveTip(e) { lastEvt = e; tip.style.left = e.clientX + "px"; tip.style.top = e.clientY + "px"; }
function hideTip() { tip.style.opacity = "0"; lastEvt = null; }
/* ---- cards ---- */
const cardWrap = document.getElementById("cards");
cardWrap.innerHTML = ""; // idempotent: avoid double-render if DOM was pre-serialized
PICKS.map(n => DATA.find(d => d.name === n)).forEach(d => {
const c = document.createElement("div"); c.className = "card";
c.innerHTML = `<div class="rank">Berth · ${d.secDisp.toFixed(1)} sec</div>
<h3>${d.name}</h3><div class="where">${d.region}</div>
<div class="metrics">
<div class="metric"><div class="n mono">${d.au}<small> AU</small></div><div class="l">Radius</div></div>
<div class="metric"><div class="n mono">${d.jumps_from_oijamon}</div><div class="l">Jumps out</div></div>
<div class="metric"><div class="n mono">${d.jumps}<small>/h</small></div><div class="l">Traffic</div></div>
</div>
<p>${WHY[d.name]}</p>`;
cardWrap.appendChild(c);
});
/* ---- table ---- */
const tbody = document.getElementById("tbody");
const maxAu = Math.max(...DATA.map(d => d.au));
const maxTraffic = 300;
function threatCell(d) {
if (d.k24 === 0) return `<span class="threat clear"><span class="dotc"></span>Clear</span>`;
return `<span class="threat ${d.tier}"><span class="dotc"></span>${d.s}<span class="kv">s</span> ${d.p}<span class="kv">p</span></span>`;
}
function render(rows) {
tbody.innerHTML = rows.map(d => `
<tr class="${d.pick ? "pick" : ""}">
<td class="left"><span class="sysname">${d.pick ? '<span class="star">&starf;</span>' : ''}${d.name}</span><br><span class="region">${d.region}</span></td>
<td><span class="chip s${d.secDisp === 0.7 ? 7 : 6}">${d.secDisp.toFixed(1)}</span></td>
<td><span class="bar"><span class="track"><span class="fill" style="width:${(d.au / maxAu * 100).toFixed(0)}%"></span></span>${d.au.toFixed(1)}</span></td>
<td>${d.jumps_from_oijamon}</td>
<td><span class="bar traffic"><span class="track"><span class="fill" style="width:${Math.min(100, d.jumps / maxTraffic * 100).toFixed(0)}%"></span></span>${d.jumps}</span></td>
<td>${d.npc_kills}</td>
<td>${threatCell(d)}</td>
</tr>`).join("");
}
const defaultOrder = DATA.map((d, i) => ({ d, i }));
let sortKey = null, sortDir = 1;
function sortRows(key, type) {
if (sortKey === key) sortDir *= -1; else { sortDir = (key === "name") ? 1 : (key === "au" || key === "secDisp") ? -1 : 1; }
sortKey = key;
const rows = [...DATA].sort((a, b) => {
let av = a[key], bv = b[key];
if (type === "str") return av.localeCompare(bv) * sortDir;
return (av - bv) * sortDir;
});
render(rows);
document.querySelectorAll("thead th").forEach(th => {
th.removeAttribute("aria-sort");
const arr = th.querySelector(".arrow"); if (arr) arr.remove();
if (th.dataset.key === key) {
th.setAttribute("aria-sort", sortDir === 1 ? "ascending" : "descending");
const a = document.createElement("span"); a.className = "arrow"; a.textContent = sortDir === 1 ? "↑" : "↓"; th.appendChild(a);
}
});
}
document.querySelectorAll("thead th").forEach(th => {
th.tabIndex = 0;
const go = () => sortRows(th.dataset.key, th.dataset.type);
th.addEventListener("click", go);
th.addEventListener("keydown", e => { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); go(); } });
});
render(DATA); // already safest-first
</script>
</body></html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment