br-punchlist.jsx
1 // Brutalist YARD-INSPECTOR PUNCH-LIST — Form 71. 2 // 80-point certification sheet: diagram with numbered hit-points, 3 // pass/fail rows, defect photos, foreman verdict. 4 5 function BRPunchlist({ onNav }) { 6 const ship = makeShip("KRV-IC-2849-AX"); 7 const items = [ 8 [1, "Hull plating · bow quadrant", "PASS", "—"], 9 [2, "Hull plating · port strake", "FLAG", "1.4cm dent, cosmetic"], 10 [3, "Hull plating · starboard strake","PASS", "—"], 11 [4, "Ventral heat tiles", "PASS", "—"], 12 [5, "Canopy seal", "PASS", "replaced 2395.188"], 13 [6, "Canopy glass · 4-layer", "PASS", "—"], 14 [7, "Bow antenna · Q-band", "FLAG", "corrosion · grade-B"], 15 [8, "Drive mount · stud array", "FAIL", "stud 4B torque 412/470"], 16 [9, "Q-drive · primary coil", "PASS", "—"], 17 [10,"Q-drive · secondary coil", "PASS", "—"], 18 [11,"Fuel cell · A-bank", "PASS", "—"], 19 [12,"Fuel cell · B-bank", "PASS", "—"], 20 [13,"Fuel injector · 3", "FAIL", "atomization 94%"], 21 [14,"Fuel line · return", "PASS", "—"], 22 [15,"Coolant loop 1", "PASS", "—"], 23 [16,"Coolant loop 2", "PASS", "—"], 24 [17,"Coolant loop 3", "FLAG", "transient · monitor"], 25 [18,"Life support · O₂ scrubber", "PASS", "replaced 2396.040"], 26 [19,"Life support · CO₂ vent", "PASS", "—"], 27 [20,"Emergency pod · A", "PASS", "sealed · charge 1.0"], 28 [21,"Emergency pod · B", "PASS", "sealed · charge 1.0"], 29 [22,"LIDAR array", "FLAG", "gain drift +8%"], 30 [23,"EM passive array", "PASS", "—"], 31 [24,"Transponder · primary", "PASS", "recoded 2396.114"], 32 [25,"Transponder · backup", "PASS", "—"], 33 [26,"Weapon bay · hardpoint 1", "PASS", "locked · safe"], 34 [27,"Weapon bay · hardpoint 2", "PASS", "locked · safe"], 35 [28,"Flare bay", "PASS", "12/12 charges"], 36 [29,"Decoy launcher", "PASS", "4/4 charges"], 37 [30,"Landing gear · port", "PASS", "—"], 38 [31,"Landing gear · starboard", "PASS", "—"], 39 [32,"Landing gear · nose", "FLAG", "hydraulic weep · grade-A"], 40 ]; 41 42 const counts = { PASS: items.filter(i=>i[2]==="PASS").length, FLAG: items.filter(i=>i[2]==="FLAG").length, FAIL: items.filter(i=>i[2]==="FAIL").length }; 43 44 return ( 45 <BRPage minHeight={2200}> 46 <BRNav active="punch" cartCount={0} onNav={onNav}/> 47 48 {/* HEADER */} 49 <div style={{padding:"30px 40px 22px", borderBottom:`4px double ${BR.ink}`, display:"flex", justifyContent:"space-between", alignItems:"flex-end"}}> 50 <div> 51 <div style={{fontFamily:"IBM Plex Mono", fontSize:11, letterSpacing:3, color:BR.mute, textTransform:"uppercase"}}>FORM 71 · YARD INSPECTION · 80-POINT CERTIFICATION</div> 52 <div style={{fontFamily:"Oswald", fontWeight:900, fontSize:92, lineHeight:0.9, letterSpacing:-2, textTransform:"uppercase", marginTop:6}}>Punch-List</div> 53 <div style={{fontFamily:"IBM Plex Mono", fontSize:12, color:BR.ink2, marginTop:8, letterSpacing:1.2}}> 54 HULL KRV-IC-2849-AX · INSPECTOR S. ORIN · DRY-DOCK C · 2396.116.0600Z 55 </div> 56 </div> 57 <div style={{display:"flex", gap:10}}> 58 <BRStamp rotate={-6} color="#c78f1a">CONDITIONAL</BRStamp> 59 <BRStamp rotate={5} color={BR.rust}>2 FAIL</BRStamp> 60 </div> 61 </div> 62 63 {/* SUMMARY STRIP */} 64 <div style={{display:"grid", gridTemplateColumns:"repeat(5,1fr)", borderBottom:`2px solid ${BR.ink}`, background:BR.paper2}}> 65 {[ 66 ["TOTAL", 80, BR.ink], 67 ["EXAMINED", items.length, BR.ink], 68 ["PASS", counts.PASS, BR.green], 69 ["FLAG", counts.FLAG, "#c78f1a"], 70 ["FAIL", counts.FAIL, BR.rust], 71 ].map(([k,v,c],i)=>( 72 <div key={i} style={{padding:"14px 18px", borderRight: i<4 ? `1px solid ${BR.ink}` : "none"}}> 73 <div style={{fontFamily:"IBM Plex Mono", fontSize:10, letterSpacing:2, color:BR.mute, textTransform:"uppercase"}}>{k}</div> 74 <div style={{fontFamily:"Oswald", fontWeight:900, fontSize:32, letterSpacing:-0.5, color:c, marginTop:2}}>{v}</div> 75 </div> 76 ))} 77 </div> 78 79 <div style={{display:"grid", gridTemplateColumns:"1fr 1fr"}}> 80 {/* LEFT — diagram */} 81 <div style={{borderRight:`1px solid ${BR.ink}`, padding:"24px 30px"}}> 82 <BRH n="01">Plate · Hit-Point Map</BRH> 83 <div style={{border:`2px solid ${BR.ink}`, background:BR.paper2, position:"relative", height:300}}> 84 <div style={{position:"absolute", inset:"8% 6%"}}> 85 <ShipSilhouette ship={ship} stroke={BR.ink} glow={false} strokeWidth={1.2} detail="high"/> 86 </div> 87 {/* hit points */} 88 {[ 89 [22,30,"1"],[38,22,"2","FLAG"],[60,22,"3"],[50,44,"4"],[58,12,"6"], 90 [15,35,"7","FLAG"],[70,50,"8","FAIL"],[78,40,"13","FAIL"],[50,70,"17","FLAG"], 91 [32,72,"22","FLAG"],[18,58,"28"],[88,60,"32","FLAG"], 92 ].map(([x,y,n,flag],i)=>{ 93 const color = flag === "FAIL" ? BR.rust : flag === "FLAG" ? "#c78f1a" : BR.ink; 94 return ( 95 <div key={i} style={{position:"absolute", left:`${x}%`, top:`${y}%`, transform:"translate(-50%,-50%)", width:22, height:22, border:`2px solid ${color}`, background: flag ? color : BR.paper, color: flag ? BR.paper : BR.ink, display:"flex", alignItems:"center", justifyContent:"center", fontFamily:"Oswald", fontWeight:900, fontSize:11, letterSpacing:0.5, borderRadius:"50%"}}>{n}</div> 96 ); 97 })} 98 <div style={{position:"absolute", bottom:10, left:12, fontFamily:"IBM Plex Mono", fontSize:10, color:BR.mute, letterSpacing:2, textTransform:"uppercase"}}>VIEW · PORT ELEVATION</div> 99 </div> 100 101 <div style={{height:22}}/> 102 <BRH n="02">Defect Gallery</BRH> 103 <div style={{display:"grid", gridTemplateColumns:"1fr 1fr 1fr", gap:10}}> 104 {[ 105 ["#2 STRAKE DENT", "FLAG", "1.4cm · cosmetic"], 106 ["#8 STUD 4B", "FAIL", "torque 412/470 Nm"], 107 ["#13 INJECTOR", "FAIL", "atomization 94%"], 108 ].map(([t, s, d], i)=>( 109 <div key={i} style={{border:`2px solid ${BR.ink}`, background:BR.paper}}> 110 <div style={{height:90, background:BR.paper2, borderBottom:`1px solid ${BR.ink}`, position:"relative"}}> 111 <svg viewBox="0 0 120 90" style={{width:"100%", height:"100%"}}> 112 <defs> 113 <pattern id={`h${i}`} width="5" height="5" patternUnits="userSpaceOnUse" patternTransform="rotate(45)"> 114 <line x1="0" y1="0" x2="0" y2="5" stroke={BR.ink} strokeOpacity="0.2" strokeWidth="1"/> 115 </pattern> 116 </defs> 117 <rect width="120" height="90" fill={`url(#h${i})`}/> 118 <circle cx="60" cy="45" r="14" fill="none" stroke={BR.ink} strokeWidth="1.5"/> 119 <line x1="50" y1="35" x2="70" y2="55" stroke={BR.ink} strokeWidth="1"/> 120 <text x="76" y="40" fontFamily="IBM Plex Mono" fontSize="7" fill={BR.mute} letterSpacing="1">DEFECT</text> 121 <text x="6" y="82" fontFamily="IBM Plex Mono" fontSize="7" fill={BR.mute} letterSpacing="1">PLATE {t.split(" ")[0]}</text> 122 </svg> 123 </div> 124 <div style={{padding:"8px 10px"}}> 125 <div style={{display:"flex", justifyContent:"space-between", alignItems:"baseline"}}> 126 <div style={{fontFamily:"Oswald", fontWeight:700, fontSize:11, letterSpacing:1.5, textTransform:"uppercase"}}>{t}</div> 127 <span style={{fontFamily:"Oswald", fontWeight:900, fontSize:10, letterSpacing:2, color: s==="FAIL" ? BR.rust : "#c78f1a"}}>{s}</span> 128 </div> 129 <div style={{fontFamily:"IBM Plex Mono", fontSize:10, color:BR.mute, marginTop:2}}>{d}</div> 130 </div> 131 </div> 132 ))} 133 </div> 134 135 <div style={{height:22}}/> 136 <BRH n="03">Inspector's Verdict</BRH> 137 <div style={{border:`3px double ${BR.ink}`, background:BR.paper2, padding:"16px 18px"}}> 138 <div style={{fontFamily:"IBM Plex Sans", fontSize:14, lineHeight:1.6, color:BR.ink}}> 139 Hull is fundamentally sound. Two grade-A failures (stud 4B, injector 3) are parts-and-labor and within standard turn. Four flagged items are monitor-only and do not impede airworthiness. I certify the hull <b>CONDITIONAL</b> pending completion of the open work order. 140 </div> 141 <div style={{marginTop:14, display:"grid", gridTemplateColumns:"1fr 1fr", gap:24}}> 142 <div> 143 <div style={{fontFamily:"'Caveat','Space Grotesk',cursive", fontSize:28, color:BR.ink, borderBottom:`2px solid ${BR.ink}`, paddingBottom:4}}>S. Orin</div> 144 <div style={{fontFamily:"IBM Plex Mono", fontSize:9, color:BR.mute, letterSpacing:2, marginTop:2, textTransform:"uppercase"}}>Yard inspector · Lic 44-01</div> 145 </div> 146 <div> 147 <div style={{fontFamily:"'Caveat','Space Grotesk',cursive", fontSize:28, color:BR.ink, borderBottom:`2px solid ${BR.ink}`, paddingBottom:4}}>K. Maars</div> 148 <div style={{fontFamily:"IBM Plex Mono", fontSize:9, color:BR.mute, letterSpacing:2, marginTop:2, textTransform:"uppercase"}}>Yard foreman · counter-signed</div> 149 </div> 150 </div> 151 </div> 152 </div> 153 154 {/* RIGHT — long table */} 155 <div style={{padding:"24px 30px"}}> 156 <BRH n="04">Line Items · 32 of 80</BRH> 157 <table style={{width:"100%", borderCollapse:"collapse", fontFamily:"IBM Plex Mono", fontSize:11}}> 158 <thead> 159 <tr style={{background:BR.paper2, borderBottom:`2px solid ${BR.ink}`}}> 160 {["#","Item","Result","Note"].map(h=>( 161 <th key={h} style={{padding:"6px 8px", textAlign:"left", fontSize:9, letterSpacing:2, color:BR.mute, textTransform:"uppercase", fontWeight:500}}>{h}</th> 162 ))} 163 </tr> 164 </thead> 165 <tbody> 166 {items.map((r,i)=>{ 167 const color = r[2] === "FAIL" ? BR.rust : r[2] === "FLAG" ? "#c78f1a" : BR.green; 168 return ( 169 <tr key={i} style={{borderBottom:`1px dotted ${BR.ink}44`, background: i%2 ? BR.paper : BR.paper2}}> 170 <td style={{padding:"5px 8px", fontWeight:700}}>{String(r[0]).padStart(2,"0")}</td> 171 <td style={{padding:"5px 8px"}}>{r[1]}</td> 172 <td style={{padding:"5px 8px"}}><span style={{fontFamily:"Oswald", fontWeight:900, fontSize:10, letterSpacing:2, color}}>{r[2]}</span></td> 173 <td style={{padding:"5px 8px", color:BR.mute}}>{r[3]}</td> 174 </tr> 175 ); 176 })} 177 <tr style={{background:BR.paper2}}> 178 <td colSpan="4" style={{padding:"10px 8px", fontFamily:"IBM Plex Mono", fontSize:10, color:BR.mute, letterSpacing:2, textTransform:"uppercase", textAlign:"center"}}>— items 33–80 on continuation sheet 71-B —</td> 179 </tr> 180 </tbody> 181 </table> 182 183 <div style={{height:22}}/> 184 <BRH n="05">Re-Inspection Trigger</BRH> 185 <div style={{fontFamily:"IBM Plex Sans", fontSize:13, color:BR.ink2, lineHeight:1.5, marginBottom:10}}> 186 Full re-inspection will be triggered automatically upon completion of the following: 187 </div> 188 <div style={{display:"grid", gap:6}}> 189 {[ 190 ["#8 · Stud 4B re-torqued & cross-checked", true], 191 ["#13 · Injector 3 replaced & bench-verified", true], 192 ["#17 · Coolant loop 3 · 48h trend stable", false], 193 ["#32 · Nose gear hydraulic · re-sealed", false], 194 ].map(([t, done], i)=>( 195 <div key={i} style={{padding:"8px 12px", border:`2px solid ${BR.ink}`, background:done ? BR.paper2 : BR.paper, display:"flex", gap:10}}> 196 <div style={{width:14, height:14, border:`2px solid ${BR.ink}`, background: done ? BR.ink : "transparent", color:BR.paper, display:"flex", alignItems:"center", justifyContent:"center", fontFamily:"Oswald", fontWeight:900, fontSize:9, marginTop:1}}> 197 {done && "✓"} 198 </div> 199 <span style={{fontFamily:"IBM Plex Mono", fontSize:11, color:BR.ink2}}>{t}</span> 200 </div> 201 ))} 202 </div> 203 </div> 204 </div> 205 206 <BRFooter/> 207 </BRPage> 208 ); 209 } 210 211 Object.assign(window, { BRPunchlist });