PageSourceSearch

https://www.evesyndicates.com/pricecheck.php

html evesyndicates.com collected 2026-10-07 19:57:41 UTC 204,431 bytes, 3,883 lines download raw bytes

1<!doctype html>
2<html lang="en" data-theme="crucible">
3<head>
4  <meta charset="utf-8">
5  <meta name="viewport" content="width=device-width, initial-scale=1">
6  <title>Price Check — SolarCrucible/HighStellar Syndicates</title>
7  <meta name="theme-color" content="#231410">
8    <!-- CMS_PUBLIC_ADSENSE_V1 section=pricecheck -->
9  <meta name="evesyndicates-ad-section" content="pricecheck">
10  
10<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-6238237199007075" crossorigin="anonymous"></script>
10
11    
12  
13  
14  
15  
16    <link rel="icon" href="/assets/brand/themes/crucible/favicon.png?v=1787613252">
17  <link rel="preload" as="image" href="/assets/brand/themes/crucible/header.jpg?v=1787613252">
18    <link rel="stylesheet" href="/assets/style.css?v=1787613252">
19        <link rel="stylesheet" href="/assets/stellar_navigation.css?v=1787716059">
20          <link rel="stylesheet" href="/assets/contextual_help.css?v=1787613252">
21    <style>
22    :root{ --header-bg: url('/assets/brand/themes/crucible/header.jpg?v=1787613252'); --hero-bg: url('/assets/brand/themes/crucible/hero.jpg?v=1787613252'); }
23    
24    /* Compact character portrait + location badge (top header, right side) */
25.userbadge{display:flex; align-items:center; justify-content:flex-end; gap:12px; min-width:0; max-width:720px}
26.userbadge--link{padding:8px 10px; border-radius:18px; text-decoration:none; color:inherit; border:1px solid rgba(255,255,255,.10); background:linear-gradient(180deg, rgba(255,255,255,.10), rgba(255,255,255,.04)); box-shadow:0 12px 24px rgba(0,0,0,.26); transition:transform .15s ease, border-color .15s ease, box-shadow .15s ease, background .15s ease}
27.userbadge--link:hover,.userbadge--link:focus-visible{transform:translateY(-1px); border-color:rgba(255,255,255,.22); background:linear-gradient(180deg, rgba(255,255,255,.14), rgba(255,255,255,.06)); box-shadow:0 16px 30px rgba(0,0,0,.34); outline:none}
28.userbadge__portrait{width:48px; height:48px; border-radius:14px; flex:0 0 auto;
29  border:1px solid rgba(255,255,255,.16); background:rgba(0,0,0,.22);
30  box-shadow: 0 10px 18px rgba(0,0,0,.35);
31}
32.userbadge__meta{min-width:0; text-align:right; line-height:1.08}
33.userbadge__headline,.userbadge__corp,.userbadge__loc{white-space:nowrap; overflow:hidden; text-overflow:ellipsis; max-width:600px; display:block}
34.userbadge__headline{font-size:.86rem; font-weight:900; color:rgba(231,236,255,.98)}
35.userbadge__name{font-weight:1000}
36.userbadge__role{font-weight:800; color:rgba(231,236,255,.78)}
37.userbadge__sep{opacity:.52; margin:0 .2rem}
38.userbadge__corp{font-size:.76rem; color:rgba(231,236,255,.84)}
39.userbadge__loc{font-size:.76rem; color:rgba(231,236,255,.74)}
40.userbadge__sec{font-weight:800}
41@media (max-width: 720px){ .userbadge{max-width:420px} .userbadge__headline,.userbadge__corp,.userbadge__loc{max-width:340px} }
42@media (max-width: 520px){ .userbadge{max-width:255px} .userbadge__headline,.userbadge__corp,.userbadge__loc{max-width:185px} }
43
44
45/* CMS_HEADER_LOGOUT_BUTTON_V1: persistent sign-out action beside the pilot badge. */
46.cms-header-account{display:flex;align-items:center;justify-content:flex-end;gap:8px;min-width:0;flex:0 1 auto}
47.cms-header-logout{display:inline-flex;align-items:center;justify-content:center;gap:7px;min-height:42px;padding:0 12px;border-radius:13px;border:1px solid rgba(255,112,143,.36);background:linear-gradient(180deg,rgba(93,24,42,.68),rgba(43,11,23,.66));color:rgba(255,239,244,.98);text-decoration:none;font-size:.78rem;font-weight:950;letter-spacing:.02em;white-space:nowrap;box-shadow:inset 0 1px 0 rgba(255,255,255,.06),0 10px 24px rgba(0,0,0,.22);transition:transform .15s ease,border-color .15s ease,background .15s ease,box-shadow .15s ease}
48.cms-header-logout:hover,.cms-header-logout:focus-visible{transform:translateY(-1px);border-color:rgba(255,132,157,.70);background:linear-gradient(180deg,rgba(126,32,55,.78),rgba(58,14,29,.76));box-shadow:inset 0 1px 0 rgba(255,255,255,.08),0 13px 28px rgba(0,0,0,.30),0 0 0 1px rgba(255,112,143,.08);outline:none}
49.cms-header-logout__icon{font-size:1rem;line-height:1}
50@media (max-width: 900px){.cms-header-logout{padding:0 10px}.cms-header-logout__label{display:none}}
51@media (max-width: 560px){.cms-header-account{gap:6px}.cms-header-logout{min-width:40px;padding:0 9px}}
52
53/* CEO/COO safe role preview */
54/* CMS_VIEW_AS_HEADER_LAYER_HOTFIX_V1
55   The Stellar navigation is sticky at z-index 5000.  Keep the header in the
56   normal document flow, but raise it while its View As flyout is open and
57   allow the flyout to escape the header bounds instead of being clipped. */
58.topbar{overflow:visible!important}
59.topbar__inner{z-index:2}
60.topbar:has(.cms-view-as[open]){z-index:5100}
61.cms-view-as{position:relative;display:flex;align-items:center;z-index:1}
62.cms-view-as[open]{z-index:5200}
63.cms-view-as>summary{list-style:none;cursor:pointer;display:flex;align-items:center;justify-content:center;gap:7px;min-height:40px;min-width:86px;padding:0 12px;border-radius:12px;border:1px solid rgba(134,187,255,.35);background:rgba(73,123,190,.13);font-weight:900;font-size:12px;line-height:1.1;letter-spacing:.02em;color:#eaf4ff;white-space:nowrap}
64.cms-view-as>summary::-webkit-details-marker{display:none}
65.cms-view-as[open]>summary{border-color:rgba(134,187,255,.65);background:rgba(73,123,190,.23)}
66.cms-view-as__menu{position:absolute;right:0;top:calc(100% + 8px);z-index:5210;width:250px;padding:12px;border-radius:16px;background:linear-gradient(180deg,rgba(18,28,48,.99),rgba(8,14,27,.99));border:1px solid rgba(255,255,255,.13);box-shadow:0 20px 48px rgba(0,0,0,.5)}
67.cms-view-as__menu-title{font-weight:1000;margin-bottom:4px}.cms-view-as__menu-sub{font-size:11px;opacity:.68;line-height:1.4;margin-bottom:10px}
68.cms-view-as__menu form{display:grid;gap:7px}.cms-view-as__menu button{width:100%;text-align:left;padding:9px 11px;border-radius:10px;border:1px solid rgba(255,255,255,.1);background:rgba(255,255,255,.045);color:#eef5ff;font-weight:850;cursor:pointer}.cms-view-as__menu button:hover{background:rgba(116,177,255,.14);border-color:rgba(116,177,255,.42)}
69
70.cms-vacation-banner{position:relative;z-index:899;background:linear-gradient(90deg,rgba(23,74,110,.98),rgba(34,82,91,.98));border-top:1px solid rgba(125,220,255,.28);border-bottom:1px solid rgba(125,220,255,.32);color:#eafaff}
71.cms-vacation-banner__inner{min-height:52px;display:flex;gap:14px;align-items:center;justify-content:center;flex-wrap:wrap;padding:8px 16px;font-weight:800}.cms-vacation-banner form{margin:0}.cms-vacation-banner button{border:1px solid rgba(255,255,255,.45);background:rgba(255,255,255,.14);color:#fff;padding:8px 13px;border-radius:10px;font-weight:950;cursor:pointer}
72
73.cms-role-preview-banner{position:relative;z-index:900;background:linear-gradient(90deg,rgba(122,75,9,.98),rgba(117,45,19,.98));border-top:1px solid rgba(255,211,118,.38);border-bottom:1px solid rgba(255,211,118,.42);color:#fff4d9}
74.cms-role-preview-banner__inner{min-height:50px;display:flex;gap:14px;align-items:center;justify-content:center;flex-wrap:wrap;padding:8px 16px;font-weight:850}.cms-role-preview-banner strong{color:#fff}.cms-role-preview-banner form{margin:0}.cms-role-preview-banner button{border:1px solid rgba(255,255,255,.4);background:rgba(255,255,255,.13);color:#fff;padding:7px 12px;border-radius:10px;font-weight:950;cursor:pointer}
75@media (max-width:900px){.cms-view-as>summary{padding:0 9px}.cms-view-as__label{display:none}.cms-view-as__menu{right:-56px}}
76
77/* Hall of Fame nav pill */
78.pill--hof{
79  position:relative;
80  color:#fff7dc !important;
81  background:linear-gradient(180deg, rgba(255,221,115,.30), rgba(171,118,23,.34)) !important;
82  border:1px solid rgba(255,214,102,.58) !important;
83  box-shadow: inset 0 1px 0 rgba(255,245,200,.28), 0 8px 18px rgba(76,50,6,.24);
84  text-shadow:0 1px 0 rgba(77,45,0,.45);
85}
86.pill--hof:hover,
87.pill--hof:focus-visible{
88  background:linear-gradient(180deg, rgba(255,230,140,.38), rgba(190,132,28,.42)) !important;
89  border-color:rgba(255,224,132,.72) !important;
90  box-shadow: inset 0 1px 0 rgba(255,249,220,.34), 0 10px 22px rgba(95,63,9,.30), 0 0 0 1px rgba(255,219,112,.12);
91}
92.pill--hof::before{
93  content:'🏆';
94  margin-right:.4rem;
95}
96
97/* Global page loading overlay */
98.page-loader{position:fixed;inset:0;display:flex;align-items:center;justify-content:center;background:rgba(6,10,18,.70);backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);opacity:0;visibility:hidden;pointer-events:none;transition:opacity .18s ease, visibility .18s ease;z-index:9999;}
99.page-loader.is-visible{opacity:1;visibility:visible;pointer-events:auto;}
100.page-loader__panel{min-width:230px;max-width:min(92vw,420px);padding:18px 20px;border-radius:20px;background:linear-gradient(180deg, rgba(16,24,44,.96), rgba(9,14,27,.96));border:1px solid rgba(255,255,255,.12);box-shadow:0 18px 40px rgba(0,0,0,.45);display:flex;align-items:center;gap:14px;color:#eef3ff;}
101.page-loader__spinner{width:26px;height:26px;border-radius:999px;border:3px solid rgba(255,255,255,.18);border-top-color:#8ec5ff;animation:page-loader-spin .8s linear infinite;flex:0 0 auto;}
102.page-loader__text{font-weight:1000;letter-spacing:.02em;}
103.page-loader__sub{font-size:12px;opacity:.72;margin-top:2px;}
104@keyframes page-loader-spin{to{transform:rotate(360deg)}}
105  </style>
106</head>
107<body>
108  <header class="topbar">
109    <div class="topbar__bg" aria-hidden="true"></div>
110    <div class="topbar__inner container">
111      <a class="brandmark" href="/" aria-label="Home">
112        <img class="brandmark__logo" src="/assets/brand/themes/crucible/logo.png?v=1787613252" alt="SolarCrucible/HighStellar Syndicates">
113        <div class="brandmark__text">
114          <div class="brandmark__org">Eve Syndicates</div>
115                      <div class="brandmark__app">Corporation Management System</div>
116                  </div>
117      </a>
118
119              <div class="cms-header-search" data-stellar-header-search>
120          <span class="cms-header-search__icon" aria-hidden="true">⌕</span>
121          <input type="search" data-stellar-header-search-input placeholder="Search CMS + EVE…" aria-label="Search the Corporation Management System and EVE help" autocomplete="off" readonly>
122          <kbd>Ctrl K</kbd>
123        </div>
124        <button type="button" class="cms-header-help" data-help-open title="Help for this page" aria-label="Help for this page"><span class="cms-header-help__q" aria-hidden="true">?</span><span class="cms-header-help__label">Help</span></button>
125      
126      
127    </div>
128  </header>
129
130  
131  
132                  <section class="stellar-nav" data-stellar-nav aria-label="CMS navigation">
133      <div class="stellar-nav__stars" aria-hidden="true"></div>
134      <div class="container stellar-nav__shell stellar-nav__shell--compact">
135        <div class="stellar-nav__primary-row">
136        <nav class="stellar-nav__bar" aria-label="Primary navigation">
137                                  <details class="stellar-menu stellar-menu--cyan">
138              <summary class="stellar-menu__trigger">
139                <span class="stellar-menu__icon" aria-hidden="true">◎</span>
140                <span>Public Portal</span>
141                              </summary>
142              <div class="stellar-menu__panel">
143                <div class="stellar-menu__panel-head"><span>Public Portal</span><small>4 links</small></div>
144                <div class="stellar-menu__sections"><section class="stellar-menu__section"><div class="stellar-menu__grid">    <a class="stellar-card" href="/" data-stellar-launch data-result-type="page" data-search-title="home" data-search="home return to the eve syndicates public portal. landing portal">
145      <span class="stellar-card__icon" aria-hidden="true">⌂</span>
146      <span class="stellar-card__body">
147        <span class="stellar-card__title">Home</span>
148        <span class="stellar-card__desc">Return to the EVE Syndicates public portal.</span>              </span>
149      <span class="stellar-card__badges">
150                      </span>
151    </a>
152        <a class="stellar-card is-active" href="/pricecheck.php" data-stellar-launch data-result-type="page" data-search-title="public price check" data-search="public price check paste items and value them without logging in. market appraisal value">
153      <span class="stellar-card__icon" aria-hidden="true">◈</span>
154      <span class="stellar-card__body">
155        <span class="stellar-card__title">Public Price Check</span>
156        <span class="stellar-card__desc">Paste items and value them without logging in.</span>              </span>
157      <span class="stellar-card__badges">
158                      </span>
159    </a>
160        <a class="stellar-card" href="/onboarding/" data-stellar-launch data-result-type="page" data-search-title="apply to this corp" data-search="apply to this corp start the corporation application and onboarding flow. application recruit join">
161      <span class="stellar-card__icon" aria-hidden="true">➤</span>
162      <span class="stellar-card__body">
163        <span class="stellar-card__title">Apply to This Corp</span>
164        <span class="stellar-card__desc">Start the corporation application and onboarding flow.</span>              </span>
165      <span class="stellar-card__badges">
166                      </span>
167    </a>
168        <a class="stellar-card" href="/login.php" data-stellar-launch data-result-type="page" data-search-title="member login" data-search="member login access the cms pilot command desk. sign in sso">
169      <span class="stellar-card__icon" aria-hidden="true">⎋</span>
170      <span class="stellar-card__body">
171        <span class="stellar-card__title">Member Login</span>
172        <span class="stellar-card__desc">Access the CMS pilot command desk.</span>              </span>
173      <span class="stellar-card__badges">
174                      </span>
175    </a>
176    </div></section></div>              </div>
177            </details>
178                  </nav>
179
180        <div class="stellar-nav__actions">
181          <div class="stellar-nav__chips stellar-nav__chips--compact" aria-label="Session status">
182            <span class="stellar-chip stellar-chip--role">Public</span>
183                      </div>
184                    <button class="stellar-nav__quick" type="button" data-stellar-open-search aria-label="Search CMS"><span>Search</span><kbd>Ctrl K</kbd></button>
185          <button class="stellar-nav__mobile" type="button" data-stellar-open-drawer aria-label="Open navigation"><span></span><span></span><span></span></button>
186        </div>
187        </div>
188
189              </div>
190
191      <div class="stellar-search" data-stellar-search aria-hidden="true">
192        <div class="stellar-search__backdrop" data-stellar-close-search></div>
193        <div class="stellar-search__panel" role="dialog" aria-modal="true" aria-label="Search CMS">
194          <div class="stellar-search__head">
195            <div><strong>Search CMS + EVE</strong><small>CMS pages first, then Help, EVE knowledge, and trusted outside learning resources</small></div>
196            <button type="button" data-stellar-close-search aria-label="Close CMS search">×</button>
197          </div>
198          <label class="stellar-search__box"><span>⌕</span><input type="search" data-stellar-search-input placeholder="Search CMS or ask an EVE topic: scanning, PI, bubbles, hauling…" autocomplete="off"></label>
199          <div class="stellar-search__results" data-stellar-search-results>
200            <div class="stellar-search__prompt" data-stellar-search-prompt>
201              <strong>Search everything from one box.</strong>
202              <span>Try <b>scanning</b>, <b>referral</b>, <b>PI</b>, <b>bubbles</b>, <b>hauling</b>, <b>blueprints</b>, or the name of any CMS feature.</span>
203              <small>Results stay on Eve Syndicates first. Trusted outside EVE learning links are shown afterward.</small>
204            </div>
205                <a class="stellar-card stellar-card--compact" href="/" data-stellar-launch data-result-type="page" data-search-title="home" data-search="home return to the eve syndicates public portal. landing portal public portal">
206      <span class="stellar-card__icon" aria-hidden="true">⌂</span>
207      <span class="stellar-card__body">
208        <span class="stellar-card__title">Home</span>
209                <span class="stellar-card__context">Public Portal</span>      </span>
210      <span class="stellar-card__badges">
211                      </span>
212    </a>
213        <a class="stellar-card is-active stellar-card--compact" href="/pricecheck.php" data-stellar-launch data-result-type="page" data-search-title="public price check" data-search="public price check paste items and value them without logging in. market appraisal value public portal">
214      <span class="stellar-card__icon" aria-hidden="true">◈</span>
215      <span class="stellar-card__body">
216        <span class="stellar-card__title">Public Price Check</span>
217                <span class="stellar-card__context">Public Portal</span>      </span>
218      <span class="stellar-card__badges">
219                      </span>
220    </a>
221        <a class="stellar-card stellar-card--compact" href="/onboarding/" data-stellar-launch data-result-type="page" data-search-title="apply to this corp" data-search="apply to this corp start the corporation application and onboarding flow. application recruit join public portal">
222      <span class="stellar-card__icon" aria-hidden="true">➤</span>
223      <span class="stellar-card__body">
224        <span class="stellar-card__title">Apply to This Corp</span>
225                <span class="stellar-card__context">Public Portal</span>      </span>
226      <span class="stellar-card__badges">
227                      </span>
228    </a>
229        <a class="stellar-card stellar-card--compact" href="/login.php" data-stellar-launch data-result-type="page" data-search-title="member login" data-search="member login access the cms pilot command desk. sign in sso public portal">
230      <span class="stellar-card__icon" aria-hidden="true">⎋</span>
231      <span class="stellar-card__body">
232        <span class="stellar-card__title">Member Login</span>
233                <span class="stellar-card__context">Public Portal</span>      </span>
234      <span class="stellar-card__badges">
235                      </span>
236    </a>
237        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=how-to-use-the-cms-help-system" data-stellar-launch data-result-type="help" data-search-title="how to use the cms help system" data-search="how to use the cms help system click ? help beside a page heading or in the main header. the drawer explains the current screen without making you leave it. help question mark contextual drawer guide instructions new pilot search cms documentation knowledge base start here help guide instructions cms help">
238      <span class="stellar-card__icon" aria-hidden="true">?</span>
239      <span class="stellar-card__body">
240        <span class="stellar-card__title">How to Use the CMS Help System</span>
241                <span class="stellar-card__context">CMS Help</span>      </span>
242      <span class="stellar-card__badges">
243                <span class="stellar-card__badge">HELP</span>      </span>
244    </a>
245        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=how-to-use-search-cms" data-stellar-launch data-result-type="help" data-search-title="how to use search cms" data-search="how to use search cms press ctrl-k or click search cms, type what you are trying to do, then open the matching page or help result. search ctrl k quick launch command palette find page help article start here help guide instructions cms help">
246      <span class="stellar-card__icon" aria-hidden="true">?</span>
247      <span class="stellar-card__body">
248        <span class="stellar-card__title">How to Use Search CMS</span>
249                <span class="stellar-card__context">CMS Help</span>      </span>
250      <span class="stellar-card__badges">
251                <span class="stellar-card__badge">HELP</span>      </span>
252    </a>
253        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=start-here-what-the-cms-is-and-why-we-use-it" data-stellar-launch data-result-type="help" data-search-title="start here: what the cms is and why we use it" data-search="start here: what the cms is and why we use it the cms is the corporation&#039;s shared operations system for fleets, industry, logistics, training, records, and member workflows. use the menus or search cms to find the task you need. cms start here corporation management system overview new player start here help guide instructions cms help">
254      <span class="stellar-card__icon" aria-hidden="true">?</span>
255      <span class="stellar-card__body">
256        <span class="stellar-card__title">Start Here: What the CMS Is and Why We Use It</span>
257                <span class="stellar-card__context">CMS Help</span>      </span>
258      <span class="stellar-card__badges">
259                <span class="stellar-card__badge">HELP</span>      </span>
260    </a>
261        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=how-to-use-price-check" data-stellar-launch data-result-type="help" data-search-title="how to use price check" data-search="how to use price check paste the item list into price check, review the amarr-based values and selected percentage, then copy the result you need. price check amarr items valuation buyback isk new player support help guide instructions cms help">
262      <span class="stellar-card__icon" aria-hidden="true">?</span>
263      <span class="stellar-card__body">
264        <span class="stellar-card__title">How to Use Price Check</span>
265                <span class="stellar-card__context">CMS Help</span>      </span>
266      <span class="stellar-card__badges">
267                <span class="stellar-card__badge">HELP</span>      </span>
268    </a>
269        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=how-to-link-discord" data-stellar-launch data-result-type="help" data-search-title="how to link discord to the cms" data-search="how to link discord to the cms open discord link from your profile/pilot menu and follow the displayed linking steps so the cms can match your pilot to your discord account. discord link account channelbot pilot profile discord setup help guide instructions cms help">
270      <span class="stellar-card__icon" aria-hidden="true">?</span>
271      <span class="stellar-card__body">
272        <span class="stellar-card__title">How to Link Discord to the CMS</span>
273                <span class="stellar-card__context">CMS Help</span>      </span>
274      <span class="stellar-card__badges">
275                <span class="stellar-card__badge">HELP</span>      </span>
276    </a>
277        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=help-page-guide" data-stellar-launch data-result-type="help" data-search-title="reading cms help articles" data-search="reading cms help articles use the quick answer first, then read the full instructions or new pilot guidance only when you need more detail. help article quick answer new pilot guidance related article help center start here help guide instructions cms help">
278      <span class="stellar-card__icon" aria-hidden="true">?</span>
279      <span class="stellar-card__body">
280        <span class="stellar-card__title">Reading CMS Help Articles</span>
281                <span class="stellar-card__context">CMS Help</span>      </span>
282      <span class="stellar-card__badges">
283                <span class="stellar-card__badge">HELP</span>      </span>
284    </a>
285        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=help-assistant-status-guide" data-stellar-launch data-result-type="help" data-search-title="help assistant &amp; ticket status" data-search="help assistant &amp; ticket status use the normal help center, contextual ? help, or suggest a feature while assistant/ticket features are marked planned or disabled. help assistant ticket planned disabled support helpbot future start here help guide instructions cms help">
286      <span class="stellar-card__icon" aria-hidden="true">?</span>
287      <span class="stellar-card__body">
288        <span class="stellar-card__title">Help Assistant &amp; Ticket Status</span>
289                <span class="stellar-card__context">CMS Help</span>      </span>
290      <span class="stellar-card__badges">
291                <span class="stellar-card__badge">HELP</span>      </span>
292    </a>
293        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=onboarding-pilot-guide" data-stellar-launch data-result-type="help" data-search-title="corporation onboarding" data-search="corporation onboarding follow the current onboarding status page. complete only the step it asks for next; staff review and background-check steps can take time. onboarding application applicant background check provisional solar crucible status start here help guide instructions cms help">
294      <span class="stellar-card__icon" aria-hidden="true">?</span>
295      <span class="stellar-card__body">
296        <span class="stellar-card__title">Corporation Onboarding</span>
297                <span class="stellar-card__context">CMS Help</span>      </span>
298      <span class="stellar-card__badges">
299                <span class="stellar-card__badge">HELP</span>      </span>
300    </a>
301        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=pilot-command-desk-guide" data-stellar-launch data-result-type="help" data-search-title="pilot command desk" data-search="pilot command desk start here when you log in. use the top navigation or search cms to jump to the task you need. home pilot command desk cms navigation search ctrl k start here help guide instructions cms help">
302      <span class="stellar-card__icon" aria-hidden="true">?</span>
303      <span class="stellar-card__body">
304        <span class="stellar-card__title">Pilot Command Desk</span>
305                <span class="stellar-card__context">CMS Help</span>      </span>
306      <span class="stellar-card__badges">
307                <span class="stellar-card__badge">HELP</span>      </span>
308    </a>
309        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=provisional-dashboard-guide" data-stellar-launch data-result-type="help" data-search-title="provisional member dashboard" data-search="provisional member dashboard the provisional dashboard shows the actions and information available during the provisional period. complete checklist items and use the provided links rather than looking for hidden full-member menus. provisional member dashboard checklist discord onboarding probation start here help guide instructions cms help">
310      <span class="stellar-card__icon" aria-hidden="true">?</span>
311      <span class="stellar-card__body">
312        <span class="stellar-card__title">Provisional Member Dashboard</span>
313                <span class="stellar-card__context">CMS Help</span>      </span>
314      <span class="stellar-card__badges">
315                <span class="stellar-card__badge">HELP</span>      </span>
316    </a>
317        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-scanning-dscan-probes" data-stellar-launch data-result-type="eve" data-search-title="eve scanning: d-scan, probe scanner &amp; probes" data-search="eve scanning: d-scan, probe scanner &amp; probes use d-scan to check what is around you without launching probes. use the probe scanner with core probes to locate cosmic signatures such as relic, data, wormhole, and other scannable sites. scanning scan scanner dscan d-scan directional scanner probe probes probing probe scanner core scanner probes combat probes signatures cosmic signatures exploration alt-p eve new player knowledge help guide instructions eve knowledge">
318      <span class="stellar-card__icon" aria-hidden="true">✦</span>
319      <span class="stellar-card__body">
320        <span class="stellar-card__title">EVE Scanning: D-Scan, Probe Scanner &amp; Probes</span>
321                <span class="stellar-card__context">EVE Knowledge</span>      </span>
322      <span class="stellar-card__badges">
323                <span class="stellar-card__badge">EVE GUIDE</span>      </span>
324    </a>
325        <a class="stellar-card stellar-card--compact" href="/referrals.php" data-stellar-launch data-result-type="page" data-search-title="open referral page" data-search="open referral page share the official referral link when you want the cms to record who referred a new applicant. recruitment referrals referral recruit applicant link code attribution recruitment page feature open go to cms page">
326      <span class="stellar-card__icon" aria-hidden="true">⌂</span>
327      <span class="stellar-card__body">
328        <span class="stellar-card__title">Open Referral Page</span>
329                <span class="stellar-card__context">CMS Page</span>      </span>
330      <span class="stellar-card__badges">
331                <span class="stellar-card__badge">CMS</span>      </span>
332    </a>
333        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=referrals-guide" data-stellar-launch data-result-type="help" data-search-title="recruitment referrals" data-search="recruitment referrals share the official referral link when you want the cms to record who referred a new applicant. referral recruit applicant link code attribution recruitment corporation &amp; membership help guide instructions cms help">
334      <span class="stellar-card__icon" aria-hidden="true">?</span>
335      <span class="stellar-card__body">
336        <span class="stellar-card__title">Recruitment Referrals</span>
337                <span class="stellar-card__context">CMS Help</span>      </span>
338      <span class="stellar-card__badges">
339                <span class="stellar-card__badge">HELP</span>      </span>
340    </a>
341        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=partner-access-guide" data-stellar-launch data-result-type="help" data-search-title="partner access / branded instance request" data-search="partner access / branded instance request enter the organization and contact details, choose the type of access requested, and submit the form for leadership review. partner access branded instance alliance corporation request allowlist external organization corporation &amp; membership help guide instructions cms help">
342      <span class="stellar-card__icon" aria-hidden="true">?</span>
343      <span class="stellar-card__body">
344        <span class="stellar-card__title">Partner Access / Branded Instance Request</span>
345                <span class="stellar-card__context">CMS Help</span>      </span>
346      <span class="stellar-card__badges">
347                <span class="stellar-card__badge">HELP</span>      </span>
348    </a>
349        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-exploration-relic-data-sites" data-stellar-launch data-result-type="eve" data-search-title="exploration, relic sites &amp; data sites" data-search="exploration, relic sites &amp; data sites exploration uses probe scanning to find cosmic signatures, then analyzers to hack relic or data containers for loot. it is one of the easiest careers to begin with a small inexpensive frigate. exploration explorer relic data site sites hacking cosmic signature signatures archaeology analyzer data analyzer relic analyzer loot scan scanning eve new player knowledge help guide instructions eve knowledge">
350      <span class="stellar-card__icon" aria-hidden="true">✦</span>
351      <span class="stellar-card__body">
352        <span class="stellar-card__title">Exploration, Relic Sites &amp; Data Sites</span>
353                <span class="stellar-card__context">EVE Knowledge</span>      </span>
354      <span class="stellar-card__badges">
355                <span class="stellar-card__badge">EVE GUIDE</span>      </span>
356    </a>
357        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-hacking-basics" data-stellar-launch data-result-type="eve" data-search-title="hacking relic and data containers" data-search="hacking relic and data containers after you scan a relic or data site, approach a container, activate the correct analyzer, and complete the hacking minigame by finding and destroying the system core. hacking hack relic analyzer data analyzer virus coherence strength system core minigame exploration containers eve new player knowledge help guide instructions eve knowledge">
358      <span class="stellar-card__icon" aria-hidden="true">✦</span>
359      <span class="stellar-card__body">
360        <span class="stellar-card__title">Hacking Relic and Data Containers</span>
361                <span class="stellar-card__context">EVE Knowledge</span>      </span>
362      <span class="stellar-card__badges">
363                <span class="stellar-card__badge">EVE GUIDE</span>      </span>
364    </a>
365        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-overview-local-basics" data-stellar-launch data-result-type="eve" data-search-title="overview, local chat &amp; situational awareness" data-search="overview, local chat &amp; situational awareness your overview shows objects and pilots on grid; local shows who is in the system where local is available. together with d-scan, they are your basic awareness tools. overview local chat situational awareness neutral red blue standings grid pilots danger hostile intel eve new player knowledge help guide instructions eve knowledge">
366      <span class="stellar-card__icon" aria-hidden="true">✦</span>
367      <span class="stellar-card__body">
368        <span class="stellar-card__title">Overview, Local Chat &amp; Situational Awareness</span>
369                <span class="stellar-card__context">EVE Knowledge</span>      </span>
370      <span class="stellar-card__badges">
371                <span class="stellar-card__badge">EVE GUIDE</span>      </span>
372    </a>
373        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-bookmarks-safe-spots" data-stellar-launch data-result-type="eve" data-search-title="bookmarks, safe spots &amp; travel marks" data-search="bookmarks, safe spots &amp; travel marks bookmarks save locations in space. they are used for safe spots, gate perches, instant-dock/undock locations, wormhole entrances, tactical positions, and repeated work sites. bookmark bookmarks safe safe spot safespot perch tactical instant dock undock gate travel wormhole marks locations eve new player knowledge help guide instructions eve knowledge">
374      <span class="stellar-card__icon" aria-hidden="true">✦</span>
375      <span class="stellar-card__body">
376        <span class="stellar-card__title">Bookmarks, Safe Spots &amp; Travel Marks</span>
377                <span class="stellar-card__context">EVE Knowledge</span>      </span>
378      <span class="stellar-card__badges">
379                <span class="stellar-card__badge">EVE GUIDE</span>      </span>
380    </a>
381        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-security-space-types" data-stellar-launch data-result-type="eve" data-search-title="high-sec, low-sec, null-sec &amp; wormhole space" data-search="high-sec, low-sec, null-sec &amp; wormhole space eve space has different security rules. high-sec has concord response, low-sec has limited empire enforcement, null-sec has no concord protection, and wormholes have their own local-chat and travel risks. highsec high-sec lowsec low-sec nullsec null-sec wormhole wormholes security status concord space types dangerous space eve new player knowledge help guide instructions eve knowledge">
382      <span class="stellar-card__icon" aria-hidden="true">✦</span>
383      <span class="stellar-card__body">
384        <span class="stellar-card__title">High-Sec, Low-Sec, Null-Sec &amp; Wormhole Space</span>
385                <span class="stellar-card__context">EVE Knowledge</span>      </span>
386      <span class="stellar-card__badges">
387                <span class="stellar-card__badge">EVE GUIDE</span>      </span>
388    </a>
389        <a class="stellar-card stellar-card--compact" href="/university/" data-stellar-launch data-result-type="page" data-search-title="open thesyndicates university" data-search="open thesyndicates university warp disruption bubbles are area effects used mainly in null-sec and wormhole space to stop or alter warps. they are a major reason null-sec travel requires different habits than high-sec travel. warp bubbles &amp; interdiction bubble bubbles warp disruption interdiction interdictor dictor hic drag bubble catch bubble nullsec travel gate camp warp page feature open go to cms page">
390      <span class="stellar-card__icon" aria-hidden="true">⌂</span>
391      <span class="stellar-card__body">
392        <span class="stellar-card__title">Open TheSyndicates University</span>
393                <span class="stellar-card__context">CMS Page</span>      </span>
394      <span class="stellar-card__badges">
395                <span class="stellar-card__badge">CMS</span>      </span>
396    </a>
397        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-warp-bubbles-interdiction" data-stellar-launch data-result-type="eve" data-search-title="warp bubbles &amp; interdiction" data-search="warp bubbles &amp; interdiction warp disruption bubbles are area effects used mainly in null-sec and wormhole space to stop or alter warps. they are a major reason null-sec travel requires different habits than high-sec travel. bubble bubbles warp disruption interdiction interdictor dictor hic drag bubble catch bubble nullsec travel gate camp warp eve new player knowledge help guide instructions eve knowledge">
398      <span class="stellar-card__icon" aria-hidden="true">✦</span>
399      <span class="stellar-card__body">
400        <span class="stellar-card__title">Warp Bubbles &amp; Interdiction</span>
401                <span class="stellar-card__context">EVE Knowledge</span>      </span>
402      <span class="stellar-card__badges">
403                <span class="stellar-card__badge">EVE GUIDE</span>      </span>
404    </a>
405        <a class="stellar-card stellar-card--compact" href="/fits.php" data-stellar-launch data-result-type="page" data-search-title="open my fits" data-search="open my fits a ship fit is the combination of modules, rigs, ammunition, drones, and charges installed for a specific job. fits work best when they have one clear purpose. ship fittings: high, mid, low slots &amp; rigs fit fitting fittings modules high slot mid slot low slot rigs cpu powergrid calibration ship fit eft pyfa doctrine page feature open go to cms page">
406      <span class="stellar-card__icon" aria-hidden="true">⌂</span>
407      <span class="stellar-card__body">
408        <span class="stellar-card__title">Open My Fits</span>
409                <span class="stellar-card__context">CMS Page</span>      </span>
410      <span class="stellar-card__badges">
411                <span class="stellar-card__badge">CMS</span>      </span>
412    </a>
413        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-fittings-basics" data-stellar-launch data-result-type="eve" data-search-title="ship fittings: high, mid, low slots &amp; rigs" data-search="ship fittings: high, mid, low slots &amp; rigs a ship fit is the combination of modules, rigs, ammunition, drones, and charges installed for a specific job. fits work best when they have one clear purpose. fit fitting fittings modules high slot mid slot low slot rigs cpu powergrid calibration ship fit eft pyfa doctrine eve new player knowledge help guide instructions eve knowledge">
414      <span class="stellar-card__icon" aria-hidden="true">✦</span>
415      <span class="stellar-card__body">
416        <span class="stellar-card__title">Ship Fittings: High, Mid, Low Slots &amp; Rigs</span>
417                <span class="stellar-card__context">EVE Knowledge</span>      </span>
418      <span class="stellar-card__badges">
419                <span class="stellar-card__badge">EVE GUIDE</span>      </span>
420    </a>
421        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-capacitor-modules" data-stellar-launch data-result-type="eve" data-search-title="capacitor, module activation &amp; overheating" data-search="capacitor, module activation &amp; overheating capacitor is your ship’s energy pool for many active modules. if your capacitor reaches zero, modules that require capacitor can shut off and your escape options may disappear. capacitor cap stable module activation cycle overheating heat thermodynamics neut neutralizer energy eve new player knowledge help guide instructions eve knowledge">
422      <span class="stellar-card__icon" aria-hidden="true">✦</span>
423      <span class="stellar-card__body">
424        <span class="stellar-card__title">Capacitor, Module Activation &amp; Overheating</span>
425                <span class="stellar-card__context">EVE Knowledge</span>      </span>
426      <span class="stellar-card__badges">
427                <span class="stellar-card__badge">EVE GUIDE</span>      </span>
428    </a>
429        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-tanking-basics" data-stellar-launch data-result-type="eve" data-search-title="shield, armor &amp; hull tanking" data-search="shield, armor &amp; hull tanking tanking is how a fit survives damage. most ships focus primarily on shield or armor rather than trying to maximize every defense layer at once. tank tanking shield armor hull buffer active tank resist resistance repairer booster extender plate damage control ehp eve new player knowledge help guide instructions eve knowledge">
430      <span class="stellar-card__icon" aria-hidden="true">✦</span>
431      <span class="stellar-card__body">
432        <span class="stellar-card__title">Shield, Armor &amp; Hull Tanking</span>
433                <span class="stellar-card__context">EVE Knowledge</span>      </span>
434      <span class="stellar-card__badges">
435                <span class="stellar-card__badge">EVE GUIDE</span>      </span>
436    </a>
437        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-drones-basics" data-stellar-launch data-result-type="eve" data-search-title="drones: launching, controlling &amp; recalling" data-search="drones: launching, controlling &amp; recalling drones are small controlled craft launched from a drone bay. they can deal damage, mine, repair, jam, salvage, or perform other specialized roles depending on type. drone drones drone bay bandwidth light medium heavy mining salvage repair ecm recall launch control eve new player knowledge help guide instructions eve knowledge">
438      <span class="stellar-card__icon" aria-hidden="true">✦</span>
439      <span class="stellar-card__body">
440        <span class="stellar-card__title">Drones: Launching, Controlling &amp; Recalling</span>
441                <span class="stellar-card__context">EVE Knowledge</span>      </span>
442      <span class="stellar-card__badges">
443                <span class="stellar-card__badge">EVE GUIDE</span>      </span>
444    </a>
445        <a class="stellar-card stellar-card--compact" href="/fleets/" data-stellar-launch data-result-type="page" data-search-title="open corporation fleets" data-search="open corporation fleets mining means locking an asteroid, activating a mining laser or strip miner, and moving the ore into a hold or fleet workflow. the real skill is doing it efficiently without ignoring safety. mining basics: ore, lasers, holds &amp; safety mining mine ore asteroid mining laser strip miner venture barge exhumer yield ore hold survey scanner boosts compression page feature open go to cms page">
446      <span class="stellar-card__icon" aria-hidden="true">⌂</span>
447      <span class="stellar-card__body">
448        <span class="stellar-card__title">Open Corporation Fleets</span>
449                <span class="stellar-card__context">CMS Page</span>      </span>
450      <span class="stellar-card__badges">
451                <span class="stellar-card__badge">CMS</span>      </span>
452    </a>
453        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-mining-basics" data-stellar-launch data-result-type="eve" data-search-title="mining basics: ore, lasers, holds &amp; safety" data-search="mining basics: ore, lasers, holds &amp; safety mining means locking an asteroid, activating a mining laser or strip miner, and moving the ore into a hold or fleet workflow. the real skill is doing it efficiently without ignoring safety. mining mine ore asteroid mining laser strip miner venture barge exhumer yield ore hold survey scanner boosts compression eve new player knowledge help guide instructions eve knowledge">
454      <span class="stellar-card__icon" aria-hidden="true">✦</span>
455      <span class="stellar-card__body">
456        <span class="stellar-card__title">Mining Basics: Ore, Lasers, Holds &amp; Safety</span>
457                <span class="stellar-card__context">EVE Knowledge</span>      </span>
458      <span class="stellar-card__badges">
459                <span class="stellar-card__badge">EVE GUIDE</span>      </span>
460    </a>
461        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-reprocessing-compression" data-stellar-launch data-result-type="eve" data-search-title="ore compression &amp; reprocessing" data-search="ore compression &amp; reprocessing compression reduces the hauling volume of many resources without turning them into minerals. reprocessing converts ore or other materials into their refined outputs and can lose value if your yield or location is poor. compression compress compressed ore reprocessing refine refining minerals yield efficiency mining hauling eve new player knowledge help guide instructions eve knowledge">
462      <span class="stellar-card__icon" aria-hidden="true">✦</span>
463      <span class="stellar-card__body">
464        <span class="stellar-card__title">Ore Compression &amp; Reprocessing</span>
465                <span class="stellar-card__context">EVE Knowledge</span>      </span>
466      <span class="stellar-card__badges">
467                <span class="stellar-card__badge">EVE GUIDE</span>      </span>
468    </a>
469        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-market-orders" data-stellar-launch data-result-type="eve" data-search-title="market: buy orders, sell orders &amp; regional pricing" data-search="market: buy orders, sell orders &amp; regional pricing sell orders offer items at a price; buy orders offer isk for items. eve markets are regional, so price and availability can change dramatically from one trade hub or region to another. market buy order sell order regional market price prices station trade hub amarr jita broker fee tax order eve new player knowledge help guide instructions eve knowledge">
470      <span class="stellar-card__icon" aria-hidden="true">✦</span>
471      <span class="stellar-card__body">
472        <span class="stellar-card__title">Market: Buy Orders, Sell Orders &amp; Regional Pricing</span>
473                <span class="stellar-card__context">EVE Knowledge</span>      </span>
474      <span class="stellar-card__badges">
475                <span class="stellar-card__badge">EVE GUIDE</span>      </span>
476    </a>
477        <a class="stellar-card stellar-card--compact" href="/contracts.php" data-stellar-launch data-result-type="page" data-search-title="open contract builder" data-search="open contract builder contracts move items or isk between pilots outside the normal market. courier contracts package cargo for delivery and use collateral to protect the owner if the package is not delivered. contracts &amp; courier contracts contract contracts courier item exchange collateral reward expiration delivery hauling package accept contract corporation page feature open go to cms page">
478      <span class="stellar-card__icon" aria-hidden="true">⌂</span>
479      <span class="stellar-card__body">
480        <span class="stellar-card__title">Open Contract Builder</span>
481                <span class="stellar-card__context">CMS Page</span>      </span>
482      <span class="stellar-card__badges">
483                <span class="stellar-card__badge">CMS</span>      </span>
484    </a>
485        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-contracts-courier" data-stellar-launch data-result-type="eve" data-search-title="contracts &amp; courier contracts" data-search="contracts &amp; courier contracts contracts move items or isk between pilots outside the normal market. courier contracts package cargo for delivery and use collateral to protect the owner if the package is not delivered. contract contracts courier item exchange collateral reward expiration delivery hauling package accept contract corporation eve new player knowledge help guide instructions eve knowledge">
486      <span class="stellar-card__icon" aria-hidden="true">✦</span>
487      <span class="stellar-card__body">
488        <span class="stellar-card__title">Contracts &amp; Courier Contracts</span>
489                <span class="stellar-card__context">EVE Knowledge</span>      </span>
490      <span class="stellar-card__badges">
491                <span class="stellar-card__badge">EVE GUIDE</span>      </span>
492    </a>
493        <a class="stellar-card stellar-card--compact" href="/logistics/" data-stellar-launch data-result-type="page" data-search-title="open logistics command" data-search="open logistics command a hauling job is limited by route, cargo volume, ship capacity, risk, reward, and collateral. the cheapest route is not always the safest route. hauling, cargo volume &amp; collateral hauling haul cargo volume m3 collateral courier freight transport route reward logistics hauler page feature open go to cms page">
494      <span class="stellar-card__icon" aria-hidden="true">⌂</span>
495      <span class="stellar-card__body">
496        <span class="stellar-card__title">Open Logistics Command</span>
497                <span class="stellar-card__context">CMS Page</span>      </span>
498      <span class="stellar-card__badges">
499                <span class="stellar-card__badge">CMS</span>      </span>
500    </a>
501        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-hauling-cargo-collateral" data-stellar-launch data-result-type="eve" data-search-title="hauling, cargo volume &amp; collateral" data-search="hauling, cargo volume &amp; collateral a hauling job is limited by route, cargo volume, ship capacity, risk, reward, and collateral. the cheapest route is not always the safest route. hauling haul cargo volume m3 collateral courier freight transport route reward logistics hauler eve new player knowledge help guide instructions eve knowledge">
502      <span class="stellar-card__icon" aria-hidden="true">✦</span>
503      <span class="stellar-card__body">
504        <span class="stellar-card__title">Hauling, Cargo Volume &amp; Collateral</span>
505                <span class="stellar-card__context">EVE Knowledge</span>      </span>
506      <span class="stellar-card__badges">
507                <span class="stellar-card__badge">EVE GUIDE</span>      </span>
508    </a>
509        <a class="stellar-card stellar-card--compact" href="/manufacture/" data-stellar-launch data-result-type="page" data-search-title="open manufacturing board" data-search="open manufacturing board manufacturing turns blueprint requirements plus materials into finished items. your real cost includes materials, job fees, time, location, hauling, and any missing intermediate components. industry &amp; manufacturing basics industry manufacturing build job blueprint materials components factory production material efficiency time efficiency me te page feature open go to cms page">
510      <span class="stellar-card__icon" aria-hidden="true">⌂</span>
511      <span class="stellar-card__body">
512        <span class="stellar-card__title">Open Manufacturing Board</span>
513                <span class="stellar-card__context">CMS Page</span>      </span>
514      <span class="stellar-card__badges">
515                <span class="stellar-card__badge">CMS</span>      </span>
516    </a>
517        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-industry-manufacturing" data-stellar-launch data-result-type="eve" data-search-title="industry &amp; manufacturing basics" data-search="industry &amp; manufacturing basics manufacturing turns blueprint requirements plus materials into finished items. your real cost includes materials, job fees, time, location, hauling, and any missing intermediate components. industry manufacturing build job blueprint materials components factory production material efficiency time efficiency me te eve new player knowledge help guide instructions eve knowledge">
518      <span class="stellar-card__icon" aria-hidden="true">✦</span>
519      <span class="stellar-card__body">
520        <span class="stellar-card__title">Industry &amp; Manufacturing Basics</span>
521                <span class="stellar-card__context">EVE Knowledge</span>      </span>
522      <span class="stellar-card__badges">
523                <span class="stellar-card__badge">EVE GUIDE</span>      </span>
524    </a>
525        <a class="stellar-card stellar-card--compact" href="/blueprints/" data-stellar-launch data-result-type="page" data-search-title="open blueprint network" data-search="open blueprint network a blueprint original (bpo) can be researched and reused. a blueprint copy (bpc) has a limited number of runs. me affects material use; te affects manufacturing time. blueprints: bpos, bpcs, me &amp; te blueprint blueprints bpo bpc blueprint original copy copies runs me material efficiency te time efficiency invention page feature open go to cms page">
526      <span class="stellar-card__icon" aria-hidden="true">⌂</span>
527      <span class="stellar-card__body">
528        <span class="stellar-card__title">Open Blueprint Network</span>
529                <span class="stellar-card__context">CMS Page</span>      </span>
530      <span class="stellar-card__badges">
531                <span class="stellar-card__badge">CMS</span>      </span>
532    </a>
533        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-blueprints-bpo-bpc" data-stellar-launch data-result-type="eve" data-search-title="blueprints: bpos, bpcs, me &amp; te" data-search="blueprints: bpos, bpcs, me &amp; te a blueprint original (bpo) can be researched and reused. a blueprint copy (bpc) has a limited number of runs. me affects material use; te affects manufacturing time. blueprint blueprints bpo bpc blueprint original copy copies runs me material efficiency te time efficiency invention eve new player knowledge help guide instructions eve knowledge">
534      <span class="stellar-card__icon" aria-hidden="true">✦</span>
535      <span class="stellar-card__body">
536        <span class="stellar-card__title">Blueprints: BPOs, BPCs, ME &amp; TE</span>
537                <span class="stellar-card__context">EVE Knowledge</span>      </span>
538      <span class="stellar-card__badges">
539                <span class="stellar-card__badge">EVE GUIDE</span>      </span>
540    </a>
541        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-planetary-industry-pi" data-stellar-launch data-result-type="eve" data-search-title="planetary industry (pi) basics" data-search="planetary industry (pi) basics planetary industry extracts and processes resources on planets through command centers, extractor heads, processors, storage, and launch facilities. pi planetary industry planets command center extractor heads extraction processor processors storage launchpad p0 p1 p2 p3 p4 eve new player knowledge help guide instructions eve knowledge">
542      <span class="stellar-card__icon" aria-hidden="true">✦</span>
543      <span class="stellar-card__body">
544        <span class="stellar-card__title">Planetary Industry (PI) Basics</span>
545                <span class="stellar-card__context">EVE Knowledge</span>      </span>
546      <span class="stellar-card__badges">
547                <span class="stellar-card__badge">EVE GUIDE</span>      </span>
548    </a>
549        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-fleets-broadcasts" data-stellar-launch data-result-type="eve" data-search-title="fleets, wings, squads &amp; broadcasts" data-search="fleets, wings, squads &amp; broadcasts joining a fleet gives pilots shared organization, broadcasts, boosts, warp commands, and other coordination tools. fleet discipline matters more as the operation becomes more dangerous. fleet fleets squad wing commander fc broadcasts broadcast shield armor capacitor target warp fleet command boosts roles eve new player knowledge help guide instructions eve knowledge">
550      <span class="stellar-card__icon" aria-hidden="true">✦</span>
551      <span class="stellar-card__body">
552        <span class="stellar-card__title">Fleets, Wings, Squads &amp; Broadcasts</span>
553                <span class="stellar-card__context">EVE Knowledge</span>      </span>
554      <span class="stellar-card__badges">
555                <span class="stellar-card__badge">EVE GUIDE</span>      </span>
556    </a>
557        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-skill-training-plans" data-stellar-launch data-result-type="eve" data-search-title="skills, skill queue &amp; training plans" data-search="skills, skill queue &amp; training plans skills train in real time. a good plan trains what you need to fly and fit your next useful ship instead of chasing every skill to level v immediately. skills skill training queue skill plan plans sp skillpoints skill points level v support skills training time eve new player knowledge help guide instructions eve knowledge">
558      <span class="stellar-card__icon" aria-hidden="true">✦</span>
559      <span class="stellar-card__body">
560        <span class="stellar-card__title">Skills, Skill Queue &amp; Training Plans</span>
561                <span class="stellar-card__context">EVE Knowledge</span>      </span>
562      <span class="stellar-card__badges">
563                <span class="stellar-card__badge">EVE GUIDE</span>      </span>
564    </a>
565        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-ship-loss-insurance" data-stellar-launch data-result-type="eve" data-search-title="ship loss, insurance &amp; replacement" data-search="ship loss, insurance &amp; replacement ships in eve are consumable tools. when a ship explodes, the hull and most fitted assets are gone; some modules or cargo may drop as loot. ship loss losses insurance explode destroyed killmail kill report replacement srp ship replacement afford to lose eve new player knowledge help guide instructions eve knowledge">
566      <span class="stellar-card__icon" aria-hidden="true">✦</span>
567      <span class="stellar-card__body">
568        <span class="stellar-card__title">Ship Loss, Insurance &amp; Replacement</span>
569                <span class="stellar-card__context">EVE Knowledge</span>      </span>
570      <span class="stellar-card__badges">
571                <span class="stellar-card__badge">EVE GUIDE</span>      </span>
572    </a>
573        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-wormholes-basics" data-stellar-launch data-result-type="eve" data-search-title="wormholes: connections, polarization &amp; no normal local" data-search="wormholes: connections, polarization &amp; no normal local wormholes are temporary connections with limited mass and lifetime. local chat does not work like normal known-space local, so d-scan and probes become critical. wormhole wormholes wh jspace j-space scanning probes dscan local polarization mass lifetime connection bookmark eve new player knowledge help guide instructions eve knowledge">
574      <span class="stellar-card__icon" aria-hidden="true">✦</span>
575      <span class="stellar-card__body">
576        <span class="stellar-card__title">Wormholes: Connections, Polarization &amp; No Normal Local</span>
577                <span class="stellar-card__context">EVE Knowledge</span>      </span>
578      <span class="stellar-card__badges">
579                <span class="stellar-card__badge">EVE GUIDE</span>      </span>
580    </a>
581        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-nullsec-intel-survival" data-stellar-launch data-result-type="eve" data-search-title="null-sec survival, intel &amp; nbsi" data-search="null-sec survival, intel &amp; nbsi null-sec has no concord protection. survival depends on local/intel awareness, standings, safe travel habits, fleet communication, and understanding bubbles and gate threats. nullsec null-sec null space intel nbsi not blue shoot it local standings hostile neutral gate camp bubble alliance womp survival eve new player knowledge help guide instructions eve knowledge">
582      <span class="stellar-card__icon" aria-hidden="true">✦</span>
583      <span class="stellar-card__body">
584        <span class="stellar-card__title">Null-Sec Survival, Intel &amp; NBSI</span>
585                <span class="stellar-card__context">EVE Knowledge</span>      </span>
586      <span class="stellar-card__badges">
587                <span class="stellar-card__badge">EVE GUIDE</span>      </span>
588    </a>
589        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-terms-acronyms" data-stellar-launch data-result-type="eve" data-search-title="common eve terms &amp; acronyms" data-search="common eve terms &amp; acronyms eve players use a lot of shorthand. if a fleet or guide uses a term you do not recognize, search it here rather than guessing during an operation. terms acronyms glossary fc dps logi tackle scram point mwd ab ewar dscan pi bpo bpc me te nbsi srp cta eve slang eve new player knowledge help guide instructions eve knowledge">
590      <span class="stellar-card__icon" aria-hidden="true">✦</span>
591      <span class="stellar-card__body">
592        <span class="stellar-card__title">Common EVE Terms &amp; Acronyms</span>
593                <span class="stellar-card__context">EVE Knowledge</span>      </span>
594      <span class="stellar-card__badges">
595                <span class="stellar-card__badge">EVE GUIDE</span>      </span>
596    </a>
597        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=eve-sso-login-and-background-authorization-basics" data-stellar-launch data-result-type="help" data-search-title="eve sso login and background authorization basics" data-search="eve sso login and background authorization basics use the eve sso button and read the scopes shown by ccp before authorizing. normal login and special background-check authorization are separate flows. eve sso login background authorization scopes ccp token eve sso / login help guide instructions cms help">
598      <span class="stellar-card__icon" aria-hidden="true">?</span>
599      <span class="stellar-card__body">
600        <span class="stellar-card__title">EVE SSO Login and Background Authorization Basics</span>
601                <span class="stellar-card__context">CMS Help</span>      </span>
602      <span class="stellar-card__badges">
603                <span class="stellar-card__badge">HELP</span>      </span>
604    </a>
605        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=price-check-order-book-immediate-pricing" data-stellar-launch data-result-type="help" data-search-title="using the syndicates price check: order book &amp; immediate pricing" data-search="using the syndicates price check: order book &amp; immediate pricing immediate sell walks current buy-order price levels for your full quantity. immediate buy walks current sell-order levels. a partial fill warning means the selected hub does not currently have enough visible liquidity to fill the entire quantity at any stored order-book level. price check market appraisal immediate sell immediate buy order book liquidity fill percentage jita amarr dodixie rens hek split top buy top sell eve market public tools &amp; market intelligence help guide instructions cms help">
606      <span class="stellar-card__icon" aria-hidden="true">?</span>
607      <span class="stellar-card__body">
608        <span class="stellar-card__title">Using The Syndicates Price Check: Order Book &amp; Immediate Pricing</span>
609                <span class="stellar-card__context">CMS Help</span>      </span>
610      <span class="stellar-card__badges">
611                <span class="stellar-card__badge">HELP</span>      </span>
612    </a>
613        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=price-check-whole-appraisal-reprocessing" data-stellar-launch data-result-type="help" data-search-title="price check: whole-appraisal reprocessing" data-search="price check: whole-appraisal reprocessing enable reprocess entire appraisal, set efficiency, and click check prices. price check replaces reprocessable source items with their aggregated recovered outputs and appraises those outputs at the selected hub. incomplete portion remainders and non-reprocessable items remain in the final appraisal. price check reprocess reprocessing ore compressed ore minerals appraisal efficiency recovered output remainder public tools &amp; market intelligence help guide instructions cms help">
614      <span class="stellar-card__icon" aria-hidden="true">?</span>
615      <span class="stellar-card__body">
616        <span class="stellar-card__title">Price Check: Whole-Appraisal Reprocessing</span>
617                <span class="stellar-card__context">CMS Help</span>      </span>
618      <span class="stellar-card__badges">
619                <span class="stellar-card__badge">HELP</span>      </span>
620    </a>
621        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=price-check-market-intelligence-trends-warnings" data-stellar-launch data-result-type="help" data-search-title="price check market intelligence, trends &amp; warnings" data-search="price check market intelligence, trends &amp; warnings market intelligence describes measurable market conditions. it does not label ordinary price movement as manipulation. history-based metrics appear only after enough real daily history has accumulated in the eve syndicates market database. price check market intelligence history median trend warning spread depth vwap liquidity price impact unusual price quote confidence jita amarr dodixie rens hek public tools &amp; market intelligence help guide instructions cms help">
622      <span class="stellar-card__icon" aria-hidden="true">?</span>
623      <span class="stellar-card__body">
624        <span class="stellar-card__title">Price Check Market Intelligence, Trends &amp; Warnings</span>
625                <span class="stellar-card__context">CMS Help</span>      </span>
626      <span class="stellar-card__badges">
627                <span class="stellar-card__badge">HELP</span>      </span>
628    </a>
629        <a class="stellar-card stellar-card--compact" href="/eve-market/" data-stellar-launch data-result-type="page" data-search-title="open eve market intelligence" data-search="open eve market intelligence open eve market intelligence, search an item name or type id, then select a hub. item pages show current buy/sell, quantity-aware immediate prices, history, depth, confidence, and warnings without crowding the main price check results. public eve market item pages eve market item page market search item price jita amarr dodixie rens hek chart history order book depth immediate buy immediate sell page feature open go to cms page">
630      <span class="stellar-card__icon" aria-hidden="true">⌂</span>
631      <span class="stellar-card__body">
632        <span class="stellar-card__title">Open EVE Market Intelligence</span>
633                <span class="stellar-card__context">CMS Page</span>      </span>
634      <span class="stellar-card__badges">
635                <span class="stellar-card__badge">CMS</span>      </span>
636    </a>
637        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=public-eve-market-item-pages" data-stellar-launch data-result-type="help" data-search-title="public eve market item pages" data-search="public eve market item pages open eve market intelligence, search an item name or type id, then select a hub. item pages show current buy/sell, quantity-aware immediate prices, history, depth, confidence, and warnings without crowding the main price check results. eve market item page market search item price jita amarr dodixie rens hek chart history order book depth immediate buy immediate sell public tools &amp; market intelligence help guide instructions cms help">
638      <span class="stellar-card__icon" aria-hidden="true">?</span>
639      <span class="stellar-card__body">
640        <span class="stellar-card__title">Public EVE Market Item Pages</span>
641                <span class="stellar-card__context">CMS Help</span>      </span>
642      <span class="stellar-card__badges">
643                <span class="stellar-card__badge">HELP</span>      </span>
644    </a>
645        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=price-check-guide" data-stellar-launch data-result-type="help" data-search-title="price check" data-search="price check paste the item list, review the resolved items and totals, then adjust the permitted buyback/price options if needed. price check items amarr market buyback percent estimate paste industry help guide instructions cms help">
646      <span class="stellar-card__icon" aria-hidden="true">?</span>
647      <span class="stellar-card__body">
648        <span class="stellar-card__title">Price Check</span>
649                <span class="stellar-card__context">CMS Help</span>      </span>
650      <span class="stellar-card__badges">
651                <span class="stellar-card__badge">HELP</span>      </span>
652    </a>
653        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=how-hauling-and-logistics-work-in-the-cms" data-stellar-launch data-result-type="help" data-search-title="how hauling and logistics work in the cms" data-search="how hauling and logistics work in the cms use logistics command to see what needs action, open the run, and follow the highlighted workflow gate through assignment, contract, pickup, delivery, and payout. hauling logistics workflow courier dispatch payout run hauling / logistics help guide instructions cms help">
654      <span class="stellar-card__icon" aria-hidden="true">?</span>
655      <span class="stellar-card__body">
656        <span class="stellar-card__title">How Hauling and Logistics Work in the CMS</span>
657                <span class="stellar-card__context">CMS Help</span>      </span>
658      <span class="stellar-card__badges">
659                <span class="stellar-card__badge">HELP</span>      </span>
660    </a>
661        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=how-to-use-the-discord-helpbot" data-stellar-launch data-result-type="help" data-search-title="how to use the discord helpbot" data-search="how to use the discord helpbot use the configured discord helpbot command to search role-safe cms help articles. if the bot feature is unavailable, use search cms or the help center. discord helpbot help search role safe command discord helpbot help guide instructions cms help">
662      <span class="stellar-card__icon" aria-hidden="true">?</span>
663      <span class="stellar-card__body">
664        <span class="stellar-card__title">How to Use the Discord HelpBot</span>
665                <span class="stellar-card__context">CMS Help</span>      </span>
666      <span class="stellar-card__badges">
667                <span class="stellar-card__badge">HELP</span>      </span>
668    </a>
669        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=university-invite-guide" data-stellar-launch data-result-type="help" data-search-title="university invitation links" data-search="university invitation links a valid university invitation can still take a pilot directly into a course, but published courses no longer require an invitation for active members. university invitation invite token enrollment published course university help guide instructions cms help">
670      <span class="stellar-card__icon" aria-hidden="true">?</span>
671      <span class="stellar-card__body">
672        <span class="stellar-card__title">University Invitation Links</span>
673                <span class="stellar-card__context">CMS Help</span>      </span>
674      <span class="stellar-card__badges">
675                <span class="stellar-card__badge">HELP</span>      </span>
676    </a>
677        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=record-boards-guide" data-stellar-launch data-result-type="help" data-search-title="hall of fame &amp; record boards" data-search="hall of fame &amp; record boards use the main hall of fame for the overview, then open a specialized board for mining, fleets, pve, pvp, industry, hauling, exploration, systems, or other records. hall of fame records leaderboard mining fleet pve pvp industry hauler exploration hall of shame records &amp; achievements help guide instructions cms help">
678      <span class="stellar-card__icon" aria-hidden="true">?</span>
679      <span class="stellar-card__body">
680        <span class="stellar-card__title">Hall of Fame &amp; Record Boards</span>
681                <span class="stellar-card__context">CMS Help</span>      </span>
682      <span class="stellar-card__badges">
683                <span class="stellar-card__badge">HELP</span>      </span>
684    </a>
685        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=system-status-guide" data-stellar-launch data-result-type="help" data-search-title="cms system status" data-search="cms system status open system status when a feature looks down before repeatedly retrying actions. it can help distinguish a site-wide problem from a single record problem. status system health outage esi discord mail service troubleshooting troubleshooting help guide instructions cms help">
686      <span class="stellar-card__icon" aria-hidden="true">?</span>
687      <span class="stellar-card__body">
688        <span class="stellar-card__title">CMS System Status</span>
689                <span class="stellar-card__context">CMS Help</span>      </span>
690      <span class="stellar-card__badges">
691                <span class="stellar-card__badge">HELP</span>      </span>
692    </a>
693        <a class="stellar-card stellar-card--compact" href="/help/article.php?slug=where-to-get-help-when-something-breaks" data-stellar-launch data-result-type="help" data-search-title="where to get help when something breaks" data-search="where to get help when something breaks open ? help on the problem page, check system status when an integration may be down, then send a question/bug through the site if the issue remains. troubleshooting help broken bug question system status support troubleshooting help guide instructions cms help">
694      <span class="stellar-card__icon" aria-hidden="true">?</span>
695      <span class="stellar-card__body">
696        <span class="stellar-card__title">Where to Get Help When Something Breaks</span>
697                <span class="stellar-card__context">CMS Help</span>      </span>
698      <span class="stellar-card__badges">
699                <span class="stellar-card__badge">HELP</span>      </span>
700    </a>
701        <a class="stellar-card stellar-card--compact" href="https://wiki.eveuniversity.org/Directional_scanning" data-stellar-launch data-result-type="external" data-search-title="directional scanning" data-search="directional scanning current guide to d-scan mechanics, range, angle, and practical use. scanning scan dscan d-scan directional scanner hunting safety eve university article eve university" target="_blank" rel="noopener noreferrer">
702      <span class="stellar-card__icon" aria-hidden="true">↗</span>
703      <span class="stellar-card__body">
704        <span class="stellar-card__title">Directional scanning</span>
705                <span class="stellar-card__context">EVE University</span>      </span>
706      <span class="stellar-card__badges">
707                <span class="stellar-card__badge">WEB</span>      </span>
708    </a>
709        <a class="stellar-card stellar-card--compact" href="https://wiki.eveuniversity.org/Probing_In_Simple_Steps" data-stellar-launch data-result-type="external" data-search-title="probing in simple steps" data-search="probing in simple steps beginner steps for core probe launchers, scanner probes, and resolving signatures. scanning probes probing core scanner probe signatures exploration eve university article eve university" target="_blank" rel="noopener noreferrer">
710      <span class="stellar-card__icon" aria-hidden="true">↗</span>
711      <span class="stellar-card__body">
712        <span class="stellar-card__title">Probing In Simple Steps</span>
713                <span class="stellar-card__context">EVE University</span>      </span>
714      <span class="stellar-card__badges">
715                <span class="stellar-card__badge">WEB</span>      </span>
716    </a>
717        <a class="stellar-card stellar-card--compact" href="https://www.eveonline.com/eve-academy/careers/explorer" data-stellar-launch data-result-type="external" data-search-title="explorer - eve academy" data-search="explorer - eve academy official beginner career page for scanning, hacking, ships, and exploration. exploration scanning hacking relic data probes beginner explorer ccp / eve online official guide ccp / eve online" target="_blank" rel="noopener noreferrer">
718      <span class="stellar-card__icon" aria-hidden="true">↗</span>
719      <span class="stellar-card__body">
720        <span class="stellar-card__title">Explorer - EVE Academy</span>
721                <span class="stellar-card__context">CCP / EVE Online</span>      </span>
722      <span class="stellar-card__badges">
723                <span class="stellar-card__badge">WEB</span>      </span>
724    </a>
725        <a class="stellar-card stellar-card--compact" href="https://wiki.eveuniversity.org/Category:Exploration" data-stellar-launch data-result-type="external" data-search-title="exploration articles" data-search="exploration articles collection of exploration, scanning, hacking, and cosmic-signature guides. exploration scanning hacking relic data wormhole signatures eve university resource collection eve university" target="_blank" rel="noopener noreferrer">
726      <span class="stellar-card__icon" aria-hidden="true">↗</span>
727      <span class="stellar-card__body">
728        <span class="stellar-card__title">Exploration articles</span>
729                <span class="stellar-card__context">EVE University</span>      </span>
730      <span class="stellar-card__badges">
731                <span class="stellar-card__badge">WEB</span>      </span>
732    </a>
733        <a class="stellar-card stellar-card--compact" href="https://wiki.eveuniversity.org/Mining" data-stellar-launch data-result-type="external" data-search-title="mining" data-search="mining mining overview including ships, resources, and operating considerations. mining ore asteroid barge exhumer venture compression reprocessing eve university article eve university" target="_blank" rel="noopener noreferrer">
734      <span class="stellar-card__icon" aria-hidden="true">↗</span>
735      <span class="stellar-card__body">
736        <span class="stellar-card__title">Mining</span>
737                <span class="stellar-card__context">EVE University</span>      </span>
738      <span class="stellar-card__badges">
739                <span class="stellar-card__badge">WEB</span>      </span>
740    </a>
741        <a class="stellar-card stellar-card--compact" href="https://www.eveonline.com/eve-academy/careers/industrialist" data-stellar-launch data-result-type="external" data-search-title="industrialist - eve academy" data-search="industrialist - eve academy official beginner material for mining, production, trade, and industry careers. industry manufacturing mining market hauling blueprints industrialist ccp / eve online official guide ccp / eve online" target="_blank" rel="noopener noreferrer">
742      <span class="stellar-card__icon" aria-hidden="true">↗</span>
743      <span class="stellar-card__body">
744        <span class="stellar-card__title">Industrialist - EVE Academy</span>
745                <span class="stellar-card__context">CCP / EVE Online</span>      </span>
746      <span class="stellar-card__badges">
747                <span class="stellar-card__badge">WEB</span>      </span>
748    </a>
749                <div class="stellar-search__empty" data-stellar-search-empty hidden>No matching Eve Syndicates page or local guide was found. Try the outside EVE learning searches below.</div>
750          </div>
751        </div>
752      </div>
753
754      <aside class="stellar-drawer" data-stellar-drawer aria-hidden="true">
755        <div class="stellar-drawer__backdrop" data-stellar-close-drawer></div>
756        <div class="stellar-drawer__panel" role="dialog" aria-modal="true" aria-label="Mobile navigation">
757          <div class="stellar-drawer__head"><strong>CMS Navigation</strong><button type="button" data-stellar-close-drawer aria-label="Close navigation">×</button></div>
758          <button class="stellar-drawer__search" type="button" data-stellar-open-search>⌕ Search CMS + EVE <kbd>Ctrl K</kbd></button>
759                                <section class="stellar-drawer__group"><h3>◎ Public Portal</h3>
760                  <a class="stellar-card stellar-card--compact" href="/" data-stellar-launch data-result-type="page" data-search-title="home" data-search="home return to the eve syndicates public portal. landing portal">
761      <span class="stellar-card__icon" aria-hidden="true">⌂</span>
762      <span class="stellar-card__body">
763        <span class="stellar-card__title">Home</span>
764                      </span>
765      <span class="stellar-card__badges">
766                      </span>
767    </a>
768        <a class="stellar-card is-active stellar-card--compact" href="/pricecheck.php" data-stellar-launch data-result-type="page" data-search-title="public price check" data-search="public price check paste items and value them without logging in. market appraisal value">
769      <span class="stellar-card__icon" aria-hidden="true">◈</span>
770      <span class="stellar-card__body">
771        <span class="stellar-card__title">Public Price Check</span>
772                      </span>
773      <span class="stellar-card__badges">
774                      </span>
775    </a>
776        <a class="stellar-card stellar-card--compact" href="/onboarding/" data-stellar-launch data-result-type="page" data-search-title="apply to this corp" data-search="apply to this corp start the corporation application and onboarding flow. application recruit join">
777      <span class="stellar-card__icon" aria-hidden="true">➤</span>
778      <span class="stellar-card__body">
779        <span class="stellar-card__title">Apply to This Corp</span>
780                      </span>
781      <span class="stellar-card__badges">
782                      </span>
783    </a>
784        <a class="stellar-card stellar-card--compact" href="/login.php" data-stellar-launch data-result-type="page" data-search-title="member login" data-search="member login access the cms pilot command desk. sign in sso">
785      <span class="stellar-card__icon" aria-hidden="true">⎋</span>
786      <span class="stellar-card__body">
787        <span class="stellar-card__title">Member Login</span>
788                      </span>
789      <span class="stellar-card__badges">
790                      </span>
791    </a>
792                </section>
793                  </div>
794      </aside>
795    </section>
796          
797  
798  <main class="container content">
799  
800
801<style>
802  /* Price Check: "cool slider" */
803  .pctslider input[type=range]{
804    width:100%;
805    height:12px;
806    border-radius:999px;
807    border:1px solid var(--border);
808    background:linear-gradient(90deg, rgba(255,90,90,.28), rgba(255,255,255,.08), rgba(90,255,180,.22));
809    outline:none;
810  }
811  .pctslider input[type=range]::-webkit-slider-thumb{
812    -webkit-appearance:none;
813    appearance:none;
814    width:18px;
815    height:18px;
816    border-radius:999px;
817    background:var(--accent);
818    border:2px solid rgba(0,0,0,.28);
819    box-shadow:0 6px 16px rgba(0,0,0,.35);
820    cursor:pointer;
821  }
822  .pctslider input[type=range]::-moz-range-thumb{
823    width:18px;
824    height:18px;
825    border-radius:999px;
826    background:var(--accent);
827    border:2px solid rgba(0,0,0,.28);
828    box-shadow:0 6px 16px rgba(0,0,0,.35);
829    cursor:pointer;
830  }
831  .pctpresets{ display:flex; flex-wrap:wrap; gap:8px; margin-top:10px; }
832
833/* Recent checks badges */
834.pc-badges{ display:flex; flex-wrap:wrap; gap:8px; }
835.pc-badge{
836  appearance:none;
837  border:1px solid var(--border);
838  background:rgba(255,255,255,.04);
839  color:var(--text);
840  border-radius:999px;
841  padding:6px 10px;
842  font-size:12px;
843  line-height:1;
844  cursor:pointer;
845  transition:transform .06s ease, background .12s ease, border-color .12s ease;
846}
847.pc-badge:hover{ background:rgba(255,255,255,.07); border-color:rgba(255,255,255,.18); }
848.pc-badge:active{ transform:translateY(1px); }
849.pc-badge strong{ font-weight:700; }
850
851/* Multi-hub totals badges */
852.hubtotals{
853  display:grid;
854  grid-template-columns: repeat(5, minmax(0, 1fr));
855  gap:10px;
856  margin-top:12px;
857}
858@media (max-width: 980px){
859  .hubtotals{ grid-template-columns: repeat(2, minmax(0, 1fr)); }
860}
861@media (max-width: 560px){
862  .hubtotals{ grid-template-columns: 1fr; }
863}
864.hubbadge{
865  border:1px solid var(--border);
866  background:rgba(255,255,255,.04);
867  border-radius:14px;
868  padding:10px 12px;
869  min-height:70px;
870}
871.hubbadge.active{
872  border-color:rgba(255,255,255,.20);
873  box-shadow:0 0 0 1px rgba(255,255,255,.06) inset;
874}
875.hubbadge .h-title{
876  display:flex;
877  justify-content:space-between;
878  align-items:baseline;
879  gap:10px;
880  font-weight:800;
881}
882.hubbadge .h-sub{
883  margin-top:6px;
884  display:flex;
885  justify-content:space-between;
886  gap:10px;
887  font-size:12px;
888  color:var(--muted);
889}
890.hubbadge .h-val{
891  font-weight:800;
892  color:var(--text);
893}
894.pc-immediate-line{margin-top:5px;display:flex;flex-wrap:wrap;gap:5px 8px;font-size:11px;color:var(--muted)}
895.pc-immediate-pill{display:inline-flex;align-items:center;gap:4px;border:1px solid var(--border);border-radius:999px;padding:3px 7px;background:rgba(255,255,255,.035)}
896.pc-immediate-pill strong{color:var(--text)}
897.pc-immediate-pill.warn{border-color:rgba(243,200,96,.45);color:#ffe29b;background:rgba(243,200,96,.07)}
898.pc-totalblock.immediate{border-color:rgba(92,190,255,.30);background:rgba(92,190,255,.06)}
899.hubbadge .h-sub.immediate{color:var(--text);font-weight:750}
900
901
902  /* Results totals (center + copy) */
903  .pc-results-head{ display:flex; flex-direction:column; gap:10px; }
904  .pc-totals{ display:flex; flex-wrap:wrap; justify-content:center; align-items:center; gap:12px; text-align:center; }
905  .pc-totalblock{ display:flex; align-items:baseline; gap:8px; padding:8px 10px; border:1px solid var(--border); background:rgba(255,255,255,.04); border-radius:14px; }
906  .pc-totalblock .lbl{ font-size:12px; letter-spacing:.10em; text-transform:uppercase; font-weight:900; color:var(--muted); }
907  .pc-totalblock .val{ font-size:20px; font-weight:900; color:var(--text); }
908  .pc-copybtn{ padding:4px 8px !important; font-size:11px !important; line-height:1 !important; border-radius:999px !important; }
909  .pc-totals-meta{ flex-basis:100%; margin-top:-4px; }
910  @media (max-width:560px){ .pc-totalblock .val{ font-size:18px; } }
911  .pc-recycle-row>td{padding:0 0 10px !important;border-top:0 !important;background:transparent !important}
912  .pc-recycle{margin:0;width:100%;box-sizing:border-box;border:1px solid rgba(255,255,255,.16);background:rgba(255,255,255,.035);border-radius:10px;padding:8px 10px;transition:border-color .12s ease,background .12s ease}
913  .pc-recycle summary{cursor:pointer;font-size:12px;font-weight:850;color:var(--text);display:flex;gap:8px;align-items:center;justify-content:space-between;flex-wrap:wrap}
914  .pc-recycle-summary-value{font-weight:900;color:var(--muted)}
915  .pc-recycle.positive{border-color:rgba(55,210,125,.55);background:rgba(55,210,125,.10)}
916  .pc-recycle.positive summary,.pc-recycle.positive .pc-recycle-summary-value{color:#bff5da}
917  .pc-recycle.negative{border-color:rgba(245,90,90,.58);background:rgba(245,90,90,.10)}
918  .pc-recycle.negative summary,.pc-recycle.negative .pc-recycle-summary-value{color:#ffd1d1}
919  .pc-recycle-body{padding-top:8px}
920  .pc-recycle-head{display:block}
921  .pc-recycle-note{font-size:11px;color:var(--muted);line-height:1.45}
922  .pc-global-reprocess{margin-top:12px;padding-top:12px;border-top:1px solid var(--border)}
923  .pc-global-reprocess-title{display:flex;align-items:center;justify-content:space-between;gap:10px}
924  .pc-reprocess-toggle{display:flex;align-items:center;gap:8px;margin:0;cursor:pointer;font-weight:800}
925  .pc-reprocess-toggle input{width:16px!important;height:16px!important;min-height:0!important;padding:0!important;margin:0;accent-color:var(--accent)}
926  .pc-global-reprocess-row{display:flex;align-items:center;gap:8px;margin-top:7px}
927  .pc-global-reprocess-row input{width:110px;min-height:38px;padding:7px 10px}
928  .pc-global-reprocess strong{color:var(--text)}
929  .pc-recycle-kpis{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:7px;margin-top:9px}
930  .pc-recycle-kpi{border:1px solid var(--border);background:rgba(0,0,0,.12);border-radius:9px;padding:7px 8px;min-width:0}
931  .pc-recycle-kpi .k{font-size:9px;font-weight:900;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);line-height:1.25}
932  .pc-recycle-kpi .v{font-size:12px;font-weight:900;color:var(--text);margin-top:3px;overflow-wrap:anywhere}
933  .pc-recycle-kpi.positive .v{color:#bff5da}
934  .pc-recycle-kpi.negative .v{color:#ffd1d1}
935  .pc-recycle-tablewrap{overflow:auto;margin-top:9px;border:1px solid var(--border);border-radius:9px}
936  .pc-recycle-table{width:100%;min-width:650px;border-collapse:collapse;font-size:11px}
937  .pc-recycle-table th,.pc-recycle-table td{padding:6px 7px;border-bottom:1px solid rgba(255,255,255,.07);text-align:right;white-space:nowrap}
938  .pc-recycle-table th{font-size:9px;text-transform:uppercase;letter-spacing:.05em;
938color:var(--muted);background:rgba(255,255,255,.025)}
939  .pc-recycle-table th:first-child,.pc-recycle-table td:first-child{text-align:left;white-space:normal;min-width:180px}
940  .pc-recycle-table tbody tr:last-child td{border-bottom:0}
941  .pc-recycle-foot{margin-top:7px;font-size:10px;color:var(--muted);line-height:1.4}
942  @media(max-width:820px){.pc-recycle-kpis{grid-template-columns:repeat(2,minmax(0,1fr))}}
943  @media(max-width:520px){.pc-recycle-kpis{grid-template-columns:1fr}}
944
945  /* Unresolved-item review dialog */
946  .pc-unresolved-overlay{position:fixed;inset:0;z-index:10050;display:none;align-items:center;justify-content:center;padding:20px;background:rgba(4,9,17,.78);backdrop-filter:blur(3px)}
947  .pc-unresolved-overlay.open{display:flex}
948  .pc-unresolved-dialog{width:min(720px,96vw);max-height:86vh;display:flex;flex-direction:column;border:1px solid rgba(245,90,90,.45);background:var(--panel,#101826);border-radius:16px;box-shadow:0 20px 60px rgba(0,0,0,.52);overflow:hidden}
949  .pc-unresolved-head{display:flex;align-items:flex-start;justify-content:space-between;gap:14px;padding:16px 18px;border-bottom:1px solid var(--border);background:rgba(245,90,90,.08)}
950  .pc-unresolved-head h3{margin:0;font-size:20px}
951  .pc-unresolved-head .hint{margin-top:5px}
952  .pc-unresolved-close{flex:0 0 auto;min-width:40px;min-height:40px;padding:6px 10px!important;font-size:20px!important;line-height:1!important}
953  .pc-unresolved-body{padding:14px 18px;overflow:auto}
954  .pc-unresolved-list{display:grid;gap:8px;margin:0;padding:0;list-style:none}
955  .pc-unresolved-item{border:1px solid rgba(245,90,90,.32);background:rgba(245,90,90,.07);border-radius:10px;padding:10px 12px}
956  .pc-unresolved-item strong{display:block;color:#ffd1d1;overflow-wrap:anywhere}
957  .pc-unresolved-item .hint{margin-top:4px;font-size:11px;overflow-wrap:anywhere}
958  .pc-unresolved-actions{display:flex;justify-content:flex-end;gap:10px;flex-wrap:wrap;padding:14px 18px;border-top:1px solid var(--border);background:rgba(255,255,255,.025)}
959  .pc-unresolved-actions .btn{min-height:42px}
960  @media(max-width:560px){.pc-unresolved-overlay{padding:10px}.pc-unresolved-actions{display:grid;grid-template-columns:1fr}.pc-unresolved-actions .btn{width:100%}}
961
962
963  /* CMS_MARKET_FRESHNESS_PANEL_V1 */
964  .pc-market-freshness{
965    display:grid;
966    grid-template-columns:auto 1fr auto auto;
967    align-items:center;
968    gap:12px;
969    padding:11px 13px;
970    border:1px solid var(--border);
971    border-radius:14px;
972    background:rgba(255,255,255,.035);
973    margin-top:12px;
974  }
975
976  .pc-market-dot{
977    width:11px;
978    height:11px;
979    border-radius:50%;
980    background:#8b96a8;
981    box-shadow:0 0 0 4px rgba(139,150,168,.11);
982  }
983
984  .pc-market-freshness.fresh .pc-market-dot{
985    background:#4fda8c;
986    box-shadow:0 0 0 4px rgba(79,218,140,.12);
987  }
988
989  .pc-market-freshness.aging .pc-market-dot{
990    background:#f3c860;
991    box-shadow:0 0 0 4px rgba(243,200,96,.12);
992  }
993
994  .pc-market-freshness.stale .pc-market-dot{
995    background:#f06767;
996    box-shadow:0 0 0 4px rgba(240,103,103,.12);
997  }
998
999  .pc-market-source{
1000    font-weight:900;
1001  }
1002
1003  .pc-market-age{
1004    font-family:var(--mono);
1005    font-weight:900;
1006    white-space:nowrap;
1007  }
1008
1009  .pc-market-state{
1010    border:1px solid var(--border);
1011    border-radius:999px;
1012    padding:4px 8px;
1013    font-size:10px;
1014    font-weight:900;
1015    letter-spacing:.08em;
1016  }
1017
1018  .pc-market-freshness.fresh .pc-market-state{
1019    color:#bff5da;
1020    border-color:rgba(79,218,140,.4);
1021  }
1022
1023  .pc-market-freshness.aging .pc-market-state{
1024    color:#ffe29b;
1025    border-color:rgba(243,200,96,.4);
1026  }
1027
1028  .pc-market-freshness.stale .pc-market-state{
1029    color:#ffd1d1;
1030    border-color:rgba(240,103,103,.45);
1031  }
1032
1033  @media(max-width:720px){
1034    .pc-market-freshness{
1035      grid-template-columns:auto 1fr;
1036    }
1037
1038    .pc-market-age,
1039    .pc-market-state{
1040      grid-column:2;
1041      justify-self:start;
1042    }
1043  }
1044
1045
1046
1047  /* CMS_PRICECHECK_PHASE2_INTELLIGENCE_CSS */
1048  .pc-intel-summary{
1049    display:none;
1050    margin-top:12px;
1051    border:1px solid var(--border);
1052    border-radius:14px;
1053    background:rgba(255,255,255,.035);
1054    padding:11px 13px;
1055  }
1056  .pc-intel-summary.show{display:block}
1057  .pc-intel-summary.warning{border-color:rgba(243,200,96,.42);background:rgba(243,200,96,.06)}
1058  .pc-intel-summary.high{border-color:rgba(240,103,103,.48);background:rgba(240,103,103,.07)}
1059  .pc-intel-summary-head{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap}
1060  .pc-intel-summary-title{font-weight:900}
1061  .pc-intel-summary-bits{display:flex;gap:7px;flex-wrap:wrap;margin-top:8px}
1062  .pc-intel-chip{display:inline-flex;align-items:center;gap:5px;border:1px solid var(--border);border-radius:999px;padding:4px 8px;font-size:10px;font-weight:850;color:var(--muted);background:rgba(255,255,255,.025)}
1063  .pc-intel-chip.high{border-color:rgba(240,103,103,.45);color:#ffd1d1;background:rgba(240,103,103,.07)}
1064  .pc-intel-chip.warning{border-color:rgba(243,200,96,.45);color:#ffe29b;background:rgba(243,200,96,.07)}
1065  .pc-intel-row>td{padding:0 0 10px!important;border-top:0!important;background:transparent!important}
1066  .pc-intel{margin:0;width:100%;box-sizing:border-box;border:1px solid rgba(92,190,255,.23);background:rgba(92,190,255,.035);border-radius:10px;padding:8px 10px}
1067  .pc-intel[open]{background:rgba(92,190,255,.055)}
1068  .pc-intel summary{cursor:pointer;display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap;font-size:12px;font-weight:850;color:var(--text)}
1069  .pc-intel-summary-right{display:flex;align-items:center;gap:6px;flex-wrap:wrap}
1070  .pc-confidence{display:inline-flex;align-items:center;border:1px solid var(--border);border-radius:999px;padding:3px 7px;font-size:10px;font-weight:900;letter-spacing:.03em}
1071  .pc-confidence.high{border-color:rgba(79,218,140,.38);color:#bff5da;background:rgba(79,218,140,.07)}
1072  .pc-confidence.moderate{border-color:rgba(243,200,96,.42);color:#ffe29b;background:rgba(243,200,96,.07)}
1073  .pc-confidence.low{border-color:rgba(240,103,103,.48);color:#ffd1d1;background:rgba(240,103,103,.07)}
1074  .pc-intel-body{padding-top:9px}
1075  .pc-intel-grid{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:7px}
1076  .pc-intel-kpi{border:1px solid var(--border);background:rgba(0,0,0,.13);border-radius:9px;padding:7px 8px;min-width:0}
1077  .pc-intel-kpi .k{font-size:9px;font-weight:900;letter-spacing:.055em;text-transform:uppercase;color:var(--muted);line-height:1.25}
1078  .pc-intel-kpi .v{font-size:12px;font-weight:900;color:var(--text);margin-top:3px;overflow-wrap:anywhere}
1079  .pc-intel-kpi .v.up{color:#bff5da}
1080  .pc-intel-kpi .v.down{color:#ffd1d1}
1081  .pc-intel-secondary{display:grid;grid-template-columns:minmax(220px,.8fr) minmax(300px,1.2fr);gap:10px;margin-top:9px}
1082  .pc-intel-chart,.pc-intel-depth{border:1px solid var(--border);background:rgba(0,0,0,.10);border-radius:9px;padding:8px 9px;min-width:0}
1083  .pc-intel-chart-title,.pc-intel-depth-title{font-size:9px;font-weight:900;letter-spacing:.055em;text-transform:uppercase;color:var(--muted);margin-bottom:5px}
1084  .pc-sparkline{width:100%;height:48px;display:block;color:#a7d7ff}
1085  .pc-sparkline-grid{stroke:currentColor;opacity:.12;stroke-width:1}
1086  .pc-sparkline-line{fill:none;stroke:currentColor;stroke-width:2;vector-effect:non-scaling-stroke}
1087  .pc-intel-depth-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;font-size:10px}
1088  .pc-intel-depth-grid div{display:flex;justify-content:space-between;gap:8px;border-bottom:1px solid rgba(255,255,255,.06);padding:3px 0}
1089  .pc-intel-depth-grid span:first-child{color:var(--muted)}
1090  .pc-intel-depth-grid strong{color:var(--text);text-align:right}
1091  .pc-intel-warnings{display:grid;gap:6px;margin-top:9px}
1092  .pc-intel-warning{border:1px solid var(--border);border-radius:8px;padding:7px 8px;font-size:10px;line-height:1.4}
1093  .pc-intel-warning strong{display:block;margin-bottom:2px}
1094  .pc-intel-warning.warning{border-color:rgba(243,200,96,.42);background:rgba(243,200,96,.06);color:#ffe29b}
1095  .pc-intel-warning.high{border-color:rgba(240,103,103,.48);background:rgba(240,103,103,.07);color:#ffd1d1}
1096  .pc-intel-ok{font-size:10px;color:#bff5da;border:1px solid rgba(79,218,140,.32);background:rgba(79,218,140,.05);border-radius:8px;padding:7px 8px;margin-top:9px}
1097  .pc-intel-history-note{font-size:10px;color:var(--muted);line-height:1.4;margin-top:7px}
1098  @media(max-width:1050px){.pc-intel-grid{grid-template-columns:repeat(3,minmax(0,1fr))}}
1099  @media(max-width:760px){.pc-intel-secondary{grid-template-columns:1fr}.pc-intel-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
1100  @media(max-width:460px){.pc-intel-grid{grid-template-columns:1fr}}
1101
1102
1103  /* CMS_PUBLIC_REFERRAL_BOTTOM_V1 */
1104  .pc-results-ad{display:none;width:100%;box-sizing:border-box;margin:10px 0 4px;overflow:hidden}
1105  .pc-results-ad.is-ready{display:block}
1106  .pc-referral-link{display:block;border:1px solid rgba(92,190,255,.18);border-radius:10px;overflow:hidden;box-shadow:0 8px 16px rgba(0,0,0,.16);transition:transform .16s ease, box-shadow .16s ease, border-color .16s ease}
1107  .pc-referral-link:hover{transform:translateY(-1px);box-shadow:0 12px 20px rgba(0,0,0,.22);border-color:rgba(92,190,255,.32)}
1108  .pc-referral-link img{display:block;width:100%;height:auto}
1109  @media(max-width:650px){.pc-results-ad{margin:8px 0 2px}}
1110
1111  /* CMS_PRICECHECK_UXV2_CSS */
1112  #pcResults{overflow:hidden}
1113  #pcResults .tablewrap{overflow-x:hidden;border-radius:12px}
1114  #pcTable{width:100%;table-layout:auto}
1115  #pcTable th,#pcTable td{padding:10px 9px;vertical-align:middle}
1116  #pcTable th{white-space:nowrap;font-size:11px}
1117  #pcTable td{font-size:12px}
1118  #pcTable .pc-item-cell{min-width:180px;max-width:320px}
1119  #pcTable .pc-num{text-align:right;white-space:nowrap;font-variant-numeric:tabular-nums}
1120  #pcTable .pc-actions-cell{width:1%;white-space:nowrap}
1121  .pc-row-actions{display:flex;gap:6px;justify-content:flex-end;flex-wrap:wrap}
1122  .pc-row-action{padding:5px 8px!important;min-height:0!important;font-size:10px!important;border-radius:8px!important}
1123  .pc-advanced-inline{display:none;margin-top:5px;font-size:10px;line-height:1.45;color:var(--muted)}
1124  #pcResults.pc-advanced-on .pc-advanced-inline{display:block}
1125
1126  .pc-results-head{gap:8px!important}
1127  .pc-results-toolbar{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap}
1128  .pc-results-tools{display:flex;align-items:center;gap:7px;flex-wrap:wrap}
1129  .pc-mode-btn{padding:6px 10px!important;min-height:0!important;font-size:11px!important}
1130  .pc-mode-btn.active{border-color:rgba(92,190,255,.48)!important;background:rgba(92,190,255,.10)!important}
1131  .pc-mode-btn.notice{border-color:rgba(243,200,96,.42)!important}
1132  .pc-mode-btn.high{border-color:rgba(240,103,103,.48)!important}
1133
1134  .pc-totals{display:block!important;text-align:left!important}
1135  .pc-basic-totals{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:9px;width:100%}
1136  .pc-totalhero{border:1px solid var(--border);border-radius:12px;background:rgba(255,255,255,.035);padding:10px 12px;min-width:0}
1137  .pc-totalhero .k{color:var(--muted);font-size:10px;font-weight:900;letter-spacing:.08em;text-transform:uppercase}
1138  .pc-totalhero .v{margin-top:3px;font-size:20px;font-weight:950;color:var(--text);line-height:1.1}
1139  .pc-totalhero .s{margin-top:4px;color:var(--muted);font-size:10px}
1140  .pc-totalhero-head{display:flex;align-items:flex-start;justify-content:space-between;gap:8px}
1141  .pc-basic-meta{grid-column:1/-1;color:var(--muted);font-size:10px;padding:0 2px}
1142  .pc-advanced-totals{display:none;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;margin-top:8px}
1143  #pcResults.pc-advanced-on .pc-advanced-totals{display:grid}
1144  .pc-advanced-total{border:1px solid var(--border);background:rgba(92,190,255,.035);border-radius:10px;padding:8px 10px}
1145  .pc-advanced-total .k{color:var(--muted);font-size:9px;font-weight:900;letter-spacing:.06em;text-transform:uppercase}
1146  .pc-advanced-total .v{color:var(--text);font-size:14px;font-weight:900;margin-top:2px}
1147
1148  .hubtotals{grid-template-columns:repeat(5,minmax(0,1fr))!important;gap:7px!important;margin-top:10px!important}
1149  .hubbadge{min-height:0!important;padding:8px 9px!important;border-radius:10px!important}
1150  .hubbadge .h-title{font-size:11px}
1151  .hubbadge .h-sub{margin-top:4px!important;font-size:10px!important}
1152  .hubbadge .pc-hub-advanced{display:none}
1153  #pcResults.pc-advanced-on .hubbadge .pc-hub-advanced{display:block}
1154
1155  .pc-intel-summary.show{display:none!important}
1156  #pcResults.pc-health-open .pc-intel-summary.show{display:block!important}
1157  .pc-intel-summary,.pc-intel-summary.warning,.pc-intel-summary.high{border-color:var(--border)!important;background:rgba(255,255,255,.025)!important;padding:9px 10px!important;margin-top:9px!important}
1158  .pc-intel-summary-title{font-size:12px}
1159
1160  .pc-intel-row,.pc-recycle-row{display:none}
1161  .pc-intel-row>td,.pc-recycle-row>td{padding:0 0 8px!important;background:transparent!important;border-top:0!important}
1162  .pc-detail-drawer{border:1px solid rgba(92,190,255,.25);background:rgba(92,190,255,.035);border-radius:10px;padding:10px}
1163  .pc-detail-head{display:flex;align-items:flex-start;justify-content:space-between;gap:10px;margin-bottom:8px}
1164  .pc-detail-title{font-size:12px;font-weight:900}
1165  .pc-detail-sub{color:var(--muted);font-size:10px;margin-top:2px}
1166  .pc-detail-kpis{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:7px}
1167  .pc-detail-kpi{border:1px solid var(--border);background:rgba(0,0,0,.10);border-radius:8px;padding:7px 8px;min-width:0}
1168  .pc-detail-kpi .k{color:var(--muted);font-size:8px;font-weight:900;text-transform:uppercase;letter-spacing:.055em}
1169  .pc-detail-kpi .v{color:var(--text);font-size:11px;font-weight:900;margin-top:2px;overflow-wrap:anywhere}
1170  .pc-detail-grid{display:grid;grid-template-columns:minmax(220px,.8fr) minmax(300px,1.2fr);gap:8px;margin-top:8px}
1171  .pc-detail-panel{border:1px solid var(--border);background:rgba(0,0,0,.08);border-radius:8px;padding:8px}
1172  .pc-detail-panel-title{color:var(--muted);font-size:9px;font-weight:900;text-transform:uppercase;letter-spacing:.055em;margin-bottom:5px}
1173  .pc-detail-depth{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:3px 10px;font-size:10px}
1174  .pc-detail-depth div{display:flex;justify-content:space-between;gap:8px;border-bottom:1px solid rgba(255,255,255,.05);padding:3px 0}
1175  .pc-detail-depth span{color:var(--muted)}
1176  .pc-detail-warnings{display:grid;gap:5px;margin-top:8px}
1177  .pc-detail-warning{border:1px solid rgba(243,200,96,.34);background:rgba(243,200,96,.045);color:#ffe29b;border-radius:7px;padding:6px 8px;font-size:10px;line-height:1.4}
1178  .pc-detail-warning.high{border-color:rgba(240,103,103,.42);background:rgba(240,103,103,.055);color:#ffd1d1}
1179  .pc-detail-warning strong{display:block;margin-bottom:1px}
1180  .pc-detail-ok{margin-top:8px;color:#bff5da;font-size:10px}
1181
1182  @media(max-width:900px){
1183    .hubtotals{grid-template-columns:repeat(2,minmax(0,1fr))!important}
1184    .pc-detail-kpis{grid-template-columns:repeat(2,minmax(0,1fr))}
1185    .pc-detail-grid{grid-template-columns:1fr}
1186  }
1187  @media(max-width:650px){
1188    #pcResults .tablewrap{overflow-x:auto}
1189    #pcTable{min-width:760px}
1190    .pc-basic-totals{grid-template-columns:1fr}
1191    .pc-advanced-totals{grid-template-columns:1fr}
1192    .hubtotals{grid-template-columns:1fr!important}
1193  }
1194
1195
1196  /* CMS_PRICECHECK_UXV2_NEGATIVE_CSS */
1197  .pc-negative,
1198  .pc-detail-kpi .v.down,
1199  .pc-intel-kpi .v.down,
1200  .pc-recycle-kpi.negative .v,
1201  .pc-recycle-summary-value.negative{
1202    color:#ff7373!important;
1203    font-weight:900!important;
1204  }
1205  .pc-negative{
1206    text-shadow:0 0 10px rgba(255,90,90,.10);
1207  }
1208
1209
1210  /* CMS_PRICECHECK_UXV2_MARKET_BUTTON_CSS */
1211  .pc-market-btn{
1212    display:inline-flex!important;
1213    align-items:center;
1214    justify-content:center;
1215    gap:5px;
1216    min-width:132px;
1217    font-variant-numeric:tabular-nums;
1218    font-weight:900!important;
1219  }
1220  .pc-market-btn .pc-market-confidence{
1221    font-size:9px;
1222    letter-spacing:.045em;
1223  }
1224  .pc-market-btn .pc-market-spread{
1225    font-size:9px;
1226    opacity:.9;
1227  }
1228  .pc-market-btn .pc-market-notices{
1229    display:inline-flex;
1230    align-items:center;
1231    justify-content:center;
1232    min-width:18px;
1233    height:18px;
1234    padding:0 5px;
1235    border-radius:999px;
1236    font-size:9px;
1237    font-weight:950;
1238    border:1px solid currentColor;
1239  }
1240  .pc-market-btn.good{
1241    border-color:rgba(75,210,150,.52)!important;
1242    background:rgba(75,210,150,.085)!important;
1243    color:#9ff0c9!important;
1244  }
1245  .pc-market-btn.warning{
1246    border-color:rgba(243,200,96,.60)!important;
1247    background:rgba(243,200,96,.095)!important;
1248    color:#ffe08a!important;
1249  }
1250  .pc-market-btn.high{
1251    border-color:rgba(240,103,103,.66)!important;
1252    background:rgba(240,103,103,.105)!important;
1253    color:#ff9a9a!important;
1254  }
1255  .pc-market-btn.none{
1256    border-color:var(--border)!important;
1257    color:var(--muted)!important;
1258  }
1259  .pc-market-btn.high .pc-market-notices{
1260    background:rgba(240,103,103,.12);
1261  }
1262  .pc-market-btn.warning .pc-market-notices{
1263    background:rgba(243,200,96,.10);
1264  }
1265  .pc-market-btn.good .pc-market-notices{
1266    background:rgba(75,210,150,.08);
1267  }
1268
1269  @media(max-width:820px){
1270    .pc-market-btn{
1271      min-width:116px;
1272      gap:4px;
1273    }
1274    .pc-market-btn .pc-market-spread{
1275      display:none;
1276    }
1277  }
1278
1279
1280  /* CMS_PRICECHECK_REPROCESS_MODE_AUTORUN_V1 */
1281  .pc-reprocess-btn{
1282    display:none!important;
1283  }
1284
1285</style>
1286
1287
1288<div class="grid" style="gap:14px">
1289  <div class="card">
1290    <div style="display:flex; gap:12px; align-items:flex-end; justify-content:space-between; flex-wrap:wrap">
1291      <div>
1292        <h1 style="margin:0">Price Check</h1>
1293        <div class="hint" style="margin-top:6px">
1294          Paste an item list <em>or</em> paste directly from EVE inventory/assets, pick a region, and choose a market hub, click Check Prices, and get a clean Buy / Sell appraisal. Advanced pricing, depth, history, and market health stay available on demand.
1295        </div>
1296      </div>
1297      <div class="hint" style="text-align:right">
1298        Tip: quantities can be <code>1000 Tritanium</code>, <code>30 x Plasma Thruster</code>, <code>Tritanium 1000</code>, <code>Tritanium x1000</code>, or <code>Construction Blocks (23 Units)</code>.
1299      </div>
1300    </div>
1301
1302    <form id="pcForm" style="margin-top:12px">
1303      <input type="hidden" name="csrf" value="7f97e5cf384ab7d2a7603e8e4a5e01dfa7aa9dc843d1f17e0c9b09d17db49cef">
1304
1305      <div class="grid" style="grid-template-columns: 1fr; gap:12px">
1306        <div class="grid" style="grid-template-columns: 1fr; gap:12px" id="pcGrid">
1307          <div id="pcItemsColumn" style="min-width:0">
1308            <label>Items</label>
1309            <textarea id="pcItemsTextarea" name="items" rows="10" placeholder="Tritanium 100000\n30 x Plasma Thruster\nConstruction Blocks (23 Units)\n\n(One item per line)" style="font-family:var(--mono); resize:vertical"></textarea>
1310            <div class="hint" style="margin-top:8px">Max: 200 lines per run. Blank lines are ignored.</div>
1311            <div class="grid" style="grid-template-columns: repeat(3, minmax(0, 1fr)); gap:10px; margin-top:12px">
1312              <button class="btn primary" type="submit" id="pcRun">Check Prices</button>
1313              <a class="btn ghost" href="/eve-market/" id="pcMarketBrowser">Market Browser</a><!-- CMS_PRICECHECK_PHASE3_MARKET_BROWSER_LINK -->
1314              <button class="btn ghost" type="button" id="pcClear">Clear</button>
1315              <button class="btn secondary" type="button" id="pcShare" title="Copy a shareable link with the current items">Copy Share Link</button>
1316            </div>
1317          </div>
1318
1319          <div id="pcSettingsColumn" style="min-width:0">
1320            <label>Hub</label>
1321            <div class="hint" style="margin-top:6px">Pick which market hub to price against.</div>
1322                        <select name="region_id" id="pcHubSelect">
1323              <option value="10000043" selected>Domain (Amarr)</option>
1324              <option value="10000002" >The Forge (Jita)</option>
1325              <option value="10000032" >Sinq Laison (Dodixie)</option>
1326              <option value="10000030" >Heimatar (Rens)</option>
1327              <option value="10000042" >Metropolis (Hek)</option>
1328              <option value="19000001" >Global PLEX Market (PLEX only)</option>
1329            </select>
1330
1331            
1332                        <div style="height:10px"></div>
1333            <label style="display:flex; align-items:center; justify-content:space-between; gap:10px">
1334              <span>Price adjustment %</span>
1335              <span class="badge" id="adjBadge">0%</span>
1336            </label>
1337            <div class="pctslider">
1338              <input type="range" name="adj_pct" id="adjPct" min="-90" max="90" step="0.5" value="0">
1339              <div class="pctpresets">
1340                <button class="btn ghost" type="button" data-pct="-10" style="padding:6px 10px; font-size:12px" title="Set to -10%">-10%</button>
1341                <button class="btn ghost" type="button" data-pct="0" style="padding:6px 10px; font-size:12px" title="Set to 0%">0%</button>
1342                <button class="btn ghost" type="button" data-pct="10" style="padding:6px 10px; font-size:12px" title="Set to +10%">+10%</button>
1343              </div>
1344            </div>
1345            <p class="small">Applies a +/− percent to displayed prices and totals for the selected hub.</p>
1346            
1347            <div class="pc-global-reprocess">
1348              <div class="pc-global-reprocess-title">
1349                <label class="pc-reprocess-toggle" for="pcShowReprocess" title="Appraise the entire pasted list after reprocessing instead of pricing the original ore/items.">
1350                  <input id="pcShowReprocess" type="checkbox">
1351                  <span>Reprocess entire appraisal</span>
1352                </label>
1353                <span class="badge" id="pcReprocessEffBadge">72%</span>
1354              </div>
1355              <div class="pc-global-reprocess-row">
1356                <input id="pcReprocessEff" type="number" min="0" max="100" step="0.1" value="72" inputmode="decimal" aria-describedby="pcReprocessEffHelp">
1357                <strong>%</strong>
1358              </div>
1359              <div class="hint" id="pcReprocessEffHelp" style="margin-top:6px">When enabled, the entire pasted list is converted into recovered outputs at this efficiency, then those outputs are appraised at the selected hub. Changing this option automatically reruns the appraisal. Complete-portion remainders and non-reprocessable items stay in the final appraisal.</div>
1360            </div>
1361
1362          </div>
1363        </div>
1364      </div>
1365    </form>
1366  </div>
1367
1368  
1369
1370  
1371  <!-- CMS_MARKET_FRESHNESS_PANEL_V1 -->
1372  <div
1373    id="pcMarketFreshness"
1374    class="pc-market-freshness"
1375    aria-live="polite"
1376  >
1377    <span class="pc-market-dot"></span>
1378
1379    <div>
1380      <div class="pc-market-source">
1381        EVE Syndicates Market Intelligence
1382      </div>
1383
1384      <div class="hint" id="pcMarketDetail">
1385        Checking local market ingest…
1386      </div>
1387    </div>
1388
1389    <div class="pc-market-age" id="pcMarketAge">
1390      —
1391    </div>
1392
1393    <div class="pc-market-state" id="pcMarketState">
1394      CHECKING
1395    </div>
1396  </div>
1397
1398<div class="card" id="pcResults" style="display:none">
1399    <div class="pc-results-head">
1400      <div>
1401        <div class="pc-results-toolbar">
1402          <div>
1403            <h2 style="margin:0">Results</h2>
1404            <div class="hint" id="pcMeta" style="margin-top:4px"></div>
1405          </div>
1406          <div class="pc-results-tools" aria-label="Price Check result controls">
1407            <!-- CMS_PRICECHECK_UXV2_TOOLBAR -->
1408            <button class="btn ghost pc-mode-btn" type="button" id="pcAdvancedToggle" aria-pressed="false">Advanced Pricing</button>
1409            <button class="btn ghost pc-mode-btn" type="button" id="pcHealthToggle" aria-pressed="false">Market Health</button>
1410          </div>
1411        </div>
1412      </div>
1413      <div id="pcTotals" class="pc-totals" aria-live="polite"></div>
1414    </div>
1415
1416    <div id="pcHubTotals" class="hubtotals" style="display:none"></div>
1417
1418    <!-- CMS_PRICECHECK_PHASE2_INTELLIGENCE_SUMMARY -->
1419    <div id="pcIntelSummary" class="pc-intel-summary" aria-live="polite"></div>
1420
1421    <div id="pcMsg" class="notice" style="margin-top:12px; display:none"></div>
1422
1423    <div class="tablewrap" style="margin-top:12px">
1424      <table class="table" id="pcTable">
1425        <thead>
1426          <tr>
1427            <th>Item</th>
1428            <th class="pc-num">Qty</th>
1429            <th class="pc-num">Buy</th>
1430            <th class="pc-num">Sell</th>
1431            <th class="pc-num">Buy Total</th>
1432            <th class="pc-num">Sell Total</th>
1433            <th class="pc-actions-cell">Market</th>
1434          </tr>
1435        </thead>
1436        <tbody></tbody>
1437      </table>
1438    </div>
1439
1440    <div class="hint" style="margin-top:12px">
1441      Pricing source: EVE Syndicates Market Intelligence. If a line errors, it usually means the item name didn’t resolve on ESI, or the item has no market data in that region.
1442    </div>
1443  </div>
1444
1445<div class="card" id="pcRecent" style="display:none">
1446  <div style="display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap">
1447    <h2 style="margin:0">Recent checks</h2>
1448    <button class="btn ghost" type="button" id="pcRecentClear" style="padding:6px 10px; font-size:12px">Clear history</button>
1449  </div>
1450  <div class="hint" style="margin-top:6px">Stored locally in your browser on this device.</div>
1451  <div class="pc-badges" id="pcRecentBadges" style="margin-top:12px"></div>
1452</div>
1453
1454<!-- CMS_PUBLIC_REFERRAL_BOTTOM_V1: Price Check banner intentionally below results/recent checks -->
1455<div class="pc-results-ad" id="pcResultsAd" aria-label="EVE Online free skill points referral">
1456  <a class="pc-referral-link" href="https://www.eveonline.com/signup?invc=c2c0373f-cae0-4026-91e7-651973b69340" target="_blank" rel="noopener noreferrer sponsored">
1457    <img src="/assets/referrals/eve_free_skill_points_slim_banner_2026_09_22.png" alt="Start EVE Online with free skill points — claim the referral bonus">
1458  </a>
1459</div>
1460
1461</div>
1462
1463<div class="pc-unresolved-overlay" id="pcUnresolvedOverlay" aria-hidden="true">
1464  <section class="pc-unresolved-dialog" role="dialog" aria-modal="true" aria-labelledby="pcUnresolvedTitle" aria-describedby="pcUnresolvedDesc">
1465    <div class="pc-unresolved-head">
1466      <div>
1467        <h3 id="pcUnresolvedTitle">Some pasted items did not resolve</h3>
1468        <div class="hint" id="pcUnresolvedDesc">Review the unresolved lines below. You can remove all of them and immediately run Price Check again, or close this window and edit the pasted list yourself.</div>
1469      </div>
1470      <button class="btn ghost pc-unresolved-close" type="button" id="pcUnresolvedX" aria-label="Close unresolved 
1470items dialog">×</button>
1471    </div>
1472    <div class="pc-unresolved-body">
1473      <ul class="pc-unresolved-list" id="pcUnresolvedList"></ul>
1474    </div>
1475    <div class="pc-unresolved-actions">
1476      <button class="btn ghost" type="button" id="pcUnresolvedManual">Close — Remove Manually</button>
1477      <button class="btn primary" type="button" id="pcUnresolvedRemove">Remove Unresolved &amp; Recheck</button>
1478    </div>
1479  </section>
1480</div>
1481
1482<script>
1483(function(){
1484  const form = document.getElementById('pcForm');
1485  const taItems = form ? form.querySelector('textarea[name=\"items\"]') : null;
1486  const btnRun = document.getElementById('pcRun');
1487  const btnClear = document.getElementById('pcClear');
1488  const btnShare = document.getElementById('pcShare');
1489  const results = document.getElementById('pcResults');
1490  const resultsAd = document.getElementById('pcResultsAd');
1491  let resultsAdInitialized = false;
1492  function pcInitResultsAd(){
1493    if (!resultsAd || resultsAdInitialized) return;
1494    resultsAd.classList.add('is-ready');
1495    resultsAdInitialized = true;
1496  }
1497  const msg = document.getElementById('pcMsg');
1498  const meta = document.getElementById('pcMeta');
1499  const totals = document.getElementById('pcTotals');
1500  const hubTotals = document.getElementById('pcHubTotals');
1501  const table = document.getElementById('pcTable');
1502  const recentCard = document.getElementById('pcRecent');
1503  const recentBadges = document.getElementById('pcRecentBadges');
1504  const recentClear = document.getElementById('pcRecentClear');
1505  const adjRange = document.getElementById('adjPct');
1506  const adjBadge = document.getElementById('adjBadge');
1507  const adjPresetBtns = document.querySelectorAll('[data-pct]');
1508  const reprocessEffInput = document.getElementById('pcReprocessEff');
1509  const reprocessEffBadge = document.getElementById('pcReprocessEffBadge');
1510  const showReprocessToggle = document.getElementById('pcShowReprocess');
1511  const unresolvedOverlay = document.getElementById('pcUnresolvedOverlay');
1512  const unresolvedList = document.getElementById('pcUnresolvedList');
1513  const unresolvedRemoveBtn = document.getElementById('pcUnresolvedRemove');
1514  const unresolvedManualBtn = document.getElementById('pcUnresolvedManual');
1515  const unresolvedXBtn = document.getElementById('pcUnresolvedX');
1516  let unresolvedRows = [];
1517  let unresolvedReturnFocus = null;
1518
1519  const hubSelect = form ? form.querySelector('#pcHubSelect') : null;
1520
1521  // CMS_MARKET_FRESHNESS_PANEL_V1
1522  const marketFreshness =
1523    document.getElementById('pcMarketFreshness');
1524
1525  const marketAge =
1526    document.getElementById('pcMarketAge');
1527
1528  const marketState =
1529    document.getElementById('pcMarketState');
1530
1531  const marketDetail =
1532    document.getElementById('pcMarketDetail');
1533
1534  let marketAgeAtFetch = null;
1535  let marketAgeFetchedMs = 0;
1536  let marketFreshAfter = 600;
1537  let marketStaleAfter = 1200;
1538
1539
1540
1541  let lastAppraisal = null; // Current successful appraisal used by Copy Share Link
1542
1543
1544  // Preferred hub (per-browser). Migrate the old DMC/IRS key once.
1545  const HUB_PREF_KEY = 'evesyndicates_pricecheck_preferred_hub_region';
1546  const HUB_PREF_KEY_LEGACY = 'dmc_irs_pricecheck_preferred_hub_region';
1547
1548  try {
1549    const urlHasRegion =
1550      (new URL(window.location.href))
1551        .searchParams
1552        .has('region_id');
1553
1554    if (!urlHasRegion && hubSelect) {
1555      let saved =
1556        localStorage.getItem(HUB_PREF_KEY);
1557
1558      if (!saved) {
1559        saved =
1560          localStorage.getItem(HUB_PREF_KEY_LEGACY);
1561
1562        if (saved) {
1563          localStorage.setItem(
1564            HUB_PREF_KEY,
1565            saved
1566          );
1567        }
1568      }
1569
1570      if (
1571        saved &&
1572        String(saved).trim() !== ''
1573      ) {
1574        hubSelect.value = String(saved);
1575      }
1576    }
1577  } catch (_) {}
1578
1579  
1580function showHubSavedToast(){
1581  // Tiny, dependency-free toast
1582  let t = document.getElementById('hubSavedToast');
1583  if (!t) {
1584    t = document.createElement('div');
1585    t.id = 'hubSavedToast';
1586    t.style.position = 'fixed';
1587    t.style.right = '16px';
1588    t.style.bottom = '16px';
1589    t.style.zIndex = '9999';
1590    t.style.padding = '10px 12px';
1591    t.style.borderRadius = '12px';
1592    t.style.background = 'rgba(0,0,0,0.85)';
1593    t.style.border = '1px solid rgba(255,255,255,0.18)';
1594    t.style.color = '#fff';
1595    t.style.fontSize = '13px';
1596    t.style.maxWidth = '320px';
1597    t.style.boxShadow = '0 10px 30px rgba(0,0,0,0.35)';
1598    t.style.opacity = '0';
1599    t.style.transform = 'translateY(6px)';
1600    t.style.transition = 'opacity 180ms ease, transform 180ms ease';
1601    document.body.appendChild(t);
1602  }
1603  t.textContent = 'Hub preference saved for future lookups.';
1604  requestAnimationFrame(() => {
1605    t.style.opacity = '1';
1606    t.style.transform = 'translateY(0)';
1607  });
1608  clearTimeout(window.__hubToastTimer);
1609  window.__hubToastTimer = setTimeout(() => {
1610    t.style.opacity = '0';
1611    t.style.transform = 'translateY(6px)';
1612  }, 2200);
1613}
1614
1615if (hubSelect) {
1616    hubSelect.addEventListener('change', function(){
1617      try { localStorage.setItem(HUB_PREF_KEY, String(hubSelect.value || '')); } catch (_) {}
1618      showHubSavedToast();
1619    });
1620  }
1621
1622
1623  function fmtPct(v){
1624    const n = Math.round(Number(v) * 10) / 10;
1625    const s = String(n).replace(/\.0$/, '');
1626    return (n>0?'+':'') + s + '%';
1627  }
1628
1629  function syncAdjUI(){
1630    if (!adjRange || !adjBadge) return;
1631    const v = clampPct(adjRange.value);
1632    adjRange.value = v;
1633    adjBadge.textContent = fmtPct(v);
1634  }
1635
1636  if (adjRange) adjRange.addEventListener('input', syncAdjUI);
1637  adjPresetBtns.forEach(b => b.addEventListener('click', function(){
1638    if (!adjRange) return;
1639    adjRange.value = b.getAttribute('data-pct') || '0';
1640    syncAdjUI();
1641  }));
1642
1643  // Initialize slider badge
1644  syncAdjUI();
1645
1646  function clampPct(v){
1647    let x = Number(v);
1648    if (!isFinite(x)) x = 0;
1649    if (x < -90) x = -90;
1650    if (x >  90) x =  90;
1651    return x;
1652  }
1653
1654  function getAdjPct(){
1655    try {
1656      const fd = new FormData(form);
1657      return clampPct(fd.get('adj_pct') || 0);
1658    } catch(e){ return 0; }
1659  }
1660
1661  function fmtISK(n){
1662    if (n === null || typeof n === 'undefined' || Number.isNaN(Number(n))) return '—';
1663    return new Intl.NumberFormat(undefined, { maximumFractionDigits: 2 }).format(Number(n)) + ' ISK';
1664  }
1665  function fmtInt(n){
1666    if (n === null || typeof n === 'undefined' || Number.isNaN(Number(n))) return '—';
1667    return new Intl.NumberFormat(undefined, { maximumFractionDigits: 0 }).format(Number(n));
1668  }
1669
1670
1671  function fmtM3(n){
1672    if (n === null || typeof n === 'undefined' || Number.isNaN(Number(n))) return '—';
1673    return new Intl.NumberFormat(undefined, { maximumFractionDigits: 2 }).format(Number(n)) + ' m³';
1674  }
1675
1676
1677// Recent checks (local, per-browser)
1678const RECENT_KEY = 'evesyndicates_pricecheck_recent_v1';
1679const RECENT_KEY_LEGACY = 'dmc_irs_pricecheck_recent_v1';
1680const RECENT_MAX = 10;
1681
1682function hubShort(regionId){
1683  const id = String(regionId || '');
1684  if (id === '10000002') return 'Jita';
1685  if (id === '10000043') return 'Amarr';
1686  if (id === '10000032') return 'Dodixie';
1687  if (id === '10000030') return 'Rens';
1688  if (id === '10000042') return 'Hek';
1689  if (id === '19000001') return 'PLEX';
1690  return 'Hub ' + id;
1691}
1692
1693
1694// 5-hub comparison badges (major trade hubs)
1695const HUBS_5 = [
1696  { id: '10000002', label: 'Jita' },
1697  { id: '10000043', label: 'Amarr' },
1698  { id: '10000032', label: 'Dodixie' },
1699  { id: '10000030', label: 'Rens' },
1700  { id: '10000042', label: 'Hek' },
1701];
1702
1703function hubLabel(regionId){
1704  const id = String(regionId || '');
1705  const hit = HUBS_5.find(h => h.id === id);
1706  return hit ? hit.label : hubShort(id);
1707}
1708
1709
1710function renderHubBadge(regionId, summary, adjPct, isActive, loadingText, errText){
1711  if (!hubTotals) return;
1712
1713  const id = String(regionId || '');
1714  let el = hubTotals.querySelector('[data-hub="'+id+'"]');
1715  if (!el) {
1716    el = document.createElement('div');
1717    el.className = 'hubbadge';
1718    el.dataset.hub = id;
1719    hubTotals.appendChild(el);
1720  }
1721
1722  el.classList.toggle('active', !!isActive);
1723
1724  const factor = 1 + (clampPct(adjPct) / 100);
1725  const d = summary || {};
1726  const typesOk = Number(d.types_priced || 0);
1727  const typesReq = Number(d.types_requested || 0);
1728  const topBuy = Number(d.buy_total || 0) * factor;
1729  const topSell = Number(d.sell_total || 0) * factor;
1730  const iSell = Number(d.immediate_sell_total || 0) * factor;
1731  const split = Number(d.split_total || 0) * factor;
1732  const iBuy = Number(d.immediate_buy_total || 0) * factor;
1733  const buy = iSell;
1734  const sell = iBuy;
1735  const sellFill = Number(d.immediate_sell_fill_pct || 0);
1736  const buyFill = Number(d.immediate_buy_fill_pct || 0);
1737  const right = errText ? '—' : (loadingText ? loadingText : String(typesOk) + '/' + String(typesReq));
1738
1739  el.innerHTML =
1740    '<div class="h-title"><span>'+escapeHtml(hubLabel(id))+'</span><span class="hint">'+escapeHtml(right)+'</span></div>'
1741    + (errText
1742      ? '<div class="hint" style="margin-top:5px">'+escapeHtml(errText)+'</div>'
1743      : (
1744          '<div class="h-sub"><span>Buy</span><span class="h-val">'+escapeHtml(loadingText ? '…' : fmtISKShort(buy))+'</span></div>'
1745          + '<div class="h-sub"><span>Sell</span><span class="h-val">'+escapeHtml(loadingText ? '…' : fmtISKShort(sell))+'</span></div>'
1746          + '<div class="pc-hub-advanced">'
1747          + '<div class="h-sub immediate"><span>Immediate Sell</span><span>'+escapeHtml(loadingText ? '…' : fmtISKShort(iSell))+'</span></div>'
1748          + '<div class="h-sub"><span>Split</span><span>'+escapeHtml(loadingText ? '…' : fmtISKShort(split))+'</span></div>'
1749          + '<div class="h-sub immediate"><span>Immediate Buy</span><span>'+escapeHtml(loadingText ? '…' : fmtISKShort(iBuy))+'</span></div>'
1750          + (!loadingText && (sellFill < 99.999 || buyFill < 99.999)
1751              ? '<div class="hint" style="margin-top:4px">Fill: sell '+escapeHtml(sellFill.toFixed(1))+'% · buy '+escapeHtml(buyFill.toFixed(1))+'%</div>'
1752              : '')
1753          + '</div>'
1754        )
1755    );
1756
1757  if (!errText && !loadingText) {
1758    el.title = hubLabel(id)
1759      + ' · Buy ' + fmtISK(buy)
1760      + ' · Sell ' + fmtISK(sell)
1761      + ' · Immediate Sell ' + fmtISK(iSell)
1762      + ' · Split ' + fmtISK(split)
1763      + ' · Immediate Buy ' + fmtISK(iBuy)
1764      + ' · Top Buy ' + fmtISK(topBuy)
1765      + ' · Top Sell ' + fmtISK(topSell);
1766  }
1767}
1768    
1769function loadAllHubTotals(adjPct, mainData){
1770      if (!hubTotals) return;
1771      hubTotals.style.display = '';
1772      hubTotals.innerHTML = '';
1773      const mainRegion = mainData && mainData.region_id ? String(mainData.region_id) : '';
1774      const comparison = mainData && mainData.hub_comparison ? mainData.hub_comparison : {};
1775      HUBS_5.forEach(function(h){
1776        const d = comparison[String(h.id)] || null;
1777        if (!d) {
1778          renderHubBadge(h.id, null, adjPct, h.id === mainRegion, null, 'No local comparison data');
1779          return;
1780        }
1781        renderHubBadge(h.id, d, adjPct, h.id === mainRegion, null, null);
1782      });
1783    }
1784    
1785function fmtISKShort(n){
1786  const x = Number(n);
1787  if (!isFinite(x)) return '—';
1788  const abs = Math.abs(x);
1789  const units = [
1790    {v: 1e12, s: 't'},
1791    {v: 1e9,  s: 'b'},
1792    {v: 1e6,  s: 'm'},
1793    {v: 1e3,  s: 'k'},
1794  ];
1795  for (const u of units) {
1796    if (abs >= u.v) {
1797      const v = x / u.v;
1798      const txt = (Math.round(v * 100) / 100).toString().replace(/\.0+$/,'').replace(/(\.\d)0$/,'$1');
1799      return txt + u.s + ' ISK';
1800    }
1801  }
1802  return fmtISK(x);
1803}
1804
1805function countLines(text){
1806  return String(text || '')
1807    .split(/\r?\n/)
1808    .map(l => l.trim())
1809    .filter(Boolean).length;
1810}
1811
1812function loadRecent(){
1813  try{
1814    let raw =
1815      localStorage.getItem(RECENT_KEY);
1816
1817    if (!raw) {
1818      raw =
1819        localStorage.getItem(RECENT_KEY_LEGACY);
1820
1821      if (raw) {
1822        localStorage.setItem(
1823          RECENT_KEY,
1824          raw
1825        );
1826      }
1827    }
1828
1829    const arr =
1830      raw ? JSON.parse(raw) : [];
1831
1832    return Array.isArray(arr) ? arr : [];
1833
1834  }catch(_){
1835    return [];
1836  }
1837}
1838
1839function saveRecent(arr){
1840  try{ localStorage.setItem(RECENT_KEY, JSON.stringify(arr)); }catch(_){}
1841}
1842
1843function renderRecent(){
1844  if (!recentCard || !recentBadges) return;
1845  const list = loadRecent();
1846  if (!list.length) {
1847    recentCard.style.display = 'none';
1848    recentBadges.innerHTML = '';
1849    return;
1850  }
1851  recentCard.style.display = '';
1852  recentBadges.innerHTML = '';
1853  list.forEach((it) => {
1854    const btn = document.createElement('button');
1855    btn.type = 'button';
1856    btn.className = 'pc-badge';
1857    const lines = Number(it.lines || 0) || countLines(it.items || '');
1858    const hub = hubShort(it.region_id);
1859    const total = fmtISKShort(it.total_isk);
1860    btn.innerHTML = '<strong>' + escapeHtml(String(lines)) + '</strong> items • '
1861      + escapeHtml(hub) + ' • ' + escapeHtml(total);
1862
1863    const when = it.when ? new Date(it.when) : null;
1864    const whenTxt = when && !isNaN(when.getTime()) ? when.toLocaleString() : '';
1865    const adj = (it.adj_pct && Number(it.adj_pct)) ? (' • Adjustment ' + (Number(it.adj_pct)>0?'+':'') + it.adj_pct + '%') : '';
1866    btn.title = (whenTxt ? ('Ran: ' + whenTxt) : 'Recent check') + adj;
1867
1868    btn.addEventListener('click', function(){
1869      try {
1870        // Restore this check into the UI and run it again (no gigantic URL required).
1871        if (taItems) taItems.value = it.items || '';
1872        const sel = form ? form.querySelector('select[name="region_id"]') : null;
1873        if (sel && it.region_id) sel.value = String(it.region_id);
1874        if (adjRange) { adjRange.value = String(it.adj_pct ?? 0); syncAdjUI(); }
1875
1876        // Keep URL clean.
1877        try {
1878          const u = new URL(window.location.href);
1879          u.search = '';
1880          history.replaceState(null, '', u.toString());
1881        } catch(_) {}
1882
1883        run();
1884      } catch(_) {}
1885    });
1886
1887    recentBadges.appendChild(btn);
1888  });
1889}
1890
1891if (recentClear) {
1892  recentClear.addEventListener('click', function(){
1893    try{ localStorage.removeItem(RECENT_KEY); localStorage.removeItem(RECENT_KEY_LEGACY); }catch(_){}
1894    renderRecent();
1895  });
1896}
1897
1898
1899
1900  function marketHumanAge(seconds){
1901    let s = Math.max(0, Math.floor(Number(seconds) || 0));
1902
1903    if (s < 60) return s + 's old';
1904
1905    const m = Math.floor(s / 60);
1906    const rs = s % 60;
1907
1908    if (m < 60) {
1909      return m + 'm ' + rs + 's old';
1910    }
1911
1912    const h = Math.floor(m / 60);
1913    const rm = m % 60;
1914
1915    return h + 'h ' + rm + 'm old';
1916  }
1917
1918  function marketExtractAge(m){
1919    if (!m || typeof m !== 'object') return null;
1920
1921    const direct = [
1922      m.age_seconds,
1923      m.data_age_seconds,
1924      m.ingest_age_seconds,
1925      m.seconds_old
1926    ];
1927
1928    for (const v of direct) {
1929      const n = Number(v);
1930
1931      if (Number.isFinite(n) && n >= 0) {
1932        return n;
1933      }
1934    }
1935
1936    const stamps = [
1937      m.last_success_at,
1938      m.last_success_utc,
1939      m.completed_at,
1940      m.finished_at,
1941      m.updated_at,
1942      m.ingested_at
1943    ];
1944
1945    for (const stamp of stamps) {
1946      if (!stamp) continue;
1947
1948      const d = new Date(String(stamp));
1949
1950      if (!Number.isNaN(d.getTime())) {
1951        return Math.max(
1952          0,
1953          (Date.now() - d.getTime()) / 1000
1954        );
1955      }
1956    }
1957
1958    return null;
1959  }
1960
1961  function marketRenderClock(){
1962    if (!marketFreshness || !marketAge) return;
1963
1964    if (marketAgeAtFetch === null) {
1965      marketAge.textContent = '—';
1966      return;
1967    }
1968
1969    const elapsed =
1970      Math.max(
1971        0,
1972        (Date.now() - marketAgeFetchedMs) / 1000
1973      );
1974
1975    const age = marketAgeAtFetch + elapsed;
1976
1977    marketAge.textContent = marketHumanAge(age);
1978
1979    marketFreshness.classList.remove(
1980      'fresh',
1981      'aging',
1982      'stale'
1983    );
1984
1985    let cls = 'fresh';
1986    let label = 'FRESH';
1987
1988    if (age > marketStaleAfter) {
1989      cls = 'stale';
1990      label = 'STALE';
1991    } else if (age > marketFreshAfter) {
1992      cls = 'aging';
1993      label = 'AGING';
1994    }
1995
1996    marketFreshness.classList.add(cls);
1997
1998    if (marketState) {
1999      marketState.textContent = label;
2000    }
2001  }
2002
2003  function renderMarketStatus(m, regionId){
2004    if (!marketFreshness) return;
2005
2006    const age = marketExtractAge(m);
2007
2008    const freshAfter =
2009      Number(m && m.fresh_after_seconds);
2010
2011    const staleAfter =
2012      Number(m && m.stale_after_seconds);
2013
2014    if (
2015      Number.isFinite(freshAfter)
2016      && freshAfter > 0
2017    ) {
2018      marketFreshAfter = freshAfter;
2019    }
2020
2021    if (
2022      Number.isFinite(staleAfter)
2023      && staleAfter > marketFreshAfter
2024    ) {
2025      marketStaleAfter = staleAfter;
2026    }
2027
2028    marketAgeAtFetch =
2029      Number.isFinite(age)
2030        ? age
2031        : null;
2032
2033    marketAgeFetchedMs = Date.now();
2034
2035    const option =
2036      hubSelect &&
2037      hubSelect.options &&
2038      hubSelect.selectedIndex >= 0
2039        ? hubSelect.options[hubSelect.selectedIndex]
2040        : null;
2041
2042    const hubLabel =
2043      option
2044        ? option.textContent.trim()
2045        : ('Region ' + String(regionId || ''));
2046
2047    const types =
2048      Number(
2049        m && (
2050          m.types_priced ??
2051          m.priced_types ??
2052          m.type_count
2053        )
2054      );
2055
2056    const orders =
2057      Number(
2058        m && (
2059          m.orders_kept ??
2060          m.order_count ??
2061          m.orders
2062        )
2063      );
2064
2065    const detail = [];
2066
2067    detail.push(hubLabel);
2068
2069    if (Number.isFinite(types) && types > 0) {
2070      detail.push(
2071        types.toLocaleString('en-US')
2072        + ' priced types'
2073      );
2074    }
2075
2076    if (Number.isFinite(orders) && orders > 0) {
2077      detail.push(
2078        orders.toLocaleString('en-US')
2079        + ' orders'
2080      );
2081    }
2082
2083    detail.push('Direct CCP ESI ingest');
2084    detail.push('automatic refresh enabled');
2085
2086    if (marketDetail) {
2087      marketDetail.textContent = detail.join(' • ');
2088    }
2089
2090    marketRenderClock();
2091  }
2092
2093  async function refreshMarketStatus(){
2094    if (!hubSelect) return;
2095
2096    const regionId =
2097      String(hubSelect.value || '10000043');
2098
2099    try {
2100      const u = new URL(
2101        '/api/market_status.php',
2102        window.location.origin
2103      );
2104
2105      u.searchParams.set('region_id', regionId);
2106
2107      const res = await fetch(
2108        u.toString(),
2109        {
2110          credentials:'same-origin',
2111          cache:'no-store'
2112        }
2113      );
2114
2115      const data = await res.json().catch(() => null);
2116
2117      if (
2118        res.ok &&
2119        data &&
2120        data.ok &&
2121        data.market
2122      ) {
2123        renderMarketStatus(
2124          data.market,
2125          regionId
2126        );
2127      }
2128
2129    } catch (_) {
2130      // Keep the last known timer visible.
2131    }
2132  }
2133
2134  function showMsg(html, kind){
2135    msg.style.display = '';
2136    msg.className = 'notice' + (kind ? (' ' + kind) : '');
2137    msg.innerHTML = html;
2138  }
2139  function hideMsg(){
2140    msg.style.display = 'none';
2141    msg.innerHTML = '';
2142  }
2143
2144  function unresolvedIsNameFailure(r){
2145    if (!r || !r.error) return false;
2146    if (!r.type_id) return true;
2147    return /no matching item types? found/i.test(String(r.error || ''));
2148  }
2149
2150  function unresolvedClose(){
2151    if (!unresolvedOverlay) return;
2152    unresolvedOverlay.classList.remove('open');
2153    unresolvedOverlay.setAttribute('aria-hidden', 'true');
2154    unresolvedRows = [];
2155    const target = unresolvedReturnFocus;
2156    unresolvedReturnFocus = null;
2157    if (target && typeof target.focus === 'function') { try { target.focus(); } catch(_) {} }
2158  }
2159
2160  function unresolvedOpen(rows){
2161    if (!unresolvedOverlay || !unresolvedList) return;
2162    unresolvedRows = Array.isArray(rows) ? rows.slice() : [];
2163    if (!unresolvedRows.length) return;
2164    unresolvedReturnFocus = document.activeElement;
2165    unresolvedList.innerHTML = '';
2166    unresolvedRows.forEach(function(r){
2167      const li = document.createElement('li');
2168      li.className = 'pc-unresolved-item';
2169      const label = String(r.input || r.query || r.item_name || 'Unresolved item');
2170      const lineNo = Number(r.line || 0);
2171      const err = String(r.error || 'No matching EVE item type was found.');
2172      li.innerHTML = '<strong>' + escapeHtml(label) + '</strong>'
2173        + '<div class="hint">' + (lineNo > 0 ? ('Pasted item #' + escapeHtml(String(lineNo)) + ' · ') : '') + escapeHtml(err) + '</div>';
2174      unresolvedList.appendChild(li);
2175    });
2176    if (unresolvedRemoveBtn) {
2177      unresolvedRemoveBtn.textContent = 'Remove ' + unresolvedRows.length + ' Unresolved ' + (unresolvedRows.length === 1 ? 'Item' : 'Items') + ' & Recheck';
2178    }
2179    unresolvedOverlay.classList.add('open');
2180    unresolvedOverlay.setAttribute('aria-hidden', 'false');
2181    setTimeout(function(){ if (unresolvedRemoveBtn) unresolvedRemoveBtn.focus(); }, 0);
2182  }
2183
2184  function unresolvedRemoveFromTextarea(rows){
2185    if (!taItems) return 0;
2186    const removeParsedIndexes = new Set();
2187    (rows || []).forEach(function(r){
2188      const n = Number(r && r.line || 0);
2189      if (Number.isInteger(n) && n > 0) removeParsedIndexes.add(n);
2190    });
2191    if (!removeParsedIndexes.size) return 0;
2192
2193    const original = String(taItems.value || '').replace(/\r\n/g, '\n').replace(/\r/g, '\n');
2194    const lines = original.split('\n');
2195    let parsedIndex = 0;
2196    let removed = 0;
2197    const kept = [];
2198    lines.forEach(function(line){
2199      // Mirrors Price Check's one-output-row-per-nonblank-input-line behavior.
2200      const probe = String(line || '').replace(/\u00a0/g, ' ').replace(/[\u200B-\u200D\uFEFF]/g, '').trim();
2201      if (probe !== '') {
2202        parsedIndex += 1;
2203        if (removeParsedIndexes.has(parsedIndex)) { removed += 1; return; }
2204      }
2205      kept.push(line);
2206    });
2207    taItems.value = kept.join('\n').replace(/^\n+|\n+$/g, '');
2208    return removed;
2209  }
2210
2211  if (unresolvedManualBtn) unresolvedManualBtn.addEventListener('click', unresolvedClose);
2212  if (unresolvedXBtn) unresolvedXBtn.addEventListener('click', unresolvedClose);
2213  if (unresolvedOverlay) {
2214    unresolvedOverlay.addEventListener('click', function(e){ if (e.target === unresolvedOverlay) unresolvedClose(); });
2215  }
2216  document.addEventListener('keydown', function(e){
2217    if (e.key === 'Escape' && unresolvedOverlay && unresolvedOverlay.classList.contains('open')) unresolvedClose();
2218  });
2219  if (unresolvedRemoveBtn) {
2220    unresolvedRemoveBtn.addEventListener('click', function(){
2221      const removed = unresolvedRemoveFromTextarea(unresolvedRows);
2222      unresolvedClose();
2223      if (!removed) {
2224        showMsg('Could not safely match the unresolved lines back to the pasted list. Remove them manually and run Price Check again.', 'warn');
2225        results.style.display = '';
2226        return;
2227      }
2228      if (!taItems || !String(taItems.value || '').trim()) {
2229        clearTable();
2230        totals.textContent = '';
2231        meta.textContent = '';
2232        showMsg('All pasted items were unresolved and have been removed. Paste another item list to continue.', 'w
2232arn');
2233        results.style.display = '';
2234        return;
2235      }
2236      run();
2237    });
2238  }
2239
2240  function setBusy(isBusy){
2241    if (btnRun) btnRun.disabled = !!isBusy;
2242    if (btnClear) btnClear.disabled = !!isBusy;
2243    if (btnShare) btnShare.disabled = !!isBusy;
2244    if (showReprocessToggle) showReprocessToggle.disabled = !!isBusy;
2245    if (reprocessEffInput) reprocessEffInput.disabled = !!isBusy;
2246    if (btnRun) btnRun.textContent = isBusy ? 'Checking…' : 'Check Prices';
2247  }
2248
2249  function clearTable(){
2250    const tbody = table.querySelector('tbody');
2251    tbody.innerHTML = '';
2252    const intelSummary = document.getElementById('pcIntelSummary'); // CMS_PRICECHECK_PHASE2_CLEAR_SUMMARY
2253    if (intelSummary) { intelSummary.className = 'pc-intel-summary'; intelSummary.innerHTML = ''; }
2254  }
2255
2256  function getReprocessEff(){
2257    let pct = Number(reprocessEffInput ? reprocessEffInput.value : 72);
2258    if (!Number.isFinite(pct)) pct = 72;
2259    pct = Math.max(0, Math.min(100, pct));
2260    if (reprocessEffInput && Number(reprocessEffInput.value) !== pct) reprocessEffInput.value = String(pct);
2261    if (reprocessEffBadge) reprocessEffBadge.textContent = pct.toFixed(1).replace(/\.0$/,'') + '%';
2262    return pct;
2263  }
2264
2265
2266  function syncRecycleVisibility(){
2267    if (!table) return;
2268
2269    // Whole-appraisal reprocessing replaces the appraisal result itself.
2270    // Legacy per-row Reprocess controls/drawers are never exposed.
2271    table.querySelectorAll('.pc-reprocess-btn').forEach(function(btn){
2272      btn.style.display = 'none';
2273    });
2274
2275    table.querySelectorAll('.pc-recycle-row').forEach(function(row){
2276      row.style.display = 'none';
2277    });
2278  }
2279
2280  function rerenderAllRecycleBoxes(){
2281    getReprocessEff();
2282    if (!table) return;
2283    table.querySelectorAll('.pc-recycle').forEach(renderRecycleBox);
2284    syncRecycleVisibility();
2285  }
2286
2287  if (showReprocessToggle) {
2288    showReprocessToggle.addEventListener('change', function(){
2289      syncRecycleVisibility();
2290
2291      // The checkbox is an appraisal MODE, not a per-row display option.
2292      // If there is pasted input, immediately rebuild the entire result set.
2293      if (taItems && taItems.value.trim()) {
2294        lastAppraisal = null;
2295        run();
2296      }
2297    });
2298  }
2299
2300  if (reprocessEffInput) {
2301    reprocessEffInput.addEventListener('input', function(){
2302      getReprocessEff();
2303    });
2304
2305    reprocessEffInput.addEventListener('change', function(){
2306      getReprocessEff();
2307      syncRecycleVisibility();
2308
2309      if (
2310        showReprocessToggle
2311        && showReprocessToggle.checked
2312        && taItems
2313        && taItems.value.trim()
2314      ) {
2315        lastAppraisal = null;
2316        run();
2317      }
2318    });
2319
2320    getReprocessEff();
2321  }
2322
2323  function reprocessSplitPrice(buy, sell){
2324    buy = Number(buy); sell = Number(sell);
2325    buy = Number.isFinite(buy) && buy > 0 ? buy : 0;
2326    sell = Number.isFinite(sell) && sell > 0 ? sell : 0;
2327    if (buy > 0 && sell > 0) return (buy + sell) / 2;
2328    return buy > 0 ? buy : sell;
2329  }
2330
2331  function recycleHtml(recipe, lineQty){
2332    if (!recipe || !Array.isArray(recipe.materials) || !recipe.materials.length) return '';
2333    const portion = Math.max(1, Number(recipe.portion_size || 1));
2334    const qty = Math.max(1, Number(lineQty || 1));
2335    const intactBuy = Math.max(0, Number(recipe.amarr_buy_unit || 0));
2336    const intactSell = Math.max(0, Number(recipe.amarr_sell_unit || 0));
2337    const intactSplit = Math.max(0, Number(recipe.amarr_split_unit || reprocessSplitPrice(intactBuy, intactSell)));
2338    let html = '<details class="pc-recycle" data-line-qty="' + escapeHtml(String(qty)) + '" data-portion="' + escapeHtml(String(portion)) + '" data-intact-split="' + escapeHtml(String(intactSplit)) + '">';
2339    html += '<summary><span>♻ Recyclable / Reprocessable</span><span class="pc-recycle-summary-value">calculating…</span></summary>';
2340    html += '<div class="pc-recycle-body">';
2341    html += '<div class="pc-recycle-head"><div class="pc-recycle-note">Recovered value uses <strong>Amarr Split</strong> — the midpoint between Amarr max-buy and min-sell. Recovered quantities use the <strong>Reprocess entire appraisal</strong> set above and round down to whole units.</div></div>';
2342    html += '<div class="pc-recycle-kpis">';
2343    html += '<div class="pc-recycle-kpi"><div class="k">Intact Value · Split</div><div class="v pc-rp-intact">—</div></div>';
2344    html += '<div class="pc-recycle-kpi"><div class="k">Recovered Value · Split</div><div class="v pc-rp-recovered-total">—</div></div>';
2345    html += '<div class="pc-recycle-kpi pc-rp-delta-card"><div class="k">ISK Difference</div><div class="v pc-rp-delta">—</div></div>';
2346    html += '<div class="pc-recycle-kpi pc-rp-pct-card"><div class="k">% Difference · Reprocessed vs Item</div><div class="v pc-rp-pct">—</div></div>';
2347    html += '</div>';
2348    html += '<div class="pc-recycle-tablewrap"><table class="pc-recycle-table"><thead><tr><th>
2348Output Material</th><th>Base Qty / Portion</th><th>Recovered Qty</th><th>Amarr Split / Unit</th><th>Recovered Value · Split</th></tr></thead><tbody>';
2349    for (const mat of recipe.materials) {
2350      const baseQty = Math.max(0, Number(mat.quantity || 0));
2351      const split = Math.max(0, Number(mat.amarr_split_unit || reprocessSplitPrice(mat.amarr_buy_unit, mat.amarr_sell_unit)));
2352      html += '<tr class="pc-rp-row" data-base-qty="' + escapeHtml(String(baseQty)) + '" data-split-unit="' + escapeHtml(String(split)) + '">';
2353      html += '<td><strong>' + escapeHtml(String(mat.name || ('TypeID ' + String(mat.type_id || '')))) + '</strong><div class="hint">TypeID #' + escapeHtml(fmtInt(mat.type_id || 0)) + '</div></td>';
2354      html += '<td>' + escapeHtml(fmtInt(baseQty)) + '</td><td class="pc-rp-qty">—</td><td class="pc-rp-unit">' + (split > 0 ? escapeHtml(fmtISK(split)) : '—') + '</td><td class="pc-rp-value">—</td></tr>';
2355    }
2356    html += '</tbody></table></div>';
2357    html += '<div class="pc-recycle-foot">Comparison uses only full reprocessing portions. Any remainder stays intact and is excluded from both sides of the comparison. If only one Amarr market side is available, that price is used as the Split fallback.</div>';
2358    html += '</div></details>';
2359    return html;
2360  }
2361
2362  function renderRecycleBox(box){
2363    if (!box) return;
2364    const pct = getReprocessEff();
2365
2366    const lineQty = Math.max(0, Math.floor(Number(box.dataset.lineQty || 0)));
2367    const portion = Math.max(1, Math.floor(Number(box.dataset.portion || 1)));
2368    const fullPortions = Math.floor(lineQty / portion);
2369    const usedQty = fullPortions * portion;
2370    const remainder = Math.max(0, lineQty - usedQty);
2371    const intactSplitUnit = Math.max(0, Number(box.dataset.intactSplit || 0));
2372    const intactValue = usedQty * intactSplitUnit;
2373    let recoveredTotal = 0;
2374    let pricedMaterials = 0;
2375    const materialRows = Array.from(box.querySelectorAll('.pc-rp-row'));
2376    const totalMaterials = materialRows.length;
2377
2378    materialRows.forEach(function(row){
2379      const baseQty = Math.max(0, Number(row.dataset.baseQty || 0));
2380      const splitUnit = Math.max(0, Number(row.dataset.splitUnit || 0));
2381      const recoveredQty = Math.floor(baseQty * fullPortions * (pct / 100));
2382      const recoveredValue = recoveredQty * splitUnit;
2383      if (splitUnit > 0) { recoveredTotal += recoveredValue; pricedMaterials++; }
2384      const q = row.querySelector('.pc-rp-qty');
2385      const v = row.querySelector('.pc-rp-value');
2386      if (q) q.textContent = fmtInt(recoveredQty);
2387      if (v) v.textContent = splitUnit > 0 ? fmtISK(recoveredValue) : '—';
2388    });
2389
2390    const pricesComplete = totalMaterials > 0 && pricedMaterials === totalMaterials;
2391    const canCompare = fullPortions > 0 && intactSplitUnit > 0 && pricesComplete;
2392    const delta = recoveredTotal - intactValue;
2393    const pctDiff = canCompare ? (delta / intactValue) * 100 : null;
2394    const intactEl = box.querySelector('.pc-rp-intact');
2395    const recoveredEl = box.querySelector('.pc-rp-recovered-total');
2396    const deltaEl = box.querySelector('.pc-rp-delta');
2397    const pctEl = box.querySelector('.pc-rp-pct');
2398    const summary = box.querySelector('.pc-recycle-summary-value');
2399    const deltaCard = box.querySelector('.pc-rp-delta-card');
2400    const pctCard = box.querySelector('.pc-rp-pct-card');
2401
2402    if (intactEl) intactEl.textContent = (fullPortions > 0 && intactSplitUnit > 0) ? fmtISK(intactValue) : '—';
2403    if (recoveredEl) recoveredEl.textContent = (fullPortions > 0 && pricesComplete) ? fmtISK(recoveredTotal) : '—';
2404    if (deltaEl) deltaEl.textContent = canCompare ? ((delta > 0 ? '+' : '') + fmtISK(delta)) : '—';
2405    if (pctEl) pctEl.textContent = pctDiff === null ? '—' : ((pctDiff > 0 ? '+' : '') + pctDiff.toFixed(2) + '%');
2406    [deltaCard,pctCard].forEach(function(card){ if(card) card.classList.remove('positive','negative'); });
2407    box.classList.remove('positive','negative');
2408    if (canCompare && delta > 0) {
2409      if(deltaCard) deltaCard.classList.add('positive');
2410      if(pctCard) pctCard.classList.add('positive');
2411      box.classList.add('positive');
2412    }
2413    if (canCompare && delta < 0) {
2414      if(deltaCard) deltaCard.classList.add('negative');
2415      if(pctCard) pctCard.classList.add('negative');
2416      box.classList.add('negative');
2417    }
2418
2419    if (summary) {
2420      if (fullPortions <= 0) summary.textContent = pct.toFixed(1).replace(/\.0$/,'') + '% · need ' + fmtInt(porti
2420on) + ' per portion';
2421      else if (pctDiff !== null) summary.textContent = pct.toFixed(1).replace(/\.0$/,'') + '% · ' + (pctDiff > 0 ? '+' : '') + pctDiff.toFixed(2) + '% vs intact' + (remainder > 0 ? ' · ' + fmtInt(remainder) + ' remainder' : '');
2422      else summary.textContent = pct.toFixed(1).replace(/\.0$/,'') + '% · Amarr Split pricing incomplete';
2423    }
2424  }
2425
2426  // CMS_PRICECHECK_RECYCLE_ROW_RESTORE_V2
2427  // Exact helper restored from the known-good pre-Split backup.
2428
2429  function buildRecycleRow(r){
2430    const html = recycleHtml(
2431      r && r.reprocessing ? r.reprocessing : null,
2432      Number((r && r.qty) || 1)
2433    );
2434    if (!html) return null;
2435
2436    const tr = document.createElement('tr');
2437    tr.className = 'pc-recycle-row';
2438    tr.dataset.drawerKind = 'reprocess';
2439    tr.style.display = 'none';
2440
2441    const td = document.createElement('td');
2442    td.colSpan = 7;
2443    td.innerHTML = html;
2444
2445    tr.appendChild(td);
2446    return tr;
2447  }
2448
2449
2450
2451  function buildRow(r, adjPct){
2452    const tr = document.createElement('tr');
2453    tr.className = 'pc-price-row';
2454
2455    const tdItem = document.createElement('td');
2456    const tdQty = document.createElement('td');
2457    const tdBuy = document.createElement('td');
2458    const tdSell = document.createElement('td');
2459    const tdBuyTotal = document.createElement('td');
2460    const tdSellTotal = document.createElement('td');
2461    const tdActions = document.createElement('td');
2462
2463    tdItem.className = 'pc-item-cell';
2464    tdQty.className = 'pc-num';
2465    tdBuy.className = 'pc-num';
2466    tdSell.className = 'pc-num';
2467    tdBuyTotal.className = 'pc-num';
2468    tdSellTotal.className = 'pc-num';
2469    tdActions.className = 'pc-actions-cell';
2470
2471    const qty = Math.max(1, Number(r.qty || 1));
2472    const factor = 1 + (clampPct(adjPct) / 100);
2473
2474    const minSell =
2475      (r.min_sell !== null && typeof r.min_sell !== 'undefined')
2476        ? Number(r.min_sell)
2477        : NaN;
2478
2479    const maxBuy =
2480      (r.max_buy !== null && typeof r.max_buy !== 'undefined')
2481        ? Number(r.max_buy)
2482        : NaN;
2483
2484    if (r.error) {
2485      tdItem.innerHTML =
2486        '<strong>' + escapeHtml(r.name || r.input || 'Unknown') + '</strong>'
2487        + '<div class="hint" style="margin-top:4px">'
2488        + escapeHtml(r.error)
2489        + '</div>';
2490
2491      tdQty.textContent = fmtInt(qty);
2492      tdBuy.textContent = '—';
2493      tdSell.textContent = '—';
2494      tdBuyTotal.textContent = '—';
2495      tdSellTotal.textContent = '—';
2496      tdActions.innerHTML =
2497        '<button type="button" class="btn ghost pc-row-action pc-market-btn high" disabled>'
2498        + '<span class="pc-market-confidence">ERROR</span>'
2499        + '</button>';
2500
2501      tr.style.opacity = '0.82';
2502
2503    } else {
2504      const nm = r.item_name || r.name || r.input || '';
2505      const maxBuyAdj = Number.isFinite(maxBuy) ? maxBuy * factor : NaN;
2506      const minSellAdj = Number.isFinite(minSell) ? minSell * factor : NaN;
2507      const splitAdj =
2508        Number.isFinite(maxBuyAdj) && Number.isFinite(minSellAdj)
2509          ? (maxBuyAdj + minSellAdj) / 2
2510          : NaN;
2511
2512      const iSell = r.immediate_sell && typeof r.immediate_sell === 'object'
2513        ? r.immediate_sell
2514        : null;
2515
2516      const iBuy = r.immediate_buy && typeof r.immediate_buy === 'object'
2517        ? r.immediate_buy
2518        : null;
2519
2520      const iSellAvg =
2521        iSell && Number.isFinite(Number(iSell.average))
2522          ? Number(iSell.average) * factor
2523          : NaN;
2524
2525      const iBuyAvg =
2526        iBuy && Number.isFinite(Number(iBuy.average))
2527          ? Number(iBuy.average) * factor
2528          : NaN;
2529
2530      const iSellFill = iSell ? Number(iSell.fill_pct || 0) : 0;
2531      const iBuyFill = iBuy ? Number(iBuy.fill_pct || 0) : 0;
2532
2533      // CMS_PRICECHECK_PHASE3_ITEM_LINK
2534      const marketItemUrl = r.type_id ? ('/eve-market/?type_id=' + encodeURIComponent(r.type_id)) : '';
2535      tdItem.innerHTML =
2536        (marketItemUrl
2537          ? '<strong><a href="' + marketItemUrl + '" title="Open item market page">' + escapeHtml(nm) + '</a></strong>'
2538          : '<strong>' + escapeHtml(nm) + '</strong>')
2539        + '<div class="pc-advanced-inline">'
2540        + 'Immediate Sell: <strong>' + escapeHtml(fmtISK(iSellAvg)) + '</strong>'
2541        + ' · ' + escapeHtml(iSellFill.toFixed(1)) + '%'
2542        + ' &nbsp;|&nbsp; Split: <strong>' + escapeHtml(fmtISK(splitAdj)) + '</strong>'
2543        + ' &nbsp;|&nbsp; Immediate Buy: <strong>' + escapeHtml(fmtISK(iBuyAvg)) + '</strong>'
2544        + ' · ' + escapeHtml(iBuyFill.toFixed(1)) + '%'
2545        + '</div>';
2546
2547      const iSellLine = iSell && Number.isFinite(Number(iSell.line_total))
2548        ? Number(iSell.line_total) * factor
2549        : NaN;
2550      const iBuyLine = iBuy && Number.isFinite(Number(iBuy.line_total))
2551        ? Number(iBuy.line_total) * factor
2552        : NaN;
2553
2554      // Basic columns are quantity-aware: what this exact line can execute for
2555      // now, not max-buy/min-sell multiplied beyond available order depth.
2556      tdQty.textContent = fmtInt(qty);
2557      tdBuy.textContent = fmtISK(Number.isFinite(iSellAvg) ? iSellAvg : maxBuyAdj);
2558      tdSell.textContent = fmtISK(Number.isFinite(iBuyAvg) ? iBuyAvg : minSellAdj);
2559      tdBuyTotal.textContent = fmtISK(Number.isFinite(iSellLine) ? iSellLine : ((Number.isFinite(maxBuyAdj) ? maxBuyAdj : 0) * qty));
2560      tdSellTotal.textContent = fmtISK(Number.isFinite(iBuyLine) ? iBuyLine : ((Number.isFinite(minSellAdj) ? minSellAdj : 0) * qty));
2561
2562      const actions = [];
2563
2564      if (r.market_intelligence && typeof r.market_intelligence === 'object') {
2565        const intel = r.market_intelligence;
2566        const warnings = Array.isArray(intel.warnings) ? intel.warnings : [];
2567        const conf = intel.confidence || {};
2568        const current = intel.current || {};
2569
2570        const confidenceLabel = String(conf.label || '—');
2571        const confidenceScore = Number(conf.score || 0);
2572        const spread = Number(current.spread_pct);
2573        const warningCount = warnings.length;
2574
2575        const highCount = warnings.filter(function(w){
2576          return String((w && w.severity) || '').toLowerCase() === 'high';
2577        }).length;
2578
2579        const warningSeverity =
2580          highCount > 0 || confidenceLabel.toLowerCase() === 'low'
2581            ? 'high'
2582            : (
2583                warningCount > 0 || confidenceLabel.toLowerCase() === 'moderate'
2584                  ? 'warning'
2585                  : 'good'
2586              );
2587
2588        const spreadText =
2589          Number.isFinite(spread)
2590            ? spread.toFixed(1) + '%'
2591            : '—';
2592
2593        const noticeText =
2594          highCount > 0
2595            ? String(highCount) + '!'
2596            : String(warningCount);
2597
2598        const titleBits = [
2599          'Confidence ' + confidenceLabel + ' ' + confidenceScore + '/100',
2600          'Spread ' + spreadText,
2601          warningCount + ' notice' + (warningCount === 1 ? '' : 's')
2602        ];
2603
2604        if (highCount > 0) {
2605          titleBits.push(highCount + ' high-priority');
2606        }
2607
2608        actions.push(
2609          '<button type="button"'
2610          + ' class="btn ghost pc-row-action pc-market-btn ' + warningSeverity + '"'
2611          + ' data-pc-action="intel"'
2612          + ' title="' + escapeHtml(titleBits.join(' · ')) + '">'
2613          + '<span class="pc-market-confidence">' + escapeHtml(confidenceLabel.toUpperCase()) + '</span>'
2614          + '<span class="pc-market-spread">' + escapeHtml(spreadText) + '</span>'
2615          + '<span class="pc-market-notices">' + escapeHtml(noticeText) + '</span>'
2616          + '</button>'
2617        );
2618      } else {
2619        actions.push(
2620          '<button type="button" class="btn ghost pc-row-action pc-market-btn none" disabled>'
2621          + '<span class="pc-market-confidence">NO DATA</span>'
2622          + '</button>'
2623        );
2624      }
2625
2626      if (
2627        r.reprocessing
2628        && Array.isArray(r.reprocessing.materials)
2629        && r.reprocessing.materials.length
2630      ) {
2631        actions.push(
2632          '<button type="button"'
2633          + ' class="btn ghost pc-row-action pc-reprocess-btn"'
2634          + ' data-pc-action="reprocess"'
2635          + ' style="display:none">'
2636          + '♻ Reprocess'
2637          + '</button>'
2638        );
2639      }
2640
2641      tdActions.innerHTML =
2642        '<div class="pc-row-actions">'
2643        + actions.join('')
2644        + '</div>';
2645    }
2646
2647    tr.appendChild(tdItem);
2648    tr.appendChild(tdQty);
2649    tr.appendChild(tdBuy);
2650    tr.appendChild(tdSell);
2651    tr.appendChild(tdBuyTotal);
2652    tr.appendChild(tdSellTotal);
2653    tr.appendChild(tdActions);
2654
2655    return tr;
2656  }
2657
2658
2659  // CMS_PRICECHECK_PHASE2_INTELLIGENCE_JS
2660  function intelNum(v){
2661    const n = Number(v);
2662    return Number.isFinite(n) ? n : null;
2663  }
2664
2665  function intelPct(v){
2666    const n = intelNum(v);
2667    if (n === null) return 'Building';
2668    const sign = n > 0 ? '+' : '';
2669    return sign + n.toFixed(Math.abs(n) >= 100 ? 0 : 1) + '%';
2670  }
2671
2672  function intelPctClass(v){
2673    const n = intelNum(v);
2674    if (n === null || Math.abs(n) < 0.0001) return '';
2675    return n > 0 ? 'up' : 'down';
2676  }
2677
2678  function intelSparkline(series, factor){
2679    const rows = Array.isArray(series) ? series : [];
2680    const points = rows
2681      .map(function(p){
2682        const v = intelNum(p && p.split);
2683        return v !== null && v > 0 ? {date:String(p.date || ''), value:v * factor} : null;
2684      })
2685      .filter(Boolean);
2686
2687    if (points.length < 2) {
2688      return '<div class="pc-intel-history-note">Daily history is still building. The chart appears after at least two daily samples exist.</div>';
2689    }
2690
2691    const vals = points.map(p => p.value);
2692    let lo = Math.min.apply(null, vals);
2693    let hi = Math.max.apply(null, vals);
2694    if (!(hi > lo)) { hi = lo + 1; }
2695
2696    const w = 260;
2697    const h = 48;
2698    const pad = 3;
2699    const coords = points.map(function(p, i){
2700      const x = pad + ((w - pad * 2) * (i / Math.max(1, points.length - 1)));
2701      const y = pad + ((h - pad * 2) * (1 - ((p.value - lo) / (hi - lo))));
2702      return x.toFixed(1) + ',' + y.toFixed(1);
2703    }).join(' ');
2704
2705    const title = escapeHtml(points[0].date + ' → ' + points[points.length - 1].date);
2706
2707    return '<svg class="pc-sparkline" viewBox="0 0 '+w+' '+h+'" role="img" aria-label="Split price history '+title+'">'
2708      + '<line class="pc-sparkline-grid" x1="3" y1="24" x2="257" y2="24"></line>'
2709      + '<polyline class="pc-sparkline-line" points="'+coords+'"></polyline>'
2710      + '</svg>'
2711      + '<div class="pc-intel-history-note">'
2712      + escapeHtml(points.length + ' daily samples • ' + points[0].date + ' → ' + points[points.length - 1].date)
2713      + '</div>';
2714  }
2715
2716
2717  function buildIntelRow(r, adjPct){
2718    const intel = r && r.market_intelligence;
2719    if (!intel || typeof intel !== 'object') return null;
2720
2721    const tr = document.createElement('tr');
2722    tr.className = 'pc-intel-row';
2723    tr.dataset.drawerKind = 'intel';
2724    tr.style.display = 'none';
2725
2726    const td = document.createElement('td');
2727    td.colSpan = 7;
2728
2729    const factor = 1 + (clampPct(adjPct) / 100);
2730    const hist = intel.history || {};
2731    const depth = intel.depth || {};
2732    const liq = intel.liquidity || {};
2733    const conf = intel.confidence || {};
2734    const warnings = Array.isArray(intel.warnings) ? intel.warnings : [];
2735
2736    const median = intelNum(hist.median_30d);
2737    const spread = intelNum((intel.current || {}).spread_pct);
2738    const sellImpact = intelNum(liq.immediate_sell_impact_pct);
2739    const buyImpact = intelNum(liq.immediate_buy_impact_pct);
2740    const samples = Number(hist.samples || 0);
2741    const daysCovered = Number(hist.days_covered || 0);
2742    const change1 = intelNum(hist.change_1d_pct);
2743    const change7 = intelNum(hist.change_7d_pct);
2744    const change30 = intelNum(hist.change_30d_pct);
2745    const confidenceLabel = String(conf.label || '—');
2746    const confidenceScore = Number(conf.score || 0);
2747
2748    const warningHtml = warnings.length
2749      ? '<div class="pc-detail-warnings">' + warnings.map(function(w){
2750          const sev = (w && w.severity === 'high') ? ' high' : '';
2751          return '<div class="pc-detail-warning'+sev+'"><strong>'
2752            + escapeHtml(String(w.title || 'Market notice'))
2753            + '</strong>'
2754            + escapeHtml(String(w.message || ''))
2755            + '</div>';
2756        }).join('') + '</div>'
2757      : '<div class="pc-detail-ok">No material warning thresholds are currently triggered.</div>';
2758
2759    const historyNote = samples < 2
2760      ? 'History is still building. Longer change windows appear only after enough real daily samples exist.'
2761      : ('History coverage: ' + daysCovered + ' day' + (daysCovered === 1 ? '' : 's') + '.');
2762
2763    td.innerHTML =
2764      '<section class="pc-detail-drawer">'+
2765        '<div class="pc-detail-head">'+
2766          '<div>'+
2767            '<div class="pc-detail-title">Market Intelligence · '+escapeHtml(String(r.item_name || r.name || r.input || 'Item'))+'</div>'+
2768            '<div class="pc-detail-sub">Advanced market data is shown only when requested.</div>'+
2769          '</div>'+
2770          '<button type="button" class="btn ghost pc-row-action" data-pc-action="close-drawer">Close</button>'+
2771        '</div>'+
2772        '<div class="pc-detail-kpis">'+
2773          '<div class="pc-detail-kpi"><div class="k">Quote Confidence</div><div class="v">'+escapeHtml(confidenceLabel)+' · '+escapeHtml(String(confidenceScore))+'/100</div></div>'+
2774          '<div class="pc-detail-kpi"><div class="k">Spread</div><div class="v">'+escapeHtml(spread !== null ? spread.toFixed(1)+'%' : '—')+'</div></div>'+
2775          '<div class="pc-detail-kpi"><div class="k">30D Median</div><div class="v">'+escapeHtml(median !== null ? fmtISK(median * factor) : 'Building')+'</div></div>'+
2776          '<div class="pc-detail-kpi"><div class="k">History</div><div class="v">'+escapeHtml(String(samples))+' daily</div></div>'+
2777        '</div>'+
2778        '<div class="pc-detail-grid">'+
2779          '<div class="pc-detail-panel">'+
2780            '<div class="pc-detail-panel-title">Price History</div>'+
2781            '<div class="pc-detail-kpis" style="grid-template-columns:repeat(3,minmax(0,1fr));margin-bottom:7px">'+
2782              '<div class="pc-detail-kpi"><div class="k">1D</div><div class="v '+intelPctClass(change1)+'">'+escapeHtml(intelPct(change1))+'</div></div>'+
2783              '<div class="pc-detail-kpi"><div class="k">7D</div><div class="v '+intelPctClass(change7)+'">'+escapeHtml(intelPct(change7))+'</div></div>'+
2784              '<div class="pc-detail-kpi"><div class="k">30D</div><div class="v '+intelPctClass(change30)+'">'+escapeHtml(intelPct(change30))+'</div></div>'+
2785            '</div>'+
2786            intelSparkline(hist.series || [], factor)+
2787            '<div class="pc-intel-history-note">'+escapeHtml(historyNote)+'</div>'+
2788          '</div>'+
2789          '<div class="pc-detail-panel">'+
2790            '<div class="pc-detail-panel-title">Depth & Market Impact</div>'+
2791            '<div class="pc-detail-depth">'+
2792              '<div><span>1% Buy VWAP</span><strong>'+escapeHtml(intelNum(depth.buy_vwap_1pct)!==null ? fmtISK(Number(depth.buy_vwap_1pct)*factor) : '—')+'</strong></div>'+
2793              '<div><span>1% Buy Depth</span><strong>'+escapeHtml(fmtInt(Number(depth.buy_depth_1pct || 0)))+'</strong></div>'+
2794              '<div><span>5% Buy VWAP</span><strong>'+escapeHtml(intelNum(depth.buy_vwap_5pct)!==null ? fmtISK(Number(depth.buy_vwap_5pct)*factor) : '—')+'</strong></div>'+
2795              '<div><span>5% Buy Depth</span><strong>
2795'+escapeHtml(fmtInt(Number(depth.buy_depth_5pct || 0)))+'</strong></div>'+
2796              '<div><span>1% Sell VWAP</span><strong>'+escapeHtml(intelNum(depth.sell_vwap_1pct)!==null ? fmtISK(Number(depth.sell_vwap_1pct)*factor) : '—')+'</strong></div>'+
2797              '<div><span>1% Sell Depth</span><strong>'+escapeHtml(fmtInt(Number(depth.sell_depth_1pct || 0)))+'</strong></div>'+
2798              '<div><span>5% Sell VWAP</span><strong>'+escapeHtml(intelNum(depth.sell_vwap_5pct)!==null ? fmtISK(Number(depth.sell_vwap_5pct)*factor) : '—')+'</strong></div>'+
2799              '<div><span>5% Sell Depth</span><strong>'+escapeHtml(fmtInt(Number(depth.sell_depth_5pct || 0)))+'</strong></div>'+
2800              '<div><span>Immediate Sell Impact</span><strong>'+escapeHtml(sellImpact !== null ? sellImpact.toFixed(1)+'%' : '—')+'</strong></div>'+
2801              '<div><span>Immediate Buy Impact</span><strong>'+escapeHtml(buyImpact !== null ? buyImpact.toFixed(1)+'%' : '—')+'</strong></div>'+
2802            '</div>'+
2803          '</div>'+
2804        '</div>'+
2805        warningHtml+
2806        '<div class="pc-intel-history-note">Warnings describe measurable market conditions; they are not claims of manipulation.</div>'+
2807      '</section>';
2808
2809    tr.appendChild(td);
2810    return tr;
2811  }
2812
2813
2814  function renderIntelSummary(data){
2815    const el = document.getElementById('pcIntelSummary');
2816    const btn = document.getElementById('pcHealthToggle');
2817    if (!el) return;
2818
2819    const summary = data && data.intelligence_summary ? data.intelligence_summary : null;
2820    if (!summary || !Number(summary.items_analyzed || 0)) {
2821      el.className = 'pc-intel-summary';
2822      el.innerHTML = '';
2823      if (btn) {
2824        btn.textContent = 'Market Health';
2825        btn.classList.remove('notice', 'high');
2826      }
2827      return;
2828    }
2829
2830    const analyzed = Number(summary.items_analyzed || 0);
2831    const warnings = Number(summary.warnings || 0);
2832    const high = Number(summary.high_warnings || 0);
2833    const ready7 = Number(summary.history_7d_ready_items || 0);
2834    const ready30 = Number(summary.history_30d_ready_items || 0);
2835    const conf = summary.confidence || {};
2836
2837    el.className = 'pc-intel-summary show';
2838    el.innerHTML =
2839      '<div class="pc-intel-summary-head">'
2840      + '<div><div class="pc-intel-summary-title">Market Health</div><div class="hint">Summary only — open an item Details drawer for depth, history, and notices.</div></div>'
2841      + '</div>'
2842      + '<div class="pc-intel-summary-bits">'
2843      + '<span class="pc-intel-chip">'+escapeHtml(String(analyzed))+' analyzed</span>'
2844      + '<span class="pc-intel-chip">Confidence '+escapeHtml(String(conf.High || 0))+' high · '+escapeHtml(String(conf.Moderate || 0))+' moderate · '+escapeHtml(String(conf.Low || 0))+' low</span>'
2845      + '<span class="pc-intel-chip'+(high ? ' high' : (warnings ? ' warning' : ''))+'">'+escapeHtml(String(warnings))+' notice'+(warnings===1?'':'s')+'</span>'
2846      + '<span class="pc-intel-chip">7D ready '+escapeHtml(String(ready7))+'</span>'
2847      + '<span class="pc-intel-chip">30D ready '+escapeHtml(String(ready30))+'</span>'
2848      + '</div>';
2849
2850    if (btn) {
2851      btn.textContent = warnings ? ('Market Health · ' + warnings) : 'Market Health';
2852      btn.classList.toggle('notice', warnings > 0 && high < 1);
2853      btn.classList.toggle('high', high > 0);
2854    }
2855  }
2856
2857
2858  // CMS_PRICECHECK_UXV2_JS
2859  const pcAdvancedToggle = document.getElementById('pcAdvancedToggle');
2860  const pcHealthToggle = document.getElementById('pcHealthToggle');
2861
2862  function pcSetAdvanced(on){
2863    if (!results) return;
2864    results.classList.toggle('pc-advanced-on', !!on);
2865    if (pcAdvancedToggle) {
2866      pcAdvancedToggle.classList.toggle('active', !!on);
2867      pcAdvancedToggle.setAttribute('aria-pressed', on ? 'true' : 'false');
2868      pcAdvancedToggle.textContent = on ? 'Basic Pricing' : 'Advanced Pricing';
2869    }
2870  }
2871
2872  function pcSetHealth(open){
2873    if (!results) return;
2874    results.classList.toggle('pc-health-open', !!open);
2875    if (pcHealthToggle) {
2876      pcHealthToggle.classList.toggle('active', !!open);
2877      pcHealthToggle.setAttribute('aria-pressed', open ? 'true' : 'false');
2878    }
2879  }
2880
2881  pcSetAdvanced(false);
2882  pcSetHealth(false);
2883
2884  if (pcAdvancedToggle) {
2885    pcAdvancedToggle.addEventListener('click', function(){
2886      pcSetAdvanced(!results.classList.contains('pc-advanced-on'));
2887    });
2888  }
2889
2890  if (pcHealthToggle) {
2891    pcHealthToggle.addEventListener('click', function(){
2892      pcSetHealth(!results.classList.contains('pc-health-open'));
2893    });
2894  }
2895
2896  function pcCloseAllDrawers(exceptRow){
2897    if (!table) return;
2898    table.querySelectorAll('.pc-intel-row, .pc-recycle-row').forEach(function(row){
2899      if (row !== exceptRow) row.style.display = 'none';
2900    });
2901    table.querySelectorAll('.pc-price-row').forEach(function(row){
2902      row.classList.remove('pc-row-open');
2903    });
2904  }
2905
2906  function pcFindDrawer(priceRow, kind){
2907    let row = priceRow ? priceRow.nextElementSibling : null;
2908    while (row && !row.classList.contains('pc-price-row')) {
2909      if (row.dataset && row.dataset.drawerKind === kind) return row;
2910      row = row.nextElementSibling;
2911    }
2912    return null;
2913  }
2914
2915  if (table && !table.dataset.uxv2Bound) {
2916    table.dataset.uxv2Bound = '1';
2917    table.addEventListener('click', function(e){
2918      const btn = e.target.closest('[data-pc-action]');
2919      if (!btn) return;
2920      const action = String(btn.dataset.pcAction || '');
2921
2922      if (action === 'close-drawer') {
2923        const drawerRow = btn.closest('tr');
2924        if (drawerRow) {
2925          drawerRow.style.display = 'none';
2926
2927          let prev = drawerRow.previousElementSibling;
2928          while (prev && !prev.classList.contains('pc-price-row')) {
2929            prev = prev.previousElementSibling;
2930          }
2931          if (prev) prev.classList.remove('pc-row-open');
2932        }
2933        return;
2934      }
2935
2936      const priceRow = btn.closest('.pc-price-row');
2937      if (!priceRow) return;
2938
2939      if (action === 'intel' || action === 'reprocess') {
2940        const target = pcFindDrawer(priceRow, action === 'intel' ? 'intel' : 'reprocess');
2941        if (!target) return;
2942        const opening = target.style.display === 'none' || !target.style.display;
2943        pcCloseAllDrawers(opening ? target : null);
2944        target.style.display = opening ? 'table-row' : 'none'; // CMS_PRICECHECK_UXV2_DRAWER_FIX
2945        priceRow.classList.toggle('pc-row-open', opening);
2946
2947        if (opening && action === 'reprocess') {
2948          const details = target.querySelector('details.pc-recycle');
2949          if (details) {
2950            details.open = true;
2951            try { renderRecycleBox(details); } catch(_) {}
2952          }
2953        }
2954
2955        if (opening) {
2956          try { pcApplyNegativeColors(target); } catch(_) {}
2957          target.scrollIntoView({block:'nearest', behavior:'smooth'});
2958        }
2959      }
2960    });
2961  }
2962
2963
2964  // CMS_PRICECHECK_UXV2_NEGATIVE_JS
2965  function pcApplyNegativeColors(root){
2966    const scope = root || document;
2967
2968    const selector = [
2969      '.pc-num',
2970      '.pc-totalhero .v',
2971      '.pc-advanced-total .v',
2972      '.pc-detail-kpi .v',
2973      '.pc-detail-depth strong',
2974      '.pc-intel-kpi .v',
2975      '.pc-recycle-kpi .v',
2976      '.pc-recycle-summary-value',
2977      '.pc-advanced-inline strong',
2978      '.hubbadge .h-val',
2979      '.hubbadge .pc-hub-advanced span:last-child'
2980    ].join(',');
2981
2982    scope.querySelectorAll(selector).forEach(function(el){
2983      const text = String(el.textContent || '')
2984        .replace(/\u2212/g, '-')
2985        .trim();
2986
2987      const negative =
2988        /^-\s*(?:[$€£¥]\s*)?[\d,.]+/.test(text)
2989        || /^-\s*[\d,.]+\s*(?:ISK|%|m³|B|M|K)?\b/i.test(text);
2990
2991      el.classList.toggle('pc-negative', negative);
2992    });
2993  }
2994
2995  function escapeHtml(s){
2996    return String(s)
2997      .replaceAll('&', '&amp;')
2998      .replaceAll('<', '&lt;')
2999      .replaceAll('>', '&gt;')
3000      .replaceAll('"', '&quot;')
3001      .replaceAll("'", '&#39;');
3002  }
3003
3004
3005  async function copyToClipboard(text){
3006    const t = String(text || '');
3007    if (!t) return false;
3008    try {
3009      await navigator.clipboard.writeText(t);
3010      return true;
3011    } catch (e) {
3012      try {
3013        const ta = document.createElement('textarea');
3014        ta.value = t;
3015        ta.setAttribute('readonly', '');
3016        ta.style.position = 'fixed';
3017        ta.style.left = '-9999px';
3018        document.body.appendChild(ta);
3019        ta.select();
3020        ta.setSelectionRange(0, ta.value.length);
3021        const ok = document.execCommand('copy');
3022        document.body.removeChild(ta);
3023        return !!ok;
3024      } catch(_) {
3025        return false;
3026      }
3027    }
3028  }
3029
3030  function flashCopied(btn){
3031    if (!btn) return;
3032    const old = btn.textContent;
3033    btn.textContent = '✓';
3034    btn.disabled = true;
3035    setTimeout(()=>{ btn.textContent = old; btn.disabled = false; }, 900);
3036  }
3037
3038  if (totals && !totals.dataset.copyBound) {
3039    totals.dataset.copyBound = '1';
3040    totals.addEventListener('click', async function(e){
3041      const b = e.target && e.target.closest ? e.target.closest('button[data-copy]') : null;
3042      if (!b) return;
3043      const which = b.getAttribute('data-copy') || '';
3044      let spanId = 'pcBuyTotal';
3045      if (which === 'immediate-sell') spanId = 'pcImmediateSellTotal';
3046      if (which === 'split') spanId = 'pcSplitTotal';
3047      if (which === 'immediate-buy') spanId = 'pcImmediateBuyTotal';
3048      if (which === 'sell') spanId = 'pcSellTotal';
3049      const span = document.getElementById(spanId);
3050      const val = span ? span.textContent.trim() : '';
3051      const ok = await copyToClipboard(val);
3052      flashCopied(b);
3053      if (!ok) {
3054        showMsg('Could not copy automatically. Your browser may block clipboard access here.', 'warn');
3055        results.style.display = '';
3056        setTimeout(()=>{ hideMsg(); }, 1600);
3057      }
3058    });
3059  }
3060
3061  async function run(){
3062    hideMsg();
3063    clearTable();
3064
3065    const fd = new FormData(form);
3066    const items = (fd.get('items') || '').toString();
3067    const regionId = (fd.get('region_id') || '10000043').toString();
3068    const csrf = (fd.get('csrf') || '').toString();
3069    const reprocessRequested = !!(showReprocessToggle && showReprocessToggle.checked);
3070    const reprocessEfficiency = getReprocessEff(); // CMS_PRICECHECK_REPROCESS_APPRAISAL_UI_V1
3071
3072    if (!items.trim()) {
3073      showMsg('Paste at least one item name.', 'warn');
3074      results.style.display = '';
3075      return;
3076    }
3077
3078    results.style.display = '';
3079    meta.textContent = '';
3080    totals.textContent = '';
3081    showMsg(reprocessRequested ? 'Working… reprocessing the entire appraisal and pricing recovered outputs.' : 'Working… resolving names + fetching market stats.', '');
3082
3083    setBusy(true);
3084
3085    try {
3086      const body = new URLSearchParams({
3087        items: items,
3088        region_id: regionId,
3089        csrf: csrf,
3090      });
3091
3092      if (reprocessRequested) {
3093        body.set('reprocess_mode', '1');
3094        body.set('reprocess_efficiency', String(reprocessEfficiency));
3095      }
3096
3097      const res = await fetch('/api/pricecheck.php', {
3098        method: 'POST',
3099        headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
3100        body: body.toString(),
3101        credentials: 'same-origin'
3102      });
3103
3104      const data = await res.json().catch(()=>null);
3105      if (!res.ok || !data || !data.ok) {
3106        const emsg = (data && data.error) ? data.error : ('HTTP ' + res.status);
3107        showMsg('<strong>Error:</strong> ' + escapeHtml(emsg), 'danger');
3108        return;
3109      }
3110
3111      hideMsg();
3112
3113      if (data.market) {
3114        renderMarketStatus(
3115          data.market,
3116          regionId
3117        );
3118      }
3119
3120      const adjPct = getAdjPct();
3121
3122      const regionName = data.region_name || ('Region ' + regionId);
3123      const ts = data.ts || '';
3124      meta.textContent = regionName
3125        + (adjPct ? (' • Buyback ' + (adjPct>0?'+':'') + adjPct + '%') : '')
3126        + (ts ? (' • ' + ts.replace('T',' ').replace('Z',' UTC')) : '');
3127
3128      const reprocessMeta = data.reprocessing_mode && data.reprocessing_mode.active
3129        ? data.reprocessing_mode
3130        : null;
3131
3132      if (reprocessMeta && meta) {
3133        meta.textContent +=
3134          ' • ♻ Reprocessed ' + Number(reprocessMeta.efficiency_pct || reprocessEfficiency).toFixed(1).replace(/\.0$/, '') + '%'
3135          + ' • ' + String(reprocessMeta.source_lines || 0) + ' source lines → '
3136          + String(reprocessMeta.final_types || 0) + ' final item types';
3137      }
3138
3139      const t = data.totals || {};
3140      const factor = 1 + (adjPct / 100);
3141
3142      const buyRaw = Number(t.buy_total || 0);
3143      const sellRaw = Number(t.sell_total || 0);
3144
3145      const splitRaw =
3146        Number.isFinite(Number(t.split_total))
3147          ? Number(t.split_total)
3148          : ((buyRaw + sellRaw) / 2);
3149
3150      const immediateSellRaw = Number(t.immediate_sell_total || 0);
3151      const immediateBuyRaw = Number(t.immediate_buy_total || 0);
3152      const buyAdj = buyRaw * factor;
3153      const immediateSellAdj = immediateSellRaw * factor;
3154      const splitAdj = splitRaw * factor;
3155      const immediateBuyAdj = immediateBuyRaw * factor;
3156      const sellAdj = sellRaw * factor;
3157
3158      // Headline values use quantity-aware executable depth. Top-of-book values
3159      // remain available in the API and advanced item intelligence.
3160      const buyDisplayAdj = immediateSellAdj;
3161      const sellDisplayAdj = immediateBuyAdj;
3162      const buyTxt = fmtISK(buyDisplayAdj);
3163      const immediateSellTxt = fmtISK(immediateSellAdj);
3164      const splitTxt = fmtISK(splitAdj);
3165      const immediateBuyTxt = fmtISK(immediateBuyAdj);
3166      const sellTxt = fmtISK(sellDisplayAdj);
3167
3168      const metaBits = [];
3169
3170      if (reprocessMeta) {
3171        metaBits.push(
3172          '♻ Reprocessed appraisal ' + escapeHtml(String(Number(reprocessMeta.efficiency_pct || reprocessEfficiency).toFixed(1).replace(/\.0$/, ''))) + '%'
3173        );
3174
3175        if (Number(reprocessMeta.remainder_qty || 0) > 0) {
3176          metaBits.push(
3177            escapeHtml(fmtInt(Number(reprocessMeta.remainder_qty || 0))) + ' remainder units retained'
3178          );
3179        }
3180
3181        if (Number(reprocessMeta.unprocessed_qty || 0) > 0) {
3182          metaBits.push(
3183            escapeHtml(fmtInt(Number(reprocessMeta.unprocessed_qty || 0))) + ' non-reprocessable units retained'
3184          );
3185        }
3186      }
3187
3188      if (adjPct) {
3189        metaBits.push(
3190          'Buyback '
3191          + (adjPct > 0 ? '+' : '')
3192          + escapeHtml(String(adjPct))
3193          + '%'
3194        );
3195      }
3196
3197      const immediateSellFill = Number(t.immediate_sell_fill_pct || 0);
3198      const immediateBuyFill = Number(t.immediate_buy_fill_pct || 0);
3199      if (immediateSellFill < 99.999) {
3200        metaBits.push('âš  Immediate Sell liquidity ' + escapeHtml(immediateSellFill.toFixed(1)) + '% filled');
3201      }
3202      if (immediateBuyFill < 99.999) {
3203        metaBits.push('âš  Immediate Buy liquidity ' + escapeHtml(immediateBuyFill.toFixed(1)) + '% filled');
3204      }
3205
3206      metaBits.push(
3207        escapeHtml(String(t.lines_ok || 0))
3208        + '/'
3209        + escapeHtml(String(t.lines || 0))
3210        + ' lines ok'
3211      );
3212
3213      totals.innerHTML =
3214        '<div class="pc-basic-totals">' +
3215          '<div class="pc-totalhero">' +
3216            '<div class="pc-totalhero-head">' +
3217              '<div><div class="k">Buy Value</div><div class="v" id="pcBuyTotal">
3217' + escapeHtml(buyTxt) + '</div></div>' +
3218              '<button type="button" class="btn ghost pc-copybtn" data-copy="buy" title="Copy buy total">⧉</button>' +
3219            '</div>' +
3220            '<div class="s">Executable buy-order depth for this exact quantity</div>' +
3221          '</div>' +
3222          '<div class="pc-totalhero">' +
3223            '<div class="pc-totalhero-head">' +
3224              '<div><div class="k">Sell Value</div><div class="v" id="pcSellTotal">' + escapeHtml(sellTxt) + '</div></div>' +
3225              '<button type="button" class="btn ghost pc-copybtn" data-copy="sell" title="Copy sell total">⧉</button>' +
3226            '</div>' +
3227            '<div class="s">Sell-order depth required to buy this exact quantity</div>' +
3228          '</div>' +
3229          '<div class="pc-basic-meta">' + metaBits.join(' <span class="hint">•</span> ') + '</div>' +
3230        '</div>' +
3231        '<div class="pc-advanced-totals">' +
3232          '<div class="pc-advanced-total"><div class="k">Immediate Sell</div><div class="v"><span id="pcImmediateSellTotal">' + escapeHtml(immediateSellTxt) + '</span> <button type="button" class="btn ghost pc-copybtn" data-copy="immediate-sell" title="Copy immediate-sell total">⧉</button></div></div>' +
3233          '<div class="pc-advanced-total"><div class="k">Split</div><div class="v"><span id="pcSplitTotal">' + escapeHtml(splitTxt) + '</span> <button type="button" class="btn ghost pc-copybtn" data-copy="split" title="Copy split total">⧉</button></div></div>' +
3234          '<div class="pc-advanced-total"><div class="k">Immediate Buy</div><div class="v"><span id="pcImmediateBuyTotal">' + escapeHtml(immediateBuyTxt) + '</span> <button type="button" class="btn ghost pc-copybtn" data-copy="immediate-buy" title="Copy immediate-buy total">⧉</button></div></div>' +
3235        '</div>';
3236
3237      // Snapshot exactly what this appraisal displayed so a short share link can
3238      // produce a rich Discord appraisal preview without repricing inside Discord.
3239      const appraisalPreview = (data.items || [])
3240        .filter(r => !r.error)
3241        .slice(0, 12)
3242        .map(r => {
3243          const nm = r.item_name || r.name || r.input || 'Unknown';
3244          const qty = Number(r.qty || 1);
3245          return String(nm) + ' - ' + qty.toLocaleString('en-US');
3246        });
3247
3248      lastAppraisal = {
3249        signature: [
3250          String(items).trim(),
3251          String(regionId),
3252          String(adjPct),
3253          reprocessRequested ? ('reprocess:' + String(reprocessEfficiency)) : 'raw'
3254        ].join('|'),
3255
3256        region_name: regionName,
3257        buy_total: buyDisplayAdj,
3258        split_total: splitAdj,
3259        sell_total: sellDisplayAdj,
3260        lines: Number(t.lines || 0),
3261        lines_ok: Number(t.lines_ok || 0),
3262        preview: appraisalPreview,
3263        reprocess_mode: reprocessRequested,
3264        reprocess_efficiency: reprocessRequested ? reprocessEfficiency : null
3265      };
3266
3267      const tbody = table.querySelector('tbody');
3268      
3269
3270      // 5-hub totals badges from this same local appraisal request
3271      try { loadAllHubTotals(adjPct, data); } catch(_) {}
3272      try { renderIntelSummary(data); } catch(_) {} // CMS_PRICECHECK_PHASE2_RENDER_SUMMARY
3273
3274// CMS_PRICECHECK_REPROCESS_APPRAISAL_RESULTS_V1
3275(data.items || []).forEach(function(r){
3276        tbody.appendChild(buildRow(r, adjPct));
3277        const intelRow = buildIntelRow(r, adjPct); // CMS_PRICECHECK_PHASE2_ITEM_ROW
3278        if (intelRow) tbody.appendChild(intelRow);
3279        const recycleRow = buildRecycleRow(r);
3280        if (recycleRow) tbody.appendChild(recycleRow);
3281      });
3282      rerenderAllRecycleBoxes();
3283      try { pcApplyNegativeColors(results); } catch(_) {}
3284      try { pcInitResultsAd(); } catch(_) {} // CMS_PUBLIC_REFERRAL_BOTTOM_INIT_V1
3285
3286      const unresolved = (data.items || []).filter(unresolvedIsNameFailure);
3287      if (unresolved.length) unresolvedOpen(unresolved);
3288
3289
3290// Save this run into "recent checks" (local to this browser)
3291try{
3292  const itemsText = items;
3293  const lines = Number(t.lines || 0) || countLines(itemsText);
3294  const entry = {
3295    when: new Date().toISOString(),
3296    items: itemsText,
3297    lines: lines,
3298    region_id: regionId,
3299    region_name: regionName,
3300    adj_pct: adjPct,
3301    total_isk: splitAdj
3302  };
3303
3304  let list = loadRecent();
3305  const sig = (String(entry.region_id) + '|' + String(entry.adj_pct) + '|' + String(entry.items).trim());
3306  list = list.filter(x => (String(x.region_id) + '|' + String(x.adj_pct) + '|' + String(x.items).trim()) !== sig);
3307  list.unshift(entry);
3308  if (list.length > RECENT_MAX) list = list.slice(0, RECENT_MAX);
3309  saveRecent(list);
3310  renderRecent();
3311}catch(_){}
3312
3313      // We do NOT auto-stuff the current state into the URL.
3314      // Share links are created only via the "Copy Share Link" button.
3315
3316      // CMS_PRICECHECK_RUN_RETURNS_APPRAISAL_V2
3317      return lastAppraisal;
3318
3319    } catch (e) {
3320      showMsg('<strong>Error:</strong> ' + escapeHtml(e && e.message ? e.message : e), 'danger');
3321    } finally {
3322      setBusy(false);
3323    }
3324  }
3325
3326  form && form.addEventListener('submit', function(e){
3327    e.preventDefault();
3328    run();
3329  });
3330
3331  btnClear && btnClear.addEventListener('click', function(){
3332    // Reset for a fresh run (do not re-fill from any defaults baked into the HTML).
3333    if (taItems) taItems.value = '';
3334    if (adjRange) { adjRange.value = '0'; syncAdjUI(); }
3335    hideMsg();
3336    clearTable();
3337    lastAppraisal = null;
3338    if (hubTotals) { hubTotals.style.display = 'none'; hubTotals.innerHTML = ''; }
3339    results.style.display = 'none';
3340    try {
3341      const u = new URL(window.location.href);
3342      u.searchParams.delete('items');
3343      u.searchParams.delete('item');
3344      u.searchParams.delete('adj_pct');
3345      u.searchParams.delete('share');
3346      history.replaceState(null, '', u.toString());
3347    } catch(e) {}
3348  });
3349
3350  // When coming back to this page via browser back/forward or normal navigation,
3351  // start clean unless this is an explicit share link.
3352  window.addEventListener('pageshow', function(){
3353    try {
3354      const u = new URL(window.location.href);
3355      const isShare = u.searchParams.has('items') || u.searchParams.has('item') || u.searchParams.has('share');
3356      if (!isShare) {
3357        if (taItems) taItems.value = '';
3358        if (adjRange) { adjRange.value = '0'; syncAdjUI(); }
3359        hideMsg();
3360        clearTable();
3361        if (hubTotals) { hubTotals.style.display = 'none'; hubTotals.innerHTML = ''; }
3362        results.style.display = 'none';
3363        // Keep the URL clean as well.
3364        u.searchParams.delete('adj_pct');
3365        u.searchParams.delete('items');
3366        u.searchParams.delete('item');
3367        u.searchParams.delete('share');
3368        history.replaceState(null, '', u.toString());
3369      }
3370    } catch(_) {}
3371  });
3372
3373  btnShare && btnShare.addEventListener('click', async function(){
3374    try {
3375      const fd = new FormData(form);
3376
3377      const items = (fd.get('items') || '').toString();
3378      const regionId = (fd.get('region_id') || '10000043').toString();
3379      const csrf = (fd.get('csrf') || '').toString();
3380      const adjPct = String(getAdjPct());
3381
3382      if (!items.trim()) {
3383        showMsg('Nothing to share yet — paste some items first.', 'w
3383arn');
3384        return;
3385      }
3386
3387      const wantedSignature = [
3388        String(items).trim(),
3389        String(regionId),
3390        String(Number(adjPct)),
3391        (showReprocessToggle && showReprocessToggle.checked) ? ('reprocess:' + String(getReprocessEff())) : 'raw'
3392      ].join('|');
3393
3394      let snap = lastAppraisal;
3395
3396      // If items/hub/adjustment changed since the previous appraisal, refresh it
3397      // automatically before creating the share link.
3398      if (!snap || snap.signature !== wantedSignature) {
3399        showMsg('Refreshing appraisal before creating the share link…', '');
3400        snap = await run();
3401
3402        if (!snap) {
3403          showMsg('Price Check must complete successfully before the appraisal can be shared.', 'warn');
3404          return;
3405        }
3406      }
3407
3408      const body = new URLSearchParams({
3409        items: items,
3410        region_id: regionId,
3411        adj_pct: adjPct,
3412        reprocess_mode: (showReprocessToggle && showReprocessToggle.checked) ? '1' : '0',
3413        reprocess_efficiency: String(getReprocessEff()),
3414        csrf: csrf,
3415
3416        region_name: String(snap.region_name || ''),
3417        buy_total: String(snap.buy_total || 0),
3418        split_total: String(snap.split_total || 0),
3419        sell_total: String(snap.sell_total || 0),
3420        lines: String(snap.lines || 0),
3421        lines_ok: String(snap.lines_ok || 0),
3422        preview_json: JSON.stringify(snap.preview || [])
3423      });
3424
3425      const res = await fetch('/api/sharelink.php', {
3426        method: 'POST',
3427        headers: {
3428          'Content-Type': 'application/x-www-form-urlencoded'
3429        },
3430        body: body.toString(),
3431        credentials: 'same-origin'
3432      });
3433
3434      const data = await res.json().catch(() => null);
3435
3436      if (!res.ok || !data || !data.ok || !data.code) {
3437        const emsg =
3438          (data && data.error)
3439            ? data.error
3440            : ('HTTP ' + res.status);
3441
3442        showMsg('<strong>Error:</strong> ' + escapeHtml(emsg), 'danger');
3443        return;
3444      }
3445
3446      const u = new URL(window.location.href);
3447
3448      u.searchParams.delete('items');
3449      u.searchParams.delete('item');
3450      u.searchParams.delete('region_id');
3451      u.searchParams.delete('adj_pct');
3452
3453      u.searchParams.set('share', data.code);
3454
3455      const copied = await copyToClipboard(u.toString());
3456
3457      if (copied) {
3458        showMsg(
3459          '<strong>Appraisal link copied.</strong> Discord will show the Split value and item preview.',
3460          'ok'
3461        );
3462      } else {
3463        showMsg(
3464          'Appraisal created, but the browser blocked automatic clipboard access. Copy the URL from the address bar.',
3465          'warn'
3466        );
3467      }
3468
3469      results.style.display = '';
3470
3471      setTimeout(() => {
3472        hideMsg();
3473      }, 2600);
3474
3475    } catch (e) {
3476      showMsg(
3477        'Could not create the appraisal link: '
3478        + escapeHtml(e && e.message ? e.message : String(e)),
3479        'warn'
3480      );
3481
3482      results.style.display = '';
3483    }
3484  });
3485
3486  // Make EVE clipboard paste Just Work™.
3487  // EVE often copies as TSV (tab-separated) with extra columns; normalize to "Item Qty" lines.
3488  function parseQtyClipboard(s){
3489    const cleaned = String(s || '').replace(/[\u00A0\t ,\.]/g, '').trim();
3490    if (!/^\d+$/.test(cleaned)) return null;
3491    let n = parseInt(cleaned, 10);
3492    if (!Number.isFinite(n) || n < 1) return null;
3493    if (n > 2000000000) n = 2000000000;
3494    return n;
3495  }
3496
3497  function normalizeClipboard(text){
3498    const t = String(text || '');
3499    if (!t.includes('\t')) return t;
3500    const lines = t.replace(/\r\n/g, '\n').replace(/\r/g, '\n').split('\n');
3501    const out = [];
3502    for (const ln of lines) {
3503      const raw = (ln || '').trim();
3504      if (!raw) continue;
3505      if (raw.includes('\t')) {
3506        const fields = raw.split(/\t+/).map(v => (v||'').trim()).filter(Boolean);
3507        if (fields.length >= 2) {
3508          let qty = null, qtyIdx = -1;
3509          for (let i=0; i<fields.length; i++) {
3510            const f = fields[i];
3511            if (/^[\d\s,.\u00A0]+$/.test(f)) {
3512              const q = parseQtyClipboard(f);
3513              if (q !== null) { qty = q; qtyIdx = i; break; }
3514            }
3515          }
3516          if (qty !== null) {
3517            let name = null;
3518            for (let i=0; i<fields.length; i++) {
3519              if (i === qtyIdx) continue;
3520              const f = fields[i];
3521              if (/^(type|item|name|quantity|qty)$/i.test(f)) continue;
3522              if (!/^[\d\s,.\u00A0]+$/.test(f)) { name = f; break; }
3523            }
3524            if (!name) name = (qtyIdx === 0 && fields[1]) ? fields[1] : fields[0];
3525            out.push(name + ' ' + String(qty));
3526            continue;
3527          }
3528        }
3529      }
3530      out.push(raw.replace(/\s+/g, ' '));
3531    }
3532    return out.join('\n');
3533  }
3534
3535  if (taItems && !taItems.dataset.evePasteBound) {
3536    taItems.dataset.evePasteBound = '1';
3537    taItems.addEventListener('paste', function(e){
3538      try {
3539        const clip = e.clipboardData && e.clipboardData.getData ? e.clipboardData.getData('text/plain') : '';
3540        if (clip && clip.includes('\t')) {
3541          const norm = normalizeClipboard(clip);
3542          if (norm && norm !== clip) {
3543            e.preventDefault();
3544            e.stopPropagation();
3545            const start = taItems.selectionStart || 0;
3546            const end = taItems.selectionEnd || 0;
3547            taItems.setRangeText(norm, start, end, 'end');
3548          }
3549        }
3550      } catch(err) {
3551        // If anything weird happens, let the browser do its default paste.
3552      }
3553    });
3554  }
3555
3556  // Auto-run if prefilled by querystring.
3557  (function(){
3558    try{
3559      const ta = form.querySelector('textarea[name="items"]');
3560      if (ta && ta.value && ta.value.trim().length > 0) {
3561        run();
3562      }
3563    }catch(e){}
3564  })();
3565
3566  // Responsive layout tweak: side-by-side on wide screens.
3567  (function(){
3568    const grid = document.getElementById('pcGrid');
3569    if (!grid) return;
3570    function apply(){
3571      const itemsCol = document.getElementById('pcItemsColumn');
3572      const itemsTa = document.getElementById('pcItemsTextarea');
3573      if (window.innerWidth >= 900) {
3574        grid.style.gridTemplateColumns = '2fr 1fr';
3575        grid.style.alignItems = 'stretch';
3576        if (itemsCol) {
3577          itemsCol.style.display = 'flex';
3578          itemsCol.style.flexDirection = 'column';
3579          itemsCol.style.minHeight = '100%';
3580        }
3581        if (itemsTa) {
3582          itemsTa.style.flex = '1 1 auto';
3583          itemsTa.style.minHeight = '0';
3584          itemsTa.style.height = 'auto';
3585        }
3586      } else {
3587        grid.style.gridTemplateColumns = '1fr';
3588        grid.style.alignItems = 'start';
3589        if (itemsCol) {
3590          itemsCol.style.display = 'block';
3591          itemsCol.style.minHeight = '';
3592        }
3593        if (itemsTa) {
3594          itemsTa.style.flex = '';
3595          itemsTa.style.minHeight = '180px';
3596          itemsTa.style.height = '';
3597        }
3598      }
3599    }
3600    apply();
3601    window.addEventListener('resize', apply, {passive:true});
3602  })();
3603
3604  // Render recent checks badges
3605  renderRecent();
3606
3607  // Market-data accuracy clock.
3608  refreshMarketStatus();
3609
3610  setInterval(
3611    marketRenderClock,
3612    1000
3613  );
3614
3615  setInterval(
3616    refreshMarketStatus,
3617    60000
3618  );
3619
3620  if (hubSelect) {
3621    hubSelect.addEventListener(
3622      'change',
3623      refreshMarketStatus
3624    );
3625  }
3626
3627})();
3628</script>
3628
3629
3630  </main>
3631  
3632  <div class="ctx-help-root" data-contextual-help-root data-help-api="/api/contextual_help.php" aria-hidden="true">
3633    <div class="ctx-help-backdrop" data-help-backdrop></div>
3634    <aside class="ctx-help-drawer" data-help-drawer role="dialog" aria-modal="true" aria-label="Contextual Help">
3635      <div class="ctx-help-head">
3636        <div><div class="ctx-help-head__eyebrow">CMS Help</div><h2 data-help-title>Help for this page</h2></div>
3637        <button type="button" class="ctx-help-close" data-help-close aria-label="Close help">×</button>
3638      </div>
3639      <div class="ctx-help-toolbar">
3640        <span class="small muted">Page-specific guidance without leaving your workflow.</span>
3641        <label class="ctx-help-guidance"><input type="checkbox" data-help-guidance-toggle> New Pilot Guidance</label>
3642      </div>
3643      <div class="ctx-help-body" data-help-body><div class="ctx-help-loading"><span class="ctx-help-spinner" aria-hidden="true"></span><span>Loading help…</span></div></div>
3644    </aside>
3645  </div>
3646
3647  <div id="pageLoader" class="page-loader" aria-hidden="true">
3648    <div class="page-loader__panel" role="status" aria-live="polite">
3649      <div class="page-loader__spinner" aria-hidden="true"></div>
3650      <div>
3651        <div class="page-loader__text" id="pageLoaderText">Loading…</div>
3652        <div class="page-loader__sub">Please wait while the page finishes loading.</div>
3653      </div>
3654    </div>
3655  </div>
3656
3657  <footer class="footer">
3658    <div class="container footer__inner">
3659      <div class="footer__title">SolarCrucible/HighStellar Syndicates</div>
3660      <div class="footer__text">Requests are not contracts. Each request may be accepted, rejected, or reprioritized based on capacity and materials.</div>
3661
3662      <style>
3663  .suggestionBox{margin-top:18px}
3664  .suggestionBox details{border:1px solid rgba(255,255,255,.08); border-radius:16px; background:rgba(0,0,0,.35); box-shadow:0 10px 26px rgba(0,0,0,.25)}
3665  .suggestionBox summary{cursor:pointer; list-style:none; display:flex; align-items:center; justify-content:space-between; gap:12px; padding:14px 16px}
3666  .suggestionBox summary::-webkit-details-marker{display:none}
3667  .suggestionBox .sumTitle{display:flex; align-items:center; gap:10px; font-weight:800}
3668  .suggestionBox .sumHint{opacity:.75; font-size:.9rem}
3669  .suggestionBox .inner{padding:0 16px 16px}
3670  .suggestionBox .row{display:flex; gap:10px; flex-wrap:wrap}
3671  .suggestionBox .row > div{flex:1;
3671 min-width:200px}
3672  .suggestionBox .ok{margin-top:10px; color:#a7f3d0}
3673  .suggestionBox .err{margin-top:10px; color:#fca5a5}
3674</style>
3675
3676<div class="suggestionBox">
3677  <details class="card" id="sugg_bd8d3df3c5">
3678    <summary>
3679      <div class="sumTitle">
3680        <span class="badge">Feedback</span>
3681        <span>Suggestion box</span>
3682      </div>
3683      <div class="sumHint">ideas • bugs • questions</div>
3684    </summary>
3685
3686    <div class="inner">
3687              <form class="suggestionForm" data-box="sugg_bd8d3df3c5">
3688          <input type="hidden" name="csrf" value="7f97e5cf384ab7d2a7603e8e4a5e01dfa7aa9dc843d1f17e0c9b09d17db49cef">
3689          <!--
3690            We keep the DB kind enum as feature/problem/question, but expose broader topics to users.
3691            Topic is mapped server-side (and mirrored client-side) to one of the three kinds.
3692          -->
3693          <input type="hidden" name="kind" value="feature">
3694          <input type="hidden" name="page_key" value="Footer">
3695          <input type="hidden" name="page_url" value="/pricecheck.php">
3696          <div class="row">
3697            <div>
3698              <label>Topic</label>
3699              <select name="topic">
3700                <option value="suggestion">Suggestion</option>
3701                <option value="improvement">Improvement</option>
3702                <option value="bug">Bug</option>
3703                <option value="help">Question / help</option>
3704                <option value="new_feature">New feature</option>
3705              </select>
3706            </div>
3707            <div>
3708              <label>Title <span class="muted small">(optional)</span></label>
3709              <input type="text" name="title" placeholder="Short summary (optional)">
3710            </div>
3711          </div>
3712
3713          <div style="margin-top:12px">
3714            <label>Details</label>
3715            <textarea name="message" rows="6" placeholder="What happened / what should it do? Include item names, steps, etc." required></textarea>
3716            <div class="muted small" style="margin-top:6px">This sends feedback about <b>the site</b>.</div>
3717          </div>
3718
3719          <div class="row" style="margin-top:12px">
3720            <div>
3721              <label>Character name <span class="muted small">(optional)</span></label>
3722              <input type="text" name="name" value="" placeholder="Your in-game name">
3723            </div>
3724            <div>
3725              <label>Email <span class="muted small">(optional)</span></label>
3726              <input type="email" name="email" value="" placeholder="So we can reply (optional)">
3727            </div>
3728          </div>
3729
3730          <div style="display:flex; gap:10px; flex-wrap:wrap; align-items:center; margin-top:14px">
3731            <button class="btn primary" type="submit">Send</button>
3732            <span class="muted small">Goes to admins under <b>Feature Suggestions</b>.</span>
3733          </div>
3734
3735          <div class="ok small" style="display:none"></div>
3736          <div class="err small" style="display:none"></div>
3737        </form>
3738          </div>
3739  </details>
3740</div>
3741
3742<script>
3743(function(){
3744  if (window.__dmcSuggestInit) return;
3745  window.__dmcSuggestInit = true;
3746
3747  function mapTopicToKind(topic){
3748    topic = (topic || '').toLowerCase();
3749    if (topic === 'bug') return 'problem';
3750    if (topic === 'help') return 'question';
3751    // suggestion / improvement / new_feature -> feature
3752    return 'feature';
3753  }
3754
3755  async function postForm(form){
3756    const okEl  = form.querySelector('.ok');
3757    const errEl = form.querySelector('.err');
3758    okEl.style.display = 'none'; errEl.style.display = 'none';
3759    okEl.textContent = ''; errEl.textContent = '';
3760
3761    const btn = form.querySelector('button[type="submit"]');
3762    if (btn) { btn.disabled = true; btn.textContent = 'Sending…'; }
3763
3764    try{
3765      // Mirror server-side mapping so "kind" is always present/consistent.
3766      const topicEl = form.querySelector('select[name="topic"]');
3767      const kindEl  = form.querySelector('input[name="kind"]');
3768      if (topicEl && kindEl) kindEl.value = mapTopicToKind(topicEl.value);
3769
3770      const fd = new FormData(form);
3771      const res = await fetch('/api/suggest.php', { method:'POST', body:fd, credentials:'same-origin' });
3772      const data = await res.json().catch(()=>null);
3773
3774      if (!res.ok || !data || data.ok !== true){
3775        const msg = (data && data.error) ? data.error : ('Request failed ('+res.status+').');
3776        errEl.textContent = msg;
3777        errEl.style.display = 'block';
3778      } else {
3779        okEl.textContent = 'Sent. Thanks — the admins will see it.';
3780        okEl.style.display = 'block';
3781        form.reset();
3782      }
3783    }catch(e){
3784      errEl.textContent = 'Network error. Try again.';
3785      errEl.style.display = 'block';
3786    }finally{
3787      if (btn) { btn.disabled = false; btn.textContent = 'Send'; }
3788    }
3789  }
3790
3791  document.addEventListener('submit', function(e){
3792    const form = e.target;
3793    if (!form || !form.classList || !form.classList.contains('suggestionForm')) return;
3794    e.preventDefault();
3795    postForm(form);
3796  }, true);
3797})();
3798</script>
3798
3799
3800      <div class="footer__links small">
3801                  <a href="/admin/login.php">Staff Login</a>
3802              </div>
3803    </div>
3804  </footer>
3805
3806  
3806<script>
3807  // Keep scroll position on refresh/redirect (e.g. after saving a checkbox or form).
3808  // Key is based on path + querystring EXCEPT transient params like "msg".
3809  (function(){
3810    try{
3811      function normalizedKey(){
3812        var u = new URL(window.location.href);
3813        u.searchParams.delete('msg');
3814        // Keep other filters/search intact.
3815        var qs = u.searchParams.toString();
3816        return 'scroll:' + u.pathname + (qs ? ('?' + qs) : '');
3817      }
3818
3819      var key = normalizedKey();
3820      var saved = sessionStorage.getItem(key);
3821      if (saved !== null && saved !== '') {
3822        var y = parseInt(saved, 10);
3823        if (!isNaN(y)) {
3824          // Restore a couple frames later to beat layout shifts.
3825          requestAnimationFrame(function(){
3826            requestAnimationFrame(function(){ window.scrollTo(0, y); });
3827          });
3828        }
3829      }
3830
3831      var lastWrite = 0;
3832      function saveNow(){
3833        // Normalize key again in case a redirect added msg, etc.
3834        try { key = normalizedKey(); } catch(e) {}
3835        sessionStorage.setItem(key, String(window.scrollY || 0));
3836      }
3837
3838      window.addEventListener('scroll', function(){
3839        var now = Date.now();
3840        if (now - lastWrite < 250) return;
3841        lastWrite = now;
3842        saveNow();
3843      }, {passive:true});
3844
3845      window.addEventListener('beforeunload', function(){
3846        try { saveNow(); } catch(e) {}
3847      });
3848    }catch(e){ /* no-op */ }
3849  })();
3850
3851  // Dropdown behavior: only one open at a time, click-away closes, ESC closes.
3852  (function(){
3853    function closeAll(except){
3854      document.querySelectorAll('details.dd').forEach(function(d){
3855        if (except && d === except) return;
3856        d.open = false;
3857      });
3858    }
3859    document.querySelectorAll('details.dd').forEach(function(d){
3860      d.addEventListener('toggle', function(){
3861        if (d.open) closeAll(d);
3862      });
3863    });
3864    document.addEventListener('click', function(e){
3865      if (!e.target.closest || !e.target.closest('details.dd')) closeAll(null);
3866    });
3867    document.addEventListener('keydown', function(e){
3868      if (e.key === 'Escape') closeAll(null);
3869    });
3870  })();
3871  </script>
3871
3872
3873        
3873<script src="/assets/stellar_navigation.js?v=1790823250"></script>
3873
3874  
3875        
3875<script src="/assets/contextual_help.js?v=1787613252"></script>
3875
3876  
3877    
3877<script src="/assets/localtime.js?v=1787613252"></script>
3877
3878
3879
3880<!-- CMS_HOF_LIFETIME_NAV_JS -->
3881<script src="/assets/hof_lifetime_nav.js"></script>
3881
3882</body>
3883</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.