create-izi-noir 0.2.2 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +353 -128
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -6,7 +6,7 @@ import { Command } from "commander";
6
6
  // src/commands/init.ts
7
7
  import path2 from "path";
8
8
  import { execSync } from "child_process";
9
- import pc4 from "picocolors";
9
+ import pc3 from "picocolors";
10
10
 
11
11
  // src/prompts/project.ts
12
12
  import prompts from "prompts";
@@ -17,8 +17,7 @@ var TEMPLATES = [
17
17
  { title: "Balance Proof only", value: "balance-proof" }
18
18
  ];
19
19
  var NETWORKS = [
20
- { title: "Solana (recommended)", value: "solana", description: "Uses Groth16 for on-chain verification" },
21
- { title: "EVM (Ethereum, Base, etc.)", value: "evm", description: "Uses UltraHonk proofs" }
20
+ { title: "Solana", value: "solana", description: "Uses Groth16 for on-chain verification" }
22
21
  ];
23
22
  function networkToProvider(network) {
24
23
  return network === "solana" ? "arkworks" : "barretenberg";
@@ -117,44 +116,8 @@ async function isDirectoryEmpty(dir) {
117
116
  }
118
117
  }
119
118
 
120
- // src/utils/spinner.ts
121
- import pc2 from "picocolors";
122
- var frames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
123
- var Spinner = class {
124
- message;
125
- interval = null;
126
- frameIndex = 0;
127
- constructor(message) {
128
- this.message = message;
129
- }
130
- start() {
131
- process.stdout.write("\x1B[?25l");
132
- this.interval = setInterval(() => {
133
- const frame = pc2.cyan(frames[this.frameIndex]);
134
- process.stdout.write(`\r${frame} ${this.message}`);
135
- this.frameIndex = (this.frameIndex + 1) % frames.length;
136
- }, 80);
137
- }
138
- stop(success = true) {
139
- if (this.interval) {
140
- clearInterval(this.interval);
141
- this.interval = null;
142
- }
143
- process.stdout.write("\x1B[?25h");
144
- const icon = success ? pc2.green("\u2713") : pc2.red("\u2717");
145
- process.stdout.write(`\r${icon} ${this.message}
146
- `);
147
- }
148
- update(message) {
149
- this.message = message;
150
- }
151
- };
152
- function createSpinner(message) {
153
- return new Spinner(message);
154
- }
155
-
156
119
  // src/utils/progress.ts
