src/blackrock/navigation.ts

export const researchSections = [
 {key:'market',label:'Exchange',description:'All items · bids, asks & activity'},
 {key:'economy',label:'Economic intelligence',description:'Are prices rising? · evidence & coverage'},
 {key:'opportunities',label:'Opportunities',description:'Buying candidates & risk screens'},
 {key:'charts',label:'Charts & history',description:'Executed prices, volume & quotes'},
 {key:'holders',label:'Bank holdings',description:'Find items across your bots and known players'},
 {key:'production',label:'Production',description:'Craft, combine & resell'},
 {key:'economics',label:'Time & conversion',description:'Acquisition time & smelting margins'},
 {key:'watchlists',label:'Watchlists',description:'Saved items & accumulation targets'},
 {key:'fleet',label:'Players & fleet',description:'Your bots, allies & watched players'},
 {key:'reports',label:'Original report',description:'Saved screens, comparisons & CSV'},
 {key:'tools',label:'API & data',description:'Original data · HTTP, CLI & MCP'},
] as const;
export type ResearchSection=typeof researchSections[number]['key'];
export const isResearchSection=(value:string):value is ResearchSection=>researchSections.some(s=>s.key===value);
export const researchSection=(value:ResearchSection)=>researchSections.find(s=>s.key===value)!;
const worldSections=['map','operations','signals','wealth','catalog','agent','swarms','missions','settings'];
export function initialSection(search:string,hash:string){
 if(new URLSearchParams(search).has('follow')||new URLSearchParams(search).has('cx'))return 'map';
 const key=hash.replace(/^#/,'');
 if(key==='world')return 'map';
 return isResearchSection(key)||worldSections.includes(key)?key:'economy';
}
export function sectionUrl(search:string,next:string){
 const params=new URLSearchParams(search);
 // Camera deep links select World on entry. Explicit navigation must be able to leave it.
 if(next!=='map'){params.delete('follow');params.delete('cx');}
 const query=params.toString();
 return `${query?`?${query}`:''}#${next}`;
}

/** Route an in-app handoff without reloading the live observer or losing its camera. */
export function navigateSection(next:string){
 const url=sectionUrl(window.location.search,next);
 if(`${window.location.search}${window.location.hash}`!==url)window.history.pushState(null,'',url);
 window.dispatchEvent(new PopStateEvent('popstate'));
}

/** Stable primary destinations; every legacy research route remains reachable. */
export const researchGroups = [
 {key:'economy',label:'Intelligence',sections:['economy']},
 {key:'market',label:'Exchange',sections:['market','opportunities','charts']},
 {key:'watchlists',label:'Watchlists',sections:['watchlists']},
 {key:'holders',label:'Bank holdings',sections:['holders']},
 {key:'fleet',label:'Players & fleet',sections:['fleet']},
 {key:'production',label:'Production',sections:['production','economics']},
 {key:'reports',label:'Research & data',sections:['reports','tools']},
] satisfies {key:ResearchSection;label:string;sections:ResearchSection[]}[];
export const researchGroup=(section:ResearchSection)=>researchGroups.find(group=>(group.sections as readonly string[]).includes(section))!;
export function readLanding(storage:Pick<Storage,'getItem'>):ResearchSection {
 try {const key=storage.getItem('rs-blackrock:landing');return key&&isResearchSection(key)?key:'economy';}catch{return 'economy';}
}