/ brutalist / br-punchlist.jsx
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 });