157
- import pc3 from "picocolors";
120
+ import pc2 from "picocolors";
158
121
  var THINKING_PHRASES = [
159
122
  "Initializing ZK environment",
160
123
  "Configuring proof system",
@@ -191,15 +154,15 @@ var ProgressReporter = class {
191
154
  this.showThinking();
192
155
  }
193
156
  showThinking() {
194
- const frames2 = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
157
+ const frames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
195
158
  let frameIndex = 0;
196
159
  let dotCount = 0;
197
160
  this.thinkingInterval = setInterval(() => {
198
- const frame = pc3.cyan(frames2[frameIndex]);
161
+ const frame = pc2.cyan(frames[frameIndex]);
199
162
  const phrase = THINKING_PHRASES[this.thinkingIndex % THINKING_PHRASES.length];
200
163
  const dots = ".".repeat(dotCount % 4);
201
- process.stdout.write(`\r${frame} ${pc3.dim(phrase)}${dots} `);
202
- frameIndex = (frameIndex + 1) % frames2.length;
164
+ process.stdout.write(`\r${frame} ${pc2.dim(phrase)}${dots} `);
165
+ frameIndex = (frameIndex + 1) % frames.length;
203
166
  dotCount++;
204
167
  if (dotCount % 12 === 0) {
205
168
  this.thinkingIndex++;
@@ -215,29 +178,29 @@ var ProgressReporter = class {
215
178
  }
216
179
  async reportFile(filename, isLast = false) {
217
180
  const icon = getFileIcon(filename);
218
- const line = ` ${icon} ${pc3.dim("created")} ${pc3.white(filename)}`;
219
- process.stdout.write(" " + icon + " " + pc3.dim("created") + " ");
181
+ const line = ` ${icon} ${pc2.dim("created")} ${pc2.white(filename)}`;
182
+ process.stdout.write(" " + icon + " " + pc2.dim("created") + " ");
220
183
  for (const char of filename) {
221
- process.stdout.write(pc3.white(char));
184
+ process.stdout.write(pc2.white(char));
222
185
  await sleep(8 + Math.random() * 12);
223
186
  }
224
187
  process.stdout.write("\n");
225
188
  this.currentLine = line;
226
189
  }
227
190
  async reportDirectory(dirname) {
228
- process.stdout.write(` \u{1F4C1} ${pc3.dim("mkdir")} ${pc3.blue(dirname)}/
191
+ process.stdout.write(` \u{1F4C1} ${pc2.dim("mkdir")} ${pc2.blue(dirname)}/
229
192
  `);
230
193
  await sleep(30);
231
194
  }
232
195
  showSuccess(message) {
233
196
  process.stdout.write("\x1B[?25h");
234
197
  console.log();
235
- console.log(pc3.green("\u2713") + " " + message);
198
+ console.log(pc2.green("\u2713") + " " + message);
236
199
  }
237
200
  showError(message) {
238
201
  process.stdout.write("\x1B[?25h");
239
202
  console.log();
240
- console.log(pc3.red("\u2717") + " " + message);
203
+ console.log(pc2.red("\u2717") + " " + message);
241
204
  }
242
205
  };
243
206
  function createProgressReporter() {
@@ -260,18 +223,18 @@ var InstallProgress = class {
260
223
  start() {
261
224
  process.stdout.write("\x1B[?25l");
262
225
  const barWidth = 30;
263
- const frames2 = ["\u25D0", "\u25D3", "\u25D1", "\u25D2"];
226
+ const frames = ["\u25D0", "\u25D3", "\u25D1", "\u25D2"];
264
227
  let frameIndex = 0;
265
228
  this.interval = setInterval(() => {
266
- const frame = pc3.cyan(frames2[frameIndex]);
229
+ const frame = pc2.cyan(frames[frameIndex]);
267
230
  const filled = Math.floor(this.progress / 100 * barWidth);
268
231
  const empty = barWidth - filled;
269
- const bar = pc3.green("\u2588".repeat(filled)) + pc3.dim("\u2591".repeat(empty));
232
+ const bar = pc2.green("\u2588".repeat(filled)) + pc2.dim("\u2591".repeat(empty));
270
233
  const pkg = this.packages[this.currentPackage % this.packages.length];
271
234
  process.stdout.write(
272
- `\r${frame} Installing dependencies ${bar} ${pc3.dim(pkg)} `
235
+ `\r${frame} Installing dependencies ${bar} ${pc2.dim(pkg)} `
273
236
  );
274
- frameIndex = (frameIndex + 1) % frames2.length;
237
+ frameIndex = (frameIndex + 1) % frames.length;
275
238
  if (this.progress < 95) {
276
239
  this.progress += Math.random() * 3;
277
240
  if (this.progress > (this.currentPackage + 1) * 12) {
@@ -287,7 +250,7 @@ var InstallProgress = class {
287
250
  }
288
251
  process.stdout.write("\x1B[?25h");
289
252
  process.stdout.write("\r\x1B[K");
290
- const icon = success ? pc3.green("\u2713") : pc3.red("\u2717");
253
+ const icon = success ? pc2.green("\u2713") : pc2.red("\u2717");
291
254
  const message = success ? "Dependencies installed" : "Failed to install dependencies";
292
255
  console.log(`${icon} ${message}`);
293
256
  }
@@ -295,12 +258,54 @@ var InstallProgress = class {
295
258
  function createInstallProgress() {
296
259
  return new InstallProgress();
297
260
  }
261
+ var GitProgress = class {
262
+ interval = null;
263
+ phases = [
264
+ "Initializing repository",
265
+ "Setting up version control",
266
+ "Creating .git directory",
267
+ "Configuring git objects",
268
+ "Preparing initial branch"
269
+ ];
270
+ phaseIndex = 0;
271
+ dotCount = 0;
272
+ start() {
273
+ process.stdout.write("\x1B[?25l");
274
+ const frames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
275
+ let frameIndex = 0;
276
+ this.interval = setInterval(() => {
277
+ const frame = pc2.cyan(frames[frameIndex]);
278
+ const phase = this.phases[this.phaseIndex % this.phases.length];
279
+ const dots = ".".repeat(this.dotCount % 4);
280
+ process.stdout.write(`\r${frame} ${pc2.dim(phase)}${dots} `);
281
+ frameIndex = (frameIndex + 1) % frames.length;
282
+ this.dotCount++;
283
+ if (this.dotCount % 8 === 0) {
284
+ this.phaseIndex++;
285
+ }
286
+ }, 80);
287
+ }
288
+ stop(success = true) {
289
+ if (this.interval) {
290
+ clearInterval(this.interval);
291
+ this.interval = null;
292
+ }
293
+ process.stdout.write("\x1B[?25h");
294
+ process.stdout.write("\r\x1B[K");
295
+ const icon = success ? pc2.green("\u2713") : pc2.red("\u2717");
296
+ const message = success ? "Git repository initialized" : "Failed to initialize git";
297
+ console.log(`${icon} ${message}`);
298
+ }
299
+ };
300
+ function createGitProgress() {
301
+ return new GitProgress();
302
+ }
298
303
 
299
304
  // src/generators/package-json.ts
300
305
  function generatePackageJson(options) {
301
306
  const isSolana = options.provider === "arkworks";
302
307
  const dependencies = {
303
- "@izi-noir/sdk": "^0.1.4",
308
+ "@izi-noir/sdk": "^0.1.5",
304
309
  "@noir-lang/acvm_js": "1.0.0-beta.13-1d260df.nightly",
305
310
  "@noir-lang/noirc_abi": "1.0.0-beta.13-1d260df.nightly",
306
311
  "react": "^18.3.1",
@@ -599,9 +604,17 @@ export default defineConfig({
599
604
  },
600
605
  define: {
601
606
  "global": "globalThis",
607
+ "process.env": {},
602
608
  },
603
609
  optimizeDeps: {
604
- exclude: ["@noir-lang/noir_wasm", "@aztec/bb.js", "@izi-noir/sdk"],
610
+ exclude: [
611
+ "@noir-lang/noir_wasm",
612
+ "@noir-lang/noir_js",
613
+ "@noir-lang/acvm_js",
614
+ "@noir-lang/noirc_abi",
615
+ "@aztec/bb.js",
616
+ "@izi-noir/sdk",
617
+ ],
605
618
  include: ["buffer", "util"],
606
619
  },
607
620
  build: {
@@ -636,6 +649,9 @@ function generateIndexHtml(options) {
636
649
  <link rel="icon" type="image/svg+xml" href="/vite.svg" />
637
650
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
638
651
  <title>${options.projectName} - ZK Proof Demo</title>
652
+ <link rel="preconnect" href="https://fonts.googleapis.com">
653
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
654
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
639
655
  </head>
640
656
  <body>
641
657
  <div id="root"></div>
@@ -768,10 +784,17 @@ import { Chain, Network } from '@izi-noir/sdk';` : "";
768
784
  </div>
769
785
 
770
786
  <div className="verify-box">
787
+ {publicInputs && (
788
+ <div className="public-inputs-display">
789
+ <span>Public inputs:</span>
790
+ <code>{JSON.stringify(publicInputs)}</code>
791
+ </div>
792
+ )}
771
793
  <button
772
794
  onClick={handleVerify}
773
795
  disabled={!vkAccount || isVerifying}
774
796
  className="btn btn-primary"
797
+ style={{ marginTop: publicInputs ? '0.5rem' : 0 }}
775
798
  >
776
799
  {isVerifying ? 'Verifying...' : verified ? 'Verified!' : 'Verify On-Chain'}
777
800
  </button>
@@ -839,6 +862,7 @@ function App() {
839
862
  const [proofTime, setProofTime] = useState<number | null>(null);
840
863
  const [proofError, setProofError] = useState<string | null>(null);
841
864
  const [localVerified, setLocalVerified] = useState<boolean | null>(null);
865
+ const [publicInputs, setPublicInputs] = useState<string[] | null>(null);
842
866
 
843
867
  // IziNoir instance
844
868
  const [iziInstance, setIziInstance] = useState<IziNoir | null>(null);
@@ -855,6 +879,7 @@ ${solanaState}
855
879
  setProof(null);
856
880
  setProofTime(null);
857
881
  setLocalVerified(null);
882
+ setPublicInputs(null);
858
883
  setNoirCode(null);
859
884
  }
860
885
  }, [selectedCircuit]);
@@ -927,6 +952,7 @@ ${solanaState}
927
952
  const endTime = performance.now();
928
953
  setProof(proofBytes);
929
954
  setProofTime(Math.round(endTime - startTime));
955
+ setPublicInputs(publicInputsHex);
930
956
  } catch (error) {
931
957
  console.error('Proof generation error:', error);
932
958
  setProofError((error as Error).message);
@@ -940,7 +966,7 @@ ${solanaHandlers}
940
966
  <div className="app">
941
967
  <header>
942
968
  <h1>${options.projectName}</h1>
943
- <p>Zero-Knowledge Proof Demo</p>
969
+ <p>Built with IZI-NOIR</p>
944
970
  </header>
945
971
 
946
972
  <main>
@@ -1103,29 +1129,65 @@ function capitalizeFirst(str) {
1103
1129
  return str.charAt(0).toUpperCase() + str.slice(1);
1104
1130
  }
1105
1131
  function generateAppCss() {
1106
- return `* {
1132
+ return `/* ================================
1133
+ CSS Variables - IZI-NOIR Theme
1134
+ ================================ */
1135
+ :root {
1136
+ --solana-purple: #9945FF;
1137
+ --solana-green: #14F195;
1138
+ --noir-primary: #050505;
1139
+ --noir-elevated: #0A0A0A;
1140
+ --noir-orange: #FF6B35;
1141
+ --izi-cyan: #00D4FF;
1142
+ --text: #ffffff;
1143
+ --text-muted: #888888;
1144
+ --border: rgba(255, 255, 255, 0.1);
1145
+ }
1146
+
1147
+ /* ================================
1148
+ Reset & Base Styles
1149
+ ================================ */
1150
+ * {
1107
1151
  box-sizing: border-box;
1108
1152
  margin: 0;
1109
1153
  padding: 0;
1110
1154
  }
1111
1155
 
1112
- :root {
1113
- --purple: #9945FF;
1114
- --green: #14F195;
1115
- --bg: #0a0a0a;
1116
- --bg-elevated: #111111;
1117
- --border: #222222;
1118
- --text: #ffffff;
1119
- --text-muted: #888888;
1156
+ html {
1157
+ scroll-behavior: smooth;
1120
1158
  }
1121
1159
 
1122
1160
  body {
1123
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
1124
- background: var(--bg);
1161
+ font-family: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
1162
+ background-color: var(--noir-primary);
1163
+ /* Noise texture + radial gradients like the main frontend */
1164
+ background-image:
1165
+ url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)' opacity='0.015'/%3E%3C/svg%3E"),
1166
+ radial-gradient(
1167
+ ellipse 60% 40% at 50% 30%,
1168
+ rgba(153, 69, 255, 0.06) 0%,
1169
+ transparent 50%
1170
+ ),
1171
+ radial-gradient(
1172
+ ellipse 80% 50% at 50% 110%,
1173
+ rgba(20, 241, 149, 0.04) 0%,
1174
+ transparent 40%
1175
+ );
1176
+ background-attachment: fixed;
1125
1177
  color: var(--text);
1126
1178
  line-height: 1.6;
1179
+ -webkit-font-smoothing: antialiased;
1180
+ -moz-osx-font-smoothing: grayscale;
1181
+ }
1182
+
1183
+ ::selection {
1184
+ background: rgba(153, 69, 255, 0.3);
1185
+ color: white;
1127
1186
  }
1128
1187
 
1188
+ /* ================================
1189
+ Layout
1190
+ ================================ */
1129
1191
  .app {
1130
1192
  min-height: 100vh;
1131
1193
  display: flex;
@@ -1136,11 +1198,14 @@ header {
1136
1198
  padding: 2rem;
1137
1199
  text-align: center;
1138
1200
  border-bottom: 1px solid var(--border);
1201
+ backdrop-filter: blur(8px);
1202
+ background: rgba(0, 0, 0, 0.3);
1139
1203
  }
1140
1204
 
1141
1205
  header h1 {
1142
1206
  font-size: 2rem;
1143
- background: linear-gradient(90deg, var(--purple), var(--green));
1207
+ font-weight: 700;
1208
+ background: linear-gradient(135deg, var(--solana-purple) 0%, var(--noir-orange) 100%);
1144
1209
  -webkit-background-clip: text;
1145
1210
  -webkit-text-fill-color: transparent;
1146
1211
  background-clip: text;
@@ -1159,34 +1224,51 @@ main {
1159
1224
  width: 100%;
1160
1225
  }
1161
1226
 
1227
+ /* ================================
1228
+ Section Cards - Glassmorphism
1229
+ ================================ */
1162
1230
  .section {
1163
1231
  margin-bottom: 2rem;
1164
1232
  padding: 1.5rem;
1165
- background: var(--bg-elevated);
1233
+ background: rgba(0, 0, 0, 0.3);
1234
+ backdrop-filter: blur(8px);
1166
1235
  border: 1px solid var(--border);
1167
- border-radius: 12px;
1236
+ border-radius: 16px;
1237
+ transition: border-color 0.3s ease, box-shadow 0.3s ease;
1238
+ }
1239
+
1240
+ .section:hover {
1241
+ border-color: rgba(255, 255, 255, 0.15);
1242
+ box-shadow: 0 0 30px rgba(153, 69, 255, 0.1);
1168
1243
  }
1169
1244
 
1170
1245
  .section h2 {
1171
1246
  font-size: 1.25rem;
1247
+ font-weight: 600;
1172
1248
  margin-bottom: 1rem;
1173
1249
  color: var(--text);
1174
1250
  }
1175
1251
 
1252
+ /* ================================
1253
+ Form Controls
1254
+ ================================ */
1176
1255
  .select {
1177
1256
  width: 100%;
1178
- padding: 0.75rem;
1179
- background: var(--bg);
1257
+ padding: 0.75rem 1rem;
1258
+ background: rgba(0, 0, 0, 0.4);
1180
1259
  border: 1px solid var(--border);
1181
- border-radius: 8px;
1260
+ border-radius: 12px;
1182
1261
  color: var(--text);
1262
+ font-family: inherit;
1183
1263
  font-size: 1rem;
1184
1264
  cursor: pointer;
1265
+ transition: border-color 0.3s ease, box-shadow 0.3s ease;
1185
1266
  }
1186
1267
 
1187
1268
  .select:focus {
1188
1269
  outline: none;
1189
- border-color: var(--purple);
1270
+ border-color: var(--solana-purple);
1271
+ box-shadow: 0 0 20px rgba(153, 69, 255, 0.2);
1190
1272
  }
1191
1273
 
1192
1274
  .inputs-grid {
@@ -1211,71 +1293,93 @@ main {
1211
1293
 
1212
1294
  .input-badge {
1213
1295
  font-size: 0.625rem;
1214
- padding: 0.125rem 0.375rem;
1215
- border-radius: 4px;
1296
+ padding: 0.125rem 0.5rem;
1297
+ border-radius: 6px;
1216
1298
  text-transform: uppercase;
1217
1299
  font-weight: 600;
1300
+ letter-spacing: 0.05em;
1218
1301
  }
1219
1302
 
1220
1303
  .input-badge.public {
1221
- background: var(--green);
1222
- color: #000;
1304
+ background: rgba(20, 241, 149, 0.2);
1305
+ color: var(--solana-green);
1306
+ border: 1px solid rgba(20, 241, 149, 0.3);
1223
1307
  }
1224
1308
 
1225
1309
  .input-badge.private {
1226
- background: var(--purple);
1227
- color: #fff;
1310
+ background: rgba(153, 69, 255, 0.2);
1311
+ color: var(--solana-purple);
1312
+ border: 1px solid rgba(153, 69, 255, 0.3);
1228
1313
  }
1229
1314
 
1230
1315
  .input-group input {
1231
- padding: 0.75rem;
1232
- background: var(--bg);
1316
+ padding: 0.75rem 1rem;
1317
+ background: rgba(0, 0, 0, 0.4);
1233
1318
  border: 1px solid var(--border);
1234
- border-radius: 8px;
1319
+ border-radius: 12px;
1235
1320
  color: var(--text);
1321
+ font-family: 'JetBrains Mono', 'Fira Code', monospace;
1236
1322
  font-size: 1rem;
1323
+ transition: border-color 0.3s ease, box-shadow 0.3s ease;
1237
1324
  }
1238
1325
 
1239
1326
  .input-group input:focus {
1240
1327
  outline: none;
1241
- border-color: var(--purple);
1328
+ border-color: var(--solana-purple);
1329
+ box-shadow: 0 0 20px rgba(153, 69, 255, 0.2);
1242
1330
  }
1243
1331
 
1332
+ /* ================================
1333
+ Buttons - Animated Gradient
1334
+ ================================ */
1244
1335
  .btn {
1245
1336
  padding: 0.75rem 1.5rem;
1246
1337
  font-size: 1rem;
1247
1338
  font-weight: 600;
1248
1339
  border: none;
1249
- border-radius: 8px;
1340
+ border-radius: 12px;
1250
1341
  cursor: pointer;
1251
- transition: all 0.2s;
1342
+ transition: all 0.3s ease;
1252
1343
  }
1253
1344
 
1254
1345
  .btn:disabled {
1255
- opacity: 0.5;
1346
+ opacity: 0.4;
1256
1347
  cursor: not-allowed;
1257
1348
  }
1258
1349
 
1259
1350
  .btn-primary {
1260
- background: linear-gradient(90deg, var(--purple), var(--green));
1351
+ background: linear-gradient(
1352
+ 90deg,
1353
+ var(--solana-purple) 0%,
1354
+ var(--solana-purple) 50%,
1355
+ var(--solana-green) 100%
1356
+ );
1357
+ background-size: 200% 100%;
1358
+ background-position: 0% 0%;
1261
1359
  color: white;
1360
+ box-shadow: 0 0 20px rgba(153, 69, 255, 0.3);
1262
1361
  }
1263
1362
 
1264
1363
  .btn-primary:hover:not(:disabled) {
1364
+ background-position: 100% 0%;
1265
1365
  transform: translateY(-2px);
1266
- box-shadow: 0 4px 20px rgba(153, 69, 255, 0.3);
1366
+ box-shadow: 0 0 30px rgba(20, 241, 149, 0.3);
1267
1367
  }
1268
1368
 
1269
1369
  .btn-secondary {
1270
- background: var(--bg);
1370
+ background: rgba(0, 0, 0, 0.4);
1271
1371
  border: 1px solid var(--border);
1272
1372
  color: var(--text);
1273
1373
  }
1274
1374
 
1275
1375
  .btn-secondary:hover:not(:disabled) {
1276
- border-color: var(--purple);
1376
+ border-color: var(--solana-purple);
1377
+ box-shadow: 0 0 20px rgba(153, 69, 255, 0.15);
1277
1378
  }
1278
1379
 
1380
+ /* ================================
1381
+ Results Grid
1382
+ ================================ */
1279
1383
  .results {
1280
1384
  display: grid;
1281
1385
  grid-template-columns: repeat(3, 1fr);
@@ -1283,22 +1387,36 @@ main {
1283
1387
  margin-top: 1rem;
1284
1388
  }
1285
1389
 
1390
+ @media (max-width: 640px) {
1391
+ .results {
1392
+ grid-template-columns: 1fr;
1393
+ }
1394
+ }
1395
+
1286
1396
  .result-card {
1287
- padding: 1rem;
1288
- background: var(--bg);
1397
+ padding: 1.25rem;
1398
+ background: rgba(0, 0, 0, 0.3);
1289
1399
  border: 1px solid var(--border);
1290
- border-radius: 8px;
1400
+ border-radius: 12px;
1291
1401
  text-align: center;
1402
+ transition: border-color 0.3s ease, transform 0.3s ease, box-shadow 0.3s ease;
1403
+ }
1404
+
1405
+ .result-card:hover {
1406
+ border-color: rgba(255, 255, 255, 0.15);
1407
+ transform: translateY(-4px);
1408
+ box-shadow: 0 0 25px rgba(153, 69, 255, 0.15);
1292
1409
  }
1293
1410
 
1294
1411
  .result-value {
1295
- font-size: 1.25rem;
1296
- font-weight: 600;
1412
+ font-size: 1.5rem;
1413
+ font-weight: 700;
1414
+ font-family: 'JetBrains Mono', monospace;
1297
1415
  display: block;
1298
1416
  }
1299
1417
 
1300
1418
  .result-value.success {
1301
- color: var(--green);
1419
+ color: var(--solana-green);
1302
1420
  }
1303
1421
 
1304
1422
  .result-value.error {
@@ -1309,22 +1427,40 @@ main {
1309
1427
  font-size: 0.75rem;
1310
1428
  color: var(--text-muted);
1311
1429
  text-transform: uppercase;
1312
- margin-top: 0.25rem;
1430
+ letter-spacing: 0.1em;
1431
+ margin-top: 0.5rem;
1313
1432
  display: block;
1314
1433
  }
1315
1434
 
1435
+ /* ================================
1436
+ Messages
1437
+ ================================ */
1316
1438
  .error {
1317
- color: #ff4444;
1439
+ color: #ff6b6b;
1318
1440
  font-size: 0.875rem;
1319
1441
  margin-top: 0.5rem;
1442
+ padding: 0.75rem 1rem;
1443
+ background: rgba(255, 107, 107, 0.1);
1444
+ border: 1px solid rgba(255, 107, 107, 0.2);
1445
+ border-radius: 8px;
1446
+ word-break: break-word;
1447
+ overflow-wrap: break-word;
1448
+ max-width: 100%;
1320
1449
  }
1321
1450
 
1322
1451
  .success {
1323
- color: var(--green);
1452
+ color: var(--solana-green);
1324
1453
  font-size: 0.875rem;
1325
1454
  margin-top: 0.5rem;
1455
+ padding: 0.75rem 1rem;
1456
+ background: rgba(20, 241, 149, 0.1);
1457
+ border: 1px solid rgba(20, 241, 149, 0.2);
1458
+ border-radius: 8px;
1326
1459
  }
1327
1460
 
1461
+ /* ================================
1462
+ Noir Code Details
1463
+ ================================ */
1328
1464
  .noir-details {
1329
1465
  margin-top: 1rem;
1330
1466
  }
@@ -1333,12 +1469,21 @@ main {
1333
1469
  cursor: pointer;
1334
1470
  color: var(--text-muted);
1335
1471
  font-size: 0.875rem;
1472
+ padding: 0.5rem 0;
1473
+ transition: color 0.3s ease;
1336
1474
  }
1337
1475
 
1338
1476
  .noir-details summary:hover {
1339
- color: var(--text);
1477
+ color: var(--solana-purple);
1340
1478
  }
1341
1479
 
1480
+ .noir-details[open] summary {
1481
+ color: var(--solana-purple);
1482
+ }
1483
+
1484
+ /* ================================
1485
+ Deploy & Verify Section
1486
+ ================================ */
1342
1487
  .deploy-verify-row {
1343
1488
  display: grid;
1344
1489
  grid-template-columns: 1fr 1fr;
@@ -1346,38 +1491,118 @@ main {
1346
1491
  margin-top: 1rem;
1347
1492
  }
1348
1493
 
1494
+ @media (max-width: 640px) {
1495
+ .deploy-verify-row {
1496
+ grid-template-columns: 1fr;
1497
+ }
1498
+ }
1499
+
1349
1500
  .deploy-box,
1350
1501
  .verify-box {
1351
- padding: 1rem;
1352
- background: var(--bg);
1502
+ padding: 1.25rem;
1503
+ background: rgba(0, 0, 0, 0.3);
1504
+ border: 1px solid var(--border);
1505
+ border-radius: 12px;
1506
+ overflow: hidden;
1507
+ word-break: break-word;
1508
+ transition: border-color 0.3s ease, box-shadow 0.3s ease;
1509
+ }
1510
+
1511
+ .deploy-box:hover,
1512
+ .verify-box:hover {
1513
+ border-color: rgba(255, 255, 255, 0.15);
1514
+ box-shadow: 0 0 20px rgba(153, 69, 255, 0.1);
1515
+ }
1516
+
1517
+ .public-inputs-display {
1518
+ margin-top: 0.75rem;
1519
+ font-size: 0.75rem;
1520
+ color: var(--text-muted);
1521
+ }
1522
+
1523
+ .public-inputs-display code {
1524
+ display: block;
1525
+ margin-top: 0.5rem;
1526
+ padding: 0.75rem;
1527
+ background: rgba(0, 0, 0, 0.4);
1353
1528
  border: 1px solid var(--border);
1354
1529
  border-radius: 8px;
1530
+ font-family: 'JetBrains Mono', monospace;
1531
+ font-size: 0.7rem;
1532
+ overflow-x: auto;
1533
+ max-width: 100%;
1355
1534
  }
1356
1535
 
1536
+ /* ================================
1537
+ Footer
1538
+ ================================ */
1357
1539
  footer {
1358
1540
  padding: 1.5rem;
1359
1541
  text-align: center;
1360
1542
  border-top: 1px solid var(--border);
1543
+ backdrop-filter: blur(8px);
1544
+ background: rgba(0, 0, 0, 0.3);
1361
1545
  color: var(--text-muted);
1362
1546
  font-size: 0.875rem;
1363
1547
  }
1364
1548
 
1365
1549
  footer a {
1366
- color: var(--purple);
1550
+ color: var(--solana-purple);
1367
1551
  text-decoration: none;
1552
+ transition: color 0.3s ease;
1368
1553
  }
1369
1554
 
1370
1555
  footer a:hover {
1371
- text-decoration: underline;
1556
+ color: var(--solana-green);
1557
+ }
1558
+
1559
+ /* ================================
1560
+ Custom Scrollbar
1561
+ ================================ */
1562
+ ::-webkit-scrollbar {
1563
+ width: 6px;
1564
+ height: 6px;
1565
+ }
1566
+
1567
+ ::-webkit-scrollbar-track {
1568
+ background: var(--noir-primary);
1569
+ }
1570
+
1571
+ ::-webkit-scrollbar-thumb {
1572
+ background: rgba(255, 255, 255, 0.1);
1573
+ border-radius: 9999px;
1574
+ }
1575
+
1576
+ ::-webkit-scrollbar-thumb:hover {
1577
+ background: rgba(255, 255, 255, 0.2);
1578
+ }
1579
+
1580
+ /* ================================
1581
+ Accessibility - Reduced Motion
1582
+ ================================ */
1583
+ @media (prefers-reduced-motion: reduce) {
1584
+ *,
1585
+ *::before,
1586
+ *::after {
1587
+ animation-duration: 0.01ms !important;
1588
+ animation-iteration-count: 1 !important;
1589
+ transition-duration: 0.01ms !important;
1590
+ }
1372
1591
  }
1373
1592
  `;
1374
1593
  }
1375
1594
  function generateIndexCss() {
1376
- return `body {
1595
+ return `/* Base styles - fonts are loaded in index.html */
1596
+ body {
1377
1597
  margin: 0;
1378
1598
  -webkit-font-smoothing: antialiased;
1379
1599
  -moz-osx-font-smoothing: grayscale;
1380
1600
  }
1601
+
1602
+ /* Ensure mono font is applied to code elements */
1603
+ code, pre, .mono {
1604
+ font-family: 'JetBrains Mono', 'Fira Code', 'Cascadia Code', monospace;
1605
+ }
1381
1606
  `;
1382
1607
  }
1383
1608
  function generateViteEnvDts() {
@@ -1556,14 +1781,14 @@ async function initCommand(projectName, options) {
1556
1781
  });
1557
1782
  }
1558
1783
  if (!projectOptions) {
1559
- console.log(pc4.yellow("\nOperation cancelled."));
1784
+ console.log(pc3.yellow("\nOperation cancelled."));
1560
1785
  process.exit(0);
1561
1786
  }
1562
1787
  const projectDir = path2.resolve(process.cwd(), projectOptions.projectName);
1563
1788
  if (await directoryExists(projectDir)) {
1564
1789
  if (!await isDirectoryEmpty(projectDir)) {
1565
1790
  console.log(
1566
- pc4.red(`
1791
+ pc3.red(`
1567
1792
  Error: Directory "${projectOptions.projectName}" already exists and is not empty.`)
1568
1793
  );
1569
1794
  process.exit(1);
@@ -1575,23 +1800,23 @@ Error: Directory "${projectOptions.projectName}" already exists and is not empty
1575
1800
  await progress.startThinking();
1576
1801
  await new Promise((r) => setTimeout(r, 800));
1577
1802
  progress.stopThinking();
1578
- console.log(pc4.bold("\n Scaffolding your ZK project...\n"));
1803
+ console.log(pc3.bold("\n Scaffolding your ZK project...\n"));
1579
1804
  await createProjectStructure(projectDir, projectOptions, progress);
1580
1805
  progress.showSuccess("Project structure created");
1581
1806
  } catch (error) {
1582
1807
  progress.showError("Failed to create project structure");
1583
- console.error(pc4.red("\n"), error);
1808
+ console.error(pc3.red("\n"), error);
1584
1809
  process.exit(1);
1585
1810
  }
1586
1811
  if (!projectOptions.skipGit) {
1587
- const gitSpinner = createSpinner("Initializing git repository...");
1588
- gitSpinner.start();
1812
+ const gitProgress = createGitProgress();
1813
+ gitProgress.start();
1589
1814
  try {
1590
1815
  execSync("git init", { cwd: projectDir, stdio: "ignore" });
1591
- gitSpinner.stop(true);
1816
+ gitProgress.stop(true);
1592
1817
  } catch {
1593
- gitSpinner.stop(false);
1594
- console.log(pc4.yellow(" Warning: Failed to initialize git repository"));
1818
+ gitProgress.stop(false);
1819
+ console.log(pc3.yellow(" Warning: Failed to initialize git repository"));
1595
1820
  }
1596
1821
  }
1597
1822
  if (!projectOptions.skipInstall) {
@@ -1602,7 +1827,7 @@ Error: Directory "${projectOptions.projectName}" already exists and is not empty
1602
1827
  installProgress.stop(true);
1603
1828
  } catch {
1604
1829
  installProgress.stop(false);
1605
- console.log(pc4.yellow(' Run "npm install" manually.'));
1830
+ console.log(pc3.yellow(' Run "npm install" manually.'));
1606
1831
  }
1607
1832
  }
1608
1833
  printSuccessMessage(projectOptions);
@@ -1656,26 +1881,26 @@ async function createProjectStructure(projectDir, options, progress) {
1656
1881
  }
1657
1882
  function printSuccessMessage(options) {
1658
1883
  console.log();
1659
- console.log(pc4.green("\u2713") + " Project created successfully!");
1884
+ console.log(pc3.green("\u2713") + " Project created successfully!");
1660
1885
  console.log();
1661
1886
  console.log("Next steps:");
1662
1887
  console.log();
1663
- console.log(pc4.cyan(` cd ${options.projectName}`));
1888
+ console.log(pc3.cyan(` cd ${options.projectName}`));
1664
1889
  if (options.skipInstall) {
1665
- console.log(pc4.cyan(" npm install"));
1890
+ console.log(pc3.cyan(" npm install"));
1666
1891
  }
1667
- console.log(pc4.cyan(" npm run dev"));
1892
+ console.log(pc3.cyan(" npm run dev"));
1668
1893
  console.log();
1669
- console.log("Then open " + pc4.blue("http://localhost:5173") + " in your browser.");
1894
+ console.log("Then open " + pc3.blue("http://localhost:5173") + " in your browser.");
1670
1895
  console.log();
1671
1896
  console.log("To add circuits:");
1672
1897
  console.log();
1673
- console.log(pc4.dim(" 1. Create a new circuit in circuits/*.ts"));
1674
- console.log(pc4.dim(" 2. Export it from circuits/index.ts"));
1675
- console.log(pc4.dim(" 3. Add it to CIRCUITS array in src/App.tsx"));
1898
+ console.log(pc3.dim(" 1. Create a new circuit in circuits/*.ts"));
1899
+ console.log(pc3.dim(" 2. Export it from circuits/index.ts"));
1900
+ console.log(pc3.dim(" 3. Add it to CIRCUITS array in src/App.tsx"));
1676
1901
  console.log();
1677
1902
  console.log(
1678
- pc4.dim("Learn more: ") + pc4.blue("https://github.com/izi-noir/izi-noir")
1903
+ pc3.dim("Learn more: ") + pc3.blue("https://github.com/izi-noir/izi-noir")
1679
1904
  );
1680
1905
  console.log();
1681
1906
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-izi-noir",
3
- "version": "0.2.2",
3
+ "version": "0.2.5",
4
4
  "description": "CLI to scaffold IZI-NOIR ZK projects",
5
5
  "type": "module",
6
6
  "bin": {