44 < meta charset ="UTF-8 ">
55 < meta name ="viewport " content ="width=device-width, initial-scale=1.0 ">
66 < title > KB Plate Validator & Generator</ title >
7- < link rel ="stylesheet " href ="static/style.css?v=6 ">
7+ < link rel ="stylesheet " href ="static/style.css?v=7 ">
88</ head >
99< body >
10- < div class ="container ">
10+ < div class ="container " style ="position: relative; ">
11+ < button id ="theme-toggle " class ="theme-toggle " aria-label ="Toggle Theme ">
12+ < svg id ="theme-icon " width ="20 " height ="20 " viewBox ="0 0 24 24 " fill ="none " stroke ="currentColor " stroke-width ="2 " stroke-linecap ="round " stroke-linejoin ="round ">
13+ <!-- Default to moon icon since it's dark mode default -->
14+ < path d ="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z "> </ path >
15+ </ svg >
16+ </ button >
1117 < header >
1218 < h1 > KB Plate Validator</ h1 >
1319 < p > Generate SendCutSend-ready keyboard plates from KLE and KiCad files.</ p >
1420 </ header >
1521
1622 < main >
1723 < div class ="tabs ">
18- < button class ="tab-btn " data-tab ="kle " id ="tab-kle " class =" active " > KLE Mode (No PCB) </ button >
24+ < button class ="tab-btn active " data-tab ="kle " id ="tab-kle "> KLE Mode</ button >
1925 < button class ="tab-btn " data-tab ="pcb " id ="tab-pcb "> PCB Mode</ button >
2026 < button class ="tab-btn " data-tab ="convert " id ="tab-convert "> DXF Converter</ button >
2127 </ div >
@@ -24,17 +30,17 @@ <h1>KB Plate Validator</h1>
2430 < section id ="pcb-section " class ="tab-content active ">
2531 < div class ="form-group ">
2632 < label > KLE JSON Layout < span class ="required "> *</ span > </ label >
27- < div class ="input-toggle " style =" margin-bottom: 0.5rem; " >
28- < label style =" display: inline-block; font-weight: normal; margin-right: 1rem; " >
33+ < div class ="input-toggle ">
34+ < label >
2935 < input type ="radio " name ="kle_input_mode " value ="text " checked > Paste Raw JSON
3036 </ label >
31- < label style =" display: inline-block; font-weight: normal; " >
37+ < label >
3238 < input type ="radio " name ="kle_input_mode " value ="file "> Upload File
3339 </ label >
3440 </ div >
3541
3642 < div id ="kle-text-input ">
37- < textarea id ="kle_text " name ="kle_text " rows ="6 " style =" width: 100%; padding: 0.5rem; border: 1px solid var(--border-color); border-radius: 6px; font-family: monospace; " placeholder ='[ ["Esc","Q","W","E","R","T","Y","U","I","O","P","{","}","|"] ] '> </ textarea >
43+ < textarea id ="kle_text " name ="kle_text " rows ="6 " placeholder ='[ ["Esc","Q","W","E","R","T","Y","U","I","O","P","{","}","|"] ] '> </ textarea >
3844 </ div >
3945
4046 < div id ="kle-file-input " class ="hidden ">
@@ -65,9 +71,9 @@ <h1>KB Plate Validator</h1>
6571 < label for ="pcb_dy "> PCB Y Offset (mm)</ label >
6672 < input type ="number " id ="pcb_dy " name ="pcb_dy " value ="0.0 " step ="0.1 ">
6773 </ div >
68- < div class ="form-group " style ="display: flex; align-items : center; padding-top: 1.5rem ; ">
69- < input type ="checkbox " id ="no_auto_align " name ="no_auto_align " style =" width: auto; margin-right: 0.5rem; " >
70- < label for ="no_auto_align " style =" margin-bottom: 0; cursor: pointer; " > Disable Auto-Align</ label >
74+ < div class ="form-group checkbox-group " style ="align-self : center; ">
75+ < input type ="checkbox " id ="no_auto_align " name ="no_auto_align ">
76+ < label for ="no_auto_align "> Disable Auto-Align</ label >
7177 </ div >
7278 </ div >
7379 </ div >
@@ -81,7 +87,7 @@ <h1>KB Plate Validator</h1>
8187 < input type ="file " id ="dxf_file " name ="dxf_file " accept =".dxf ">
8288 </ div >
8389 < p class ="file-name " id ="dxf-name "> </ p >
84- < div class ="notice " style =" margin-top: 1rem; " >
90+ < div class ="notice ">
8591 < strong > Note:</ strong > Works with any DXF. If standard layers exist
8692 (< code > PLATE_OUTLINE</ code > , < code > SWITCH_CUTOUTS</ code > ,
8793 < code > STAB_CUTOUTS</ code > , < code > PCB_SCREW_HOLES</ code > ) they are used.
@@ -90,24 +96,24 @@ <h1>KB Plate Validator</h1>
9096 </ div >
9197 </ div >
9298 < div class ="actions ">
93- < button type ="button " class ="primary-btn " id ="convert-btn " style =" background-color: #059669; "> Convert DXF</ button >
99+ < button type ="button " class ="primary-btn btn-secondary " id ="convert-btn "> Convert DXF</ button >
94100 </ div >
95101 </ section >
96102
97103 < section class ="options-section ">
98104 < h3 > Generation Formats</ h3 >
99- < div class ="options-grid " style =" grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); " >
100- < div class ="form -group" style =" display: flex; align-items: center; ">
101- < input type ="checkbox " id ="gen_dxf " name ="gen_dxf " checked style =" width: auto; margin-right: 0.5rem; " >
102- < label for ="gen_dxf " style =" margin-bottom: 0; cursor: pointer; " > DXF (Laser)</ label >
105+ < div class ="options-grid ">
106+ < div class ="checkbox -group ">
107+ < input type ="checkbox " id ="gen_dxf " name ="gen_dxf " checked >
108+ < label for ="gen_dxf "> DXF (Laser)</ label >
103109 </ div >
104- < div class ="form -group" style =" display: flex; align-items: center; ">
105- < input type ="checkbox " id ="gen_gerber " name ="gen_gerber " checked style =" width: auto; margin-right: 0.5rem; " >
106- < label for ="gen_gerber " style =" margin-bottom: 0; cursor: pointer; " > Gerber (JLCPCB)</ label >
110+ < div class ="checkbox -group ">
111+ < input type ="checkbox " id ="gen_gerber " name ="gen_gerber " checked >
112+ < label for ="gen_gerber "> Gerber (JLCPCB)</ label >
107113 </ div >
108- < div class ="form -group" style =" display: flex; align-items: center; ">
109- < input type ="checkbox " id ="gen_stl " name ="gen_stl " checked style =" width: auto; margin-right: 0.5rem; " >
110- < label for ="gen_stl " style =" margin-bottom: 0; cursor: pointer; " > STL (3D Print)</ label >
114+ < div class ="checkbox -group ">
115+ < input type ="checkbox " id ="gen_stl " name ="gen_stl " checked >
116+ < label for ="gen_stl "> STL (3D Print)</ label >
111117 </ div >
112118 </ div >
113119 </ section >
@@ -156,7 +162,7 @@ <h3>Plate Options</h3>
156162 </ div >
157163
158164 < div id ="kle-options ">
159- < h3 > KLE Mounting Options</ h3 >
165+ < h3 style =" margin-top: 1.5rem; " > KLE Mounting Options</ h3 >
160166 < div class ="options-grid ">
161167 < div class ="form-group ">
162168 < label for ="screw_preset "> Screw Preset</ label >
@@ -168,19 +174,22 @@ <h3>KLE Mounting Options</h3>
168174 < option value ="grid3x2 "> Grid 3x2</ option >
169175 < option value ="grid4x2 "> Grid 4x2</ option >
170176 < option value ="between_rows "> Between Rows</ option >
177+ < option value ="snap "> Intelligent Snap (Auto Brace)</ option >
178+ < option value ="gh60 "> GH60 standard</ option >
179+ < option value ="skyway96 "> Skyway96 standard</ option >
171180 </ select >
172181 </ div >
173182 < div class ="form-group ">
174183 < label for ="screw_inset "> Screw Inset (mm)</ label >
175184 < input type ="number " id ="screw_inset " name ="screw_inset " value ="5.0 " step ="0.5 ">
176185 </ div >
177- < div class ="form-group " style ="display: flex; align-items : center; padding-top: 1.5rem ; ">
178- < input type ="checkbox " id ="split " name ="split " style =" width: auto; margin-right: 0.5rem; " >
179- < label for ="split " style =" margin-bottom: 0; cursor: pointer; " > Split Plates (Ergo/Alice)</ label >
186+ < div class ="form-group checkbox-group " style ="align-self : center; ">
187+ < input type ="checkbox " id ="split " name ="split ">
188+ < label for ="split "> Split Plates (Ergo/Alice)</ label >
180189 </ div >
181- < div class ="form-group " style ="display: flex; align-items : center; padding-top: 1.5rem ; ">
182- < input type ="checkbox " id ="puzzle_split " name ="puzzle_split " style =" width: auto; margin-right: 0.5rem; " >
183- < label for ="puzzle_split " style =" margin-bottom: 0; cursor: pointer; " > Hole-Aware Puzzle Split (for 3D Printing) </ label >
190+ < div class ="form-group checkbox-group " style ="align-self : center; ">
191+ < input type ="checkbox " id ="puzzle_split " name ="puzzle_split ">
192+ < label for ="puzzle_split "> Hole-Aware Puzzle Split</ label >
184193 </ div >
185194 </ div >
186195 </ div >
@@ -199,20 +208,20 @@ <h3>KLE Mounting Options</h3>
199208 < div id ="results ">
200209 < h3 id ="results-title "> Output Files</ h3 >
201210 < div class ="stats-grid ">
202- < div class ="stat "> < span class ="label "> Keys: </ span > < span id ="stat-keys "> -</ span > </ div >
203- < div class ="stat "> < span class ="label "> Dimensions: </ span > < span id ="stat-dims "> -</ span > </ div >
204- < div class ="stat "> < span class ="label "> Screws: </ span > < span id ="stat-screws "> -</ span > </ div >
211+ < div class ="stat "> < span class ="label "> Keys</ span > < span id ="stat-keys "> -</ span > </ div >
212+ < div class ="stat "> < span class ="label "> Dimensions</ span > < span id ="stat-dims "> -</ span > </ div >
213+ < div class ="stat "> < span class ="label "> Screws</ span > < span id ="stat-screws "> -</ span > </ div >
205214 </ div >
206215
207- < div id ="preview-container " style =" margin: 2rem 0; text-align: center; background: #f8fafc; border: 1px solid #e2e8f0; border-radius: 8px; padding: 1rem; overflow: auto; max-height: 400px; min-height: 80px; " >
208- < p style ="padding: 2rem; color: var(--text-muted); "> Preview appears after generation.</ p >
216+ < div id ="preview-container ">
217+ < p style ="color: var(--text-muted); font-weight: 500 ; "> Preview appears after generation.</ p >
209218 </ div >
210219
211220 < div id ="validation-notice " class ="notice hidden "> </ div >
212- < div class ="download-buttons " style =" display: flex; gap: 1rem; justify-content: center; flex-wrap: wrap; " >
213- < a href ="# " id ="download-link " class ="primary-btn btn-disabled "> Download DXF</ a >
214- < a href ="# " id ="download-gerber " class ="primary-btn btn-disabled " style =" background-color: #059669; "> Download Gerber (JLCPCB) </ a >
215- < a href ="# " id ="download-stl " class ="primary-btn btn-disabled " style =" background-color: #7c3aed; "> Download 3D ( STL) </ a >
221+ < div class ="download-buttons ">
222+ < a href ="# " id ="download-link " class ="primary-btn btn-secondary btn- disabled "> Download DXF</ a >
223+ < a href ="# " id ="download-gerber " class ="primary-btn btn-secondary btn-disabled "> Download Gerber</ a >
224+ < a href ="# " id ="download-stl " class ="primary-btn btn-secondary btn-disabled "> Download STL</ a >
216225 </ div >
217226 </ div >
218227
@@ -224,6 +233,6 @@ <h3 id="results-title">Output Files</h3>
224233 </ footer >
225234 </ div >
226235
227- < script src ="static/script.js?v=6 "> </ script >
236+ < script src ="static/script.js?v=7 "> </ script >
228237</ body >
229238</ html >
0 commit comments