br-contacts.jsx
1 // Brutalist BROKER'S CONTACT-BOOK — Form 29. 2 // A rolodex / index-card pilot register with a cross-referenced directory, 3 // relationship notes, deal history, and a favorites column. 4 5 function BRContacts({ onNav }) { 6 const contacts = [ 7 { init:"OV", name:"CMDR O. Veyr", org:"7th Expeditionary · LOG", tier:"T-3", loc:"Ceres · G-4", tag:"BUYER", dot:BR.green, note:"Prefers escrow. Flagship escort mission in flight 2396.115." }, 8 { init:"TR", name:"CMDR T. Rhein", org:"Salvage Trust", tier:"T-3", loc:"Kepler · M-2", tag:"RIVAL", dot:"#c78f1a", note:"Underbid twice in Q1. Watches interceptor class closely." }, 9 { init:"HC", name:"H. Colea", org:"Syndic · Free Traders", tier:"T-2", loc:"Drift · K-9", tag:"SYNDIC", dot:BR.ink, note:"Proxy bidder, buys for undisclosed principals." }, 10 { init:"NR", name:"N.G.R. Liquidators",org:"Coalition Salvage", tier:"T-4", loc:"Ceres · G-4", tag:"CONSIGNOR",dot:BR.rust, note:"Consigns ex-service hulls. Reserves tend to be high." }, 11 { init:"KM", name:"K. Maars", org:"Krovas Ceres Yards", tier:"—", loc:"Ceres · G-4", tag:"YARD", dot:BR.ink, note:"Foreman. Will take a call at any hour. Owes me a drink." }, 12 { init:"JH", name:"J. Hollister", org:"Coalition Notary", tier:"—", loc:"Ceres · G-4", tag:"NOTARY", dot:BR.green, note:"Seal 4481. Prefers forms filed before 09Z." }, 13 { init:"ST", name:"LT S. Toren", org:"7th Expeditionary", tier:"T-2", loc:"Ceres · G-4", tag:"PILOT", dot:BR.ink, note:"Veyr's wingman. Good instinct on hull cosmetic issues." }, 14 { init:"KA", name:"LT K. Amara", org:"7th Expeditionary", tier:"T-2", loc:"Ceres · G-4", tag:"PILOT", dot:BR.ink, note:"Logistics lead. Requests hauler listings monthly." }, 15 { init:"FK", name:"F. Kavros", org:"Sale-Room Ceres", tier:"—", loc:"Ceres · G-4", tag:"AUCT.", dot:BR.ink, note:"Auctioneer. Do not chase his ladder — wait for the third call." }, 16 { init:"RO", name:"CIV R. Olen", org:"—", tier:"Civ", loc:"Drift · K-9", tag:"COURIER", dot:"#c78f1a", note:"Civilian operator. Takes yacht transit work, reliable." }, 17 ]; 18 const tagColor = (t) => ({ 19 BUYER:BR.green, RIVAL:"#c78f1a", SYNDIC:BR.ink, CONSIGNOR:BR.rust, YARD:BR.ink, 20 NOTARY:BR.green, PILOT:BR.ink, "AUCT.":BR.ink, COURIER:"#c78f1a" 21 }[t] || BR.ink); 22 23 return ( 24 <BRPage minHeight={2000}> 25 <BRNav active="contacts" cartCount={0} onNav={onNav}/> 26 27 {/* HEADER */} 28 <div style={{padding:"30px 40px 22px", borderBottom:`4px double ${BR.ink}`, display:"flex", justifyContent:"space-between", alignItems:"flex-end"}}> 29 <div> 30 <div style={{fontFamily:"IBM Plex Mono", fontSize:11, letterSpacing:3, color:BR.mute, textTransform:"uppercase"}}>FORM 29 · CONTACT REGISTER · BROKER S. ORIN</div> 31 <div style={{fontFamily:"Oswald", fontWeight:900, fontSize:92, lineHeight:0.9, letterSpacing:-2, textTransform:"uppercase", marginTop:6}}>Rolodex</div> 32 <div style={{fontFamily:"IBM Plex Mono", fontSize:12, color:BR.ink2, marginTop:8, letterSpacing:1.2}}> 33 148 ENTRIES · LAST UPDATED 2396.116.0412Z · ENCRYPTED LOCAL 34 </div> 35 </div> 36 <div style={{display:"flex", gap:10}}> 37 <BRStamp rotate={-6}>CONFIDENTIAL</BRStamp> 38 </div> 39 </div> 40 41 <div style={{display:"grid", gridTemplateColumns:"260px 1fr 300px"}}> 42 {/* LEFT — A–Z index */} 43 <div style={{borderRight:`1px solid ${BR.ink}`, padding:"22px 20px", background:BR.paper2}}> 44 <BRH n="01">Index</BRH> 45 <div style={{display:"grid", gridTemplateColumns:"repeat(6,1fr)", gap:4}}> 46 {"ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("").map(l => ( 47 <div key={l} style={{padding:"6px 0", textAlign:"center", fontFamily:"Oswald", fontWeight:700, fontSize:12, letterSpacing:1, border:`1.5px solid ${BR.ink}`, background: "KMNOV".includes(l) ? BR.ink : BR.paper, color: "KMNOV".includes(l) ? BR.paper : BR.ink, cursor:"pointer"}}>{l}</div> 48 ))} 49 </div> 50 51 <div style={{height:20}}/> 52 <BRH n="02">Filters</BRH> 53 {[ 54 ["BUYERS", 32, BR.green], 55 ["RIVALS", 7, "#c78f1a"], 56 ["SYNDICS", 14, BR.ink], 57 ["CONSIGNORS", 22, BR.rust], 58 ["YARD · NOTARY", 9, BR.ink], 59 ["PILOTS", 48, BR.ink], 60 ["COURIERS", 16, "#c78f1a"], 61 ].map(([t,n,c], i) => ( 62 <div key={i} style={{display:"flex", justifyContent:"space-between", alignItems:"center", padding:"8px 10px", border:`1.5px solid ${BR.ink}`, marginBottom:4, background:BR.paper, cursor:"pointer"}}> 63 <span style={{display:"flex", alignItems:"center", gap:8}}> 64 <span style={{width:8, height:8, background:c, borderRadius:"50%"}}/> 65 <span style={{fontFamily:"Oswald", fontWeight:700, fontSize:11, letterSpacing:2, textTransform:"uppercase"}}>{t}</span> 66 </span> 67 <span style={{fontFamily:"IBM Plex Mono", fontSize:10, color:BR.mute}}>{n}</span> 68 </div> 69 ))} 70 71 <div style={{height:20}}/> 72 <BRH n="03">Starred</BRH> 73 {[ 74 ["CMDR O. VEYR", "BUYER"], 75 ["K. MAARS", "YARD"], 76 ["J. HOLLISTER", "NOTARY"], 77 ].map(([n, t], i) => ( 78 <div key={i} style={{padding:"6px 0", borderBottom:`1px dotted ${BR.ink}33`, display:"flex", justifyContent:"space-between", alignItems:"baseline"}}> 79 <span style={{fontFamily:"Oswald", fontWeight:700, fontSize:11, letterSpacing:1.5, textTransform:"uppercase"}}>★ {n}</span> 80 <span style={{fontFamily:"IBM Plex Mono", fontSize:9, color:BR.mute, letterSpacing:1}}>{t}</span> 81 </div> 82 ))} 83 </div> 84 85 {/* CENTER — card grid */} 86 <div style={{padding:"22px 26px"}}> 87 {/* Search bar */} 88 <div style={{display:"flex", gap:8, border:`2px solid ${BR.ink}`, background:BR.paper, marginBottom:18}}> 89 <div style={{padding:"10px 14px", borderRight:`2px solid ${BR.ink}`, fontFamily:"IBM Plex Mono", fontSize:11, color:BR.mute, letterSpacing:1.5}}>QUERY ▸</div> 90 <input defaultValue="tier-3 buyers · sector G-4" style={{flex:1, border:"none", background:"transparent", fontFamily:"IBM Plex Mono", fontSize:13, outline:"none"}}/> 91 <div style={{background:BR.ink, color:BR.paper, padding:"10px 18px", fontFamily:"Oswald", fontSize:12, letterSpacing:3}}>SEARCH</div> 92 </div> 93 94 <BRH n="04">Register · 10 of 148</BRH> 95 <div style={{display:"grid", gridTemplateColumns:"1fr 1fr", gap:12}}> 96 {contacts.map((c, i) => ( 97 <div key={i} style={{border:`2px solid ${BR.ink}`, background:BR.paper, padding:"12px 14px", position:"relative"}}> 98 <div style={{display:"flex", gap:12}}> 99 <div style={{width:42, height:42, border:`2px solid ${BR.ink}`, background:BR.paper2, display:"flex", alignItems:"center", justifyContent:"center", fontFamily:"Oswald", fontWeight:900, fontSize:14, letterSpacing:1, position:"relative", flexShrink:0}}> 100 {c.init} 101 <div style={{position:"absolute", bottom:-3, right:-3, width:8, height:8, background:c.dot, borderRadius:"50%", border:`1px solid ${BR.paper}`}}/> 102 </div> 103 <div style={{flex:1, minWidth:0}}> 104 <div style={{display:"flex", justifyContent:"space-between", alignItems:"baseline"}}> 105 <div style={{fontFamily:"Oswald", fontWeight:700, fontSize:14, letterSpacing:1, textTransform:"uppercase"}}>{c.name}</div> 106 <span style={{fontFamily:"Oswald", fontWeight:900, fontSize:9, letterSpacing:2, padding:"2px 6px", border:`1.5px solid ${tagColor(c.tag)}`, color:tagColor(c.tag)}}>{c.tag}</span> 107 </div> 108 <div style={{fontFamily:"IBM Plex Mono", fontSize:10, color:BR.mute, letterSpacing:1, marginTop:2}}>{c.org}</div> 109 <div style={{display:"flex", gap:10, marginTop:4, fontFamily:"IBM Plex Mono", fontSize:10, color:BR.ink2, letterSpacing:1}}> 110 <span>{c.tier}</span><span>·</span><span>{c.loc}</span> 111 </div> 112 </div> 113 </div> 114 <div style={{marginTop:10, paddingTop:8, borderTop:`1px dotted ${BR.ink}33`, fontFamily:"IBM Plex Sans", fontSize:11.5, color:BR.ink2, lineHeight:1.45, fontStyle:"italic"}}> 115 "{c.note}" 116 </div> 117 <div style={{marginTop:8, display:"flex", gap:4}}> 118 {["CALL","MSG","LEDGER"].map(l => ( 119 <button key={l} style={{padding:"4px 8px", border:`1.5px solid ${BR.ink}`, background:"transparent", fontFamily:"Oswald", fontWeight:700, fontSize:9, letterSpacing:2, cursor:"pointer"}}>{l}</button> 120 ))} 121 </div> 122 </div> 123 ))} 124 </div> 125 126 {/* pager */} 127 <div style={{marginTop:18, borderTop:`2px solid ${BR.ink}`, paddingTop:10, display:"flex", justifyContent:"space-between", fontFamily:"IBM Plex Mono", fontSize:11, letterSpacing:2, color:BR.ink, textTransform:"uppercase"}}> 128 <span>◂ PREV</span> 129 <span>PAGE 01 / 15</span> 130 <span>NEXT ▸</span> 131 </div> 132 </div> 133 134 {/* RIGHT — active relationship + recent */} 135 <div style={{borderLeft:`1px solid ${BR.ink}`, padding:"22px 22px", background:BR.paper2}}> 136 <BRH n="05">Active Relationship</BRH> 137 <div style={{border:`2px solid ${BR.ink}`, padding:"14px 16px", background:BR.paper}}> 138 <div style={{fontFamily:"Oswald", fontWeight:700, fontSize:16, letterSpacing:1, textTransform:"uppercase"}}>CMDR O. Veyr</div> 139 <div style={{fontFamily:"IBM Plex Mono", fontSize:10, color:BR.mute, letterSpacing:1, marginTop:2}}>7TH EXPEDITIONARY · LOG</div> 140 141 <div style={{marginTop:12}}> 142 <BRSpec k="Lifetime ₵" v="₵44.80M"/> 143 <BRSpec k="Deals" v="3 closed · 1 in-flight"/> 144 <BRSpec k="Last" v="2396.114 · KRV-IC-2849"/> 145 <BRSpec k="Next touch" v="2396.120"/> 146 <BRSpec k="Preference" v="Escrow · tactical loadout"/> 147 </div> 148 149 <div style={{marginTop:12}}> 150 <div style={{fontFamily:"Oswald", fontWeight:700, fontSize:11, letterSpacing:2, color:BR.mute, marginBottom:4, textTransform:"uppercase"}}>DEAL HISTORY</div> 151 {[ 152 ["2396.114", "KRV-IC-2849-AX", "₵22.01M", "closed"], 153 ["2395.088", "VNT-CH-1044-BM", "₵18.40M", "closed"], 154 ["2394.212", "OBS-HL-4420-CP", "₵11.80M", "closed"], 155 ].map((r,i)=>( 156 <div key={i} style={{display:"grid", gridTemplateColumns:"60px 1fr auto", gap:8, padding:"4px 0", borderBottom:`1px dotted ${BR.ink}33`, fontFamily:"IBM Plex Mono", fontSize:10}}> 157 <span style={{color:BR.mute}}>{r[0]}</span> 158 <span>{r[1]}</span> 159 <span style={{fontWeight:700}}>{r[2]}</span> 160 </div> 161 ))} 162 </div> 163 </div> 164 165 <div style={{height:20}}/> 166 <BRH n="06">Recent Activity</BRH> 167 <div style={{fontFamily:"IBM Plex Mono", fontSize:11, color:BR.ink2, letterSpacing:0.5, lineHeight:1.8}}> 168 <div><span style={{color:BR.mute}}>0412Z</span> Note added · K. Maars</div> 169 <div><span style={{color:BR.mute}}>0318Z</span> Deal filed · O. Veyr</div> 170 <div><span style={{color:BR.mute}}>2396.115</span> Intro · H. Colea ↔ N.G.R.</div> 171 <div><span style={{color:BR.mute}}>2396.114</span> Call logged · T. Rhein</div> 172 <div><span style={{color:BR.mute}}>2396.112</span> Contact created · F. Kavros</div> 173 </div> 174 175 <div style={{marginTop:18}}> 176 <button onClick={()=>onNav("broker")} style={{width:"100%", padding:"14px 0", background:BR.ink, color:BR.paper, border:"none", fontFamily:"Oswald", fontWeight:900, fontSize:12, letterSpacing:3, cursor:"pointer"}}>▸ OPEN DISPATCH THREAD</button> 177 <button style={{width:"100%", marginTop:8, padding:"12px 0", background:"transparent", color:BR.ink, border:`2px solid ${BR.ink}`, fontFamily:"Oswald", fontWeight:700, fontSize:11, letterSpacing:3, cursor:"pointer"}}>NEW CONTACT CARD</button> 178 </div> 179 </div> 180 </div> 181 182 <BRFooter/> 183 </BRPage> 184 ); 185 } 186 187 Object.assign(window, { BRContacts });