File size: 35,411 Bytes
63b381a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Archify Start — Describe It, Then See It</title>
  <meta name="description" content="Create a verifiable technical diagram directly from a plain-language description, pasted Mermaid, or a repository. No repository is required.">
  <meta name="theme-color" content="#eff2f1">
  <meta property="og:type" content="website">
  <meta property="og:title" content="Archify Start — Describe it, then see it">
  <meta property="og:description" content="Start with a plain-language description, pasted Mermaid, or real code. No repository is required.">
  <meta property="og:url" content="https://tt-a1i.github.io/archify/start.html">
  <meta property="og:image" content="https://tt-a1i.github.io/archify/assets/archify-social-preview.png">
  <link rel="icon" type="image/svg+xml" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 28 28'><polygon points='14,2 26,8 26,20 14,26 2,20 2,8' fill='%23083344' stroke='%2322d3ee' stroke-width='1.5'/><circle cx='14' cy='15' r='2.5' fill='%2322d3ee'/></svg>">
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  <link href="https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght@0,9..144,300;0,9..144,400;0,9..144,500;1,9..144,400&family=Inter:wght@400;450;500;600&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
  <link rel="stylesheet" href="assets/site-navigation.css">
  <style>
    :root {
      /* Drafted-sheet palette — shared with the project page */
      --paper:#eff2f1; --paper-raised:#f8faf9;
      --ink:#15181b; --ink-soft:#363c41; --muted:#60686d; --dim:#929a9e;
      --line:rgba(20,23,26,0.14); --line-hi:rgba(20,23,26,0.3);
      --accent:#e14a0e; --accent-soft:rgba(225,74,14,0.08);
      --plate:#0f1216;
      --emerald:#047857;
      --font-display:'Fraunces','Songti SC','STSong',Georgia,serif;
      --font-body:'Inter',-apple-system,BlinkMacSystemFont,'PingFang SC','Hiragino Sans GB','Microsoft YaHei',sans-serif;
      --font-mono:'JetBrains Mono',ui-monospace,SFMono-Regular,Menlo,monospace;
      --ease-out:cubic-bezier(.22,1,.36,1);
    }

    *,*::before,*::after { margin:0; padding:0; box-sizing:border-box; }
    html { scroll-behavior:smooth; }
    body {
      font-family:var(--font-body);
      -webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility;
      background:var(--paper); color:var(--ink); min-height:100vh; overflow-x:hidden;
    }
    body::after {
      content:''; position:fixed; inset:0; z-index:1000; pointer-events:none;
      opacity:.05; mix-blend-mode:multiply;
      background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/></filter><rect width='140' height='140' filter='url(%23n)'/></svg>");
    }
    ::selection { background:rgba(225,74,14,.18); color:var(--ink); }
    a { color:inherit; }
    button { font:inherit; }
    :focus-visible { outline:2px solid var(--accent); outline-offset:3px; border-radius:4px; }

    .grid-bg {
      position:fixed; inset:0; z-index:0; pointer-events:none;
      background-image:linear-gradient(rgba(20,23,26,.045) 1px,transparent 1px),linear-gradient(90deg,rgba(20,23,26,.045) 1px,transparent 1px);
      background-size:56px 56px;
      -webkit-mask-image:radial-gradient(ellipse 95% 62% at 50% -6%, black 12%, transparent 75%);
      mask-image:radial-gradient(ellipse 95% 62% at 50% -6%, black 12%, transparent 75%);
    }

    main { position:relative; z-index:1; width:min(1120px,calc(100% - 3rem)); margin:0 auto; padding:10rem 0 4rem; }

    /* LEAD */
    .lead { display:grid; grid-template-columns:minmax(0,1.5fr) minmax(260px,.65fr); gap:4rem; align-items:end; margin-bottom:3.5rem; }
    .lead-label { display:flex; align-items:center; gap:.875rem; margin-bottom:1.5rem; font-family:var(--font-mono); font-size:.625rem; font-weight:500; letter-spacing:.2em; color:var(--muted); text-transform:uppercase; }
    .lead-label::before { content:''; width:2.75rem; height:1px; background:var(--line-hi); }
    h1 { max-width:780px; font-family:var(--font-display); font-optical-sizing:auto; font-size:clamp(2.5rem,5vw,4.25rem); font-weight:400; line-height:1.06; letter-spacing:-.028em; color:var(--ink); text-wrap:balance; }
    h1 em { font-style:italic; color:var(--accent); }
    html[lang^="zh"] .title-gap { display:none; }
    .lead-copy { color:var(--muted); font-size:.9375rem; line-height:1.72; text-wrap:pretty; }
    .trust-line { display:flex; gap:.6rem; align-items:flex-start; margin-top:1.125rem; color:var(--emerald); font-family:var(--font-mono); font-size:.6875rem; line-height:1.65; }
    .trust-line::before { content:'✓'; flex:0 0 auto; }

    /* INPUT PATH — make the no-repository path explicit before diagram choices */
    .input-paths { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:.625rem; margin-bottom:1.25rem; }
    .input-path {
      min-height:72px; padding:.85rem 1rem; text-align:left;
      border:1px solid var(--line); border-radius:10px; background:var(--paper);
      color:var(--muted); cursor:pointer; transition:all .18s var(--ease-out);
    }
    .input-path:hover { color:var(--ink); border-color:var(--line-hi); }
    .input-path strong { display:block; margin-bottom:.3rem; color:inherit; font-size:.8125rem; font-weight:600; }
    .input-path span { display:block; font-size:.6875rem; line-height:1.5; }
    .input-path[aria-selected="true"] { border-color:var(--accent); background:var(--accent-soft); color:var(--ink); box-shadow:inset 3px 0 0 var(--accent); }

    /* TYPE TABS */
    .type-shell { margin-bottom:var(--bento-gap,14px); padding:1.25rem 1.5rem 1.5rem; border:1px solid var(--line-hi); border-radius:14px; background:var(--paper-raised); }
    .type-label { display:flex; align-items:center; justify-content:space-between; gap:1rem; margin-bottom:1rem; color:var(--dim); font-family:var(--font-mono); font-size:.625rem; letter-spacing:.16em; text-transform:uppercase; }
    .type-label strong { color:var(--accent); font-weight:600; }
    .type-tabs { display:grid; grid-template-columns:repeat(5,1fr); gap:1px; border:1px solid var(--line); border-radius:10px; overflow:hidden; background:var(--line); }
    .type-tab {
      min-height:52px;
      border:0;
      background:var(--paper-raised);
      color:var(--muted);
      cursor:pointer;
      font-family:var(--font-mono); font-size:.6875rem; font-weight:500; letter-spacing:.06em;
      transition:background .18s var(--ease-out),color .18s var(--ease-out);
    }
    .type-tab:hover { background:var(--paper); color:var(--ink); }
    .type-tab[aria-selected="true"] { background:var(--ink); color:var(--paper); }

    /* WORKBENCH — two paper cards */
    .workbench { display:grid; grid-template-columns:minmax(0,.82fr) minmax(0,1.18fr); gap:14px; align-items:stretch; }
    .panel { min-width:0; padding:2.25rem 2.5rem; border:1px solid var(--line-hi); border-radius:14px; background:var(--paper-raised); }
    .panel-kicker { display:flex; align-items:center; gap:.875rem; margin-bottom:1.5rem; color:var(--dim); font-family:var(--font-mono); font-size:.625rem; letter-spacing:.16em; text-transform:uppercase; }
    .panel-kicker b { font-family:var(--font-display); font-style:italic; font-optical-sizing:auto; font-weight:400; font-size:1.375rem; color:var(--accent); }
    .panel h2 { margin-bottom:.625rem; font-family:var(--font-display); font-optical-sizing:auto; font-size:1.5rem; font-weight:500; letter-spacing:-.02em; color:var(--ink); }
    .panel-intro { min-height:3.9rem; margin-bottom:1.5rem; color:var(--muted); font-size:.8125rem; line-height:1.7; text-wrap:pretty; }

    .agent-picker { margin-bottom:1.25rem; }
    .agent-picker-head { display:flex; align-items:center; justify-content:space-between; gap:1rem; margin-bottom:.75rem; color:var(--muted); font-family:var(--font-mono); font-size:.625rem; letter-spacing:.1em; text-transform:uppercase; line-height:1.45; }
    .agent-picker-head strong { color:var(--emerald); font-weight:600; }
    .agent-tabs { display:flex; flex-wrap:wrap; gap:.45rem; }
    .agent-tab {
      min-height:44px;
      padding:.55rem .85rem;
      border:1px solid var(--line-hi);
      border-radius:8px;
      background:transparent;
      color:var(--muted);
      cursor:pointer;
      font-family:var(--font-mono); font-size:.625rem; font-weight:500; letter-spacing:.06em;
      transition:all .18s var(--ease-out);
    }
    .agent-tab:hover { color:var(--ink); border-color:var(--ink); }
    .agent-tab[aria-selected="true"] { color:var(--paper); border-color:var(--ink); background:var(--ink); }

    /* COMMAND BLOCKS — dark plate on paper, like the project page install strip */
    .command-block { margin-top:.875rem; border:1px solid var(--ink); border-radius:10px; overflow:hidden; background:var(--plate); }
    .command-bar { display:flex; align-items:center; justify-content:space-between; gap:1rem; padding:.6rem .875rem; border-bottom:1px solid rgba(232,237,242,.1); color:#7d8894; font-family:var(--font-mono); font-size:.5625rem; text-transform:uppercase; letter-spacing:.14em; }
    .copy-button { border:0; background:transparent; color:var(--accent); cursor:pointer; font-family:var(--font-mono); font-size:.5625rem; font-weight:600; text-transform:uppercase; letter-spacing:.12em; transition:color .18s var(--ease-out); }
    .copy-button:hover { color:#ff7a3d; }
    pre { margin:0; padding:.9rem 1rem; overflow:auto; color:#e8edf2; font:500 .6875rem/1.7 var(--font-mono); white-space:pre-wrap; overflow-wrap:anywhere; }
    .secondary-note { margin:1rem 0 0; padding:.9rem 1rem; border:1px solid var(--line); border-radius:10px; background:var(--paper); color:var(--muted); font-size:.75rem; line-height:1.7; }

    .question { margin-bottom:1rem; color:var(--ink-soft); font-size:.9375rem; font-weight:500; line-height:1.6; }
    .include-list { display:flex; flex-wrap:wrap; gap:.45rem; margin-bottom:1.25rem; list-style:none; }
    .include-list li { padding:.35rem .65rem; border:1px solid var(--line); border-radius:999px; color:var(--muted); font-family:var(--font-mono); font-size:.5625rem; letter-spacing:.06em; background:var(--paper); }
    .prompt-box { min-height:172px; padding:1.15rem 1.25rem; border:1px solid rgba(225,74,14,.3); border-radius:10px; background:var(--accent-soft); color:var(--ink-soft); font-family:var(--font-mono); font-size:.75rem; line-height:1.8; white-space:pre-wrap; }
    .actions { display:flex; align-items:center; flex-wrap:wrap; gap:.625rem; margin-top:1.25rem; }
    .action { min-height:44px; display:inline-flex; align-items:center; justify-content:center; padding:.65rem 1.05rem; border:1px solid var(--line-hi); border-radius:8px; background:transparent; color:var(--ink-soft); font:500 .8125rem var(--font-body); text-decoration:none; cursor:pointer; transition:all .2s var(--ease-out); }
    .action:hover { color:var(--ink); border-color:var(--ink); }
    .action-primary { border-color:var(--ink); background:var(--ink); color:var(--paper); }
    .action-primary:hover { background:var(--accent); border-color:var(--accent); color:var(--paper); }
    .proof-meta { margin-top:1.1rem; color:var(--dim); font-family:var(--font-mono); font-size:.5625rem; letter-spacing:.08em; line-height:1.65; text-transform:uppercase; }

    .page-footer { display:flex; align-items:center; justify-content:space-between; gap:1rem; margin-top:3.5rem; padding-top:1.5rem; border-top:1px solid var(--line); color:var(--dim); font-family:var(--font-mono); font-size:.625rem; letter-spacing:.04em; }
    .page-footer a { color:var(--muted); text-decoration:none; transition:color .18s var(--ease-out); }
    .page-footer a:hover { color:var(--ink); }
    #copy-status { min-height:1.1rem; color:var(--emerald); }

    /* ENTRANCE — one quiet rise on load */
    @keyframes rise { from { opacity:0; transform:translateY(14px); } to { opacity:1; transform:none; } }
    .lead, .type-shell, .workbench { animation:rise .7s var(--ease-out) both; }
    .type-shell { animation-delay:.08s; }
    .workbench { animation-delay:.16s; }

    @media (max-width:840px) {
      main { width:min(100% - 2rem,720px); padding-top:8rem; }
      .lead { grid-template-columns:1fr; gap:1.5rem; margin-bottom:2.5rem; }
      .workbench { grid-template-columns:1fr; }
      .type-tabs { grid-template-columns:repeat(2,1fr); }
      .input-paths { grid-template-columns:1fr; }
      .type-tab:last-child { grid-column:1 / -1; }
    }
    @media (max-width:560px) {
      main { width:calc(100% - 1.5rem); padding-top:7rem; }
      h1 { font-size:2.2rem; }
      .panel { padding:1.5rem 1.25rem; }
      .type-shell { padding:1rem 1rem 1.25rem; }
      .type-tabs { grid-template-columns:1fr; }
      .type-tab:last-child { grid-column:auto; }
      .page-footer { align-items:flex-start; flex-direction:column; }
    }
    @media (prefers-reduced-motion:reduce) {
      html { scroll-behavior:auto; }
      .lead, .type-shell, .workbench { animation:none; }
    }
  </style>
</head>
<body>
  <div class="grid-bg" aria-hidden="true"></div>

  <nav class="site-nav" aria-label="Primary navigation">
    <a class="nav-logo" href="./" aria-label="Archify project page">
      <span class="nav-logo-text">Archify</span>
      <span class="nav-logo-path" data-en="/ start" data-zh="/ 快速上手">/ start</span>
    </a>
    <div class="nav-right">
      <a class="nav-link" href="guide.html" data-en="Guide" data-zh="场景指南">Guide</a>
      <a class="nav-link" href="gallery.html" data-en="Proof Lab" data-zh="验证作品集">Proof Lab</a>
      <a class="nav-link" href="start.html" aria-current="page" data-en="Start" data-zh="快速上手">Start</a>
      <a class="nav-link" href="https://github.com/tt-a1i/archify" target="_blank" rel="noopener">GitHub</a>
      <button class="btn-lang" id="language" type="button" aria-label="Switch language">中文</button>
      <a class="btn btn-primary nav-cta" href="#install" data-en="Install Skill" data-zh="安装技能">Install Skill</a>
    </div>
  </nav>

  <main>
    <header class="lead">
      <div>
        <p class="lead-label" data-en="Start with words, Mermaid, or code" data-zh="从描述、Mermaid 或代码开始">Start with words, Mermaid, or code</p>
        <h1><span data-en="Describe it." data-zh="直接说,">Describe it.</span><span class="title-gap" aria-hidden="true"> </span><em data-en="Archify maps it." data-zh="Archify 就能画。">Archify maps it.</em></h1>
      </div>
      <div>
        <p class="lead-copy" data-en="No repository is required. Describe a system or flow in a normal agent chat and Archify will turn it into a checked, interactive diagram. If code exists, the same skill can inspect it for evidence." data-zh="不需要绑定代码库。在任意 Agent 对话里用自然语言描述系统或流程,Archify 就会把它变成经过校验的交互图;如果有代码,也可以再让它读取仓库作为证据。">No repository is required. Describe a system or flow in a normal agent chat and Archify will turn it into a checked, interactive diagram. If code exists, the same skill can inspect it for evidence.</p>
        <div class="trust-line" data-en="Your description is enough to make the first diagram." data-zh="只有一段描述,也足够画出第一张图。">Your description is enough to make the first diagram.</div>
      </div>
    </header>

    <section class="type-shell" aria-labelledby="type-label">
      <p class="type-label"><span data-en="Choose how to start" data-zh="选择如何开始">Choose how to start</span><strong data-en="Repository optional" data-zh="代码库可选">Repository optional</strong></p>
      <div class="input-paths" role="tablist" aria-label="Input source">
        <button class="input-path" type="button" role="tab" data-input="description"><strong data-en="Just describe it" data-zh="直接描述">直接描述</strong><span data-en="Start in any chat. No files or repository needed." data-zh="在任意对话里开始,不需要文件或代码库。">Start in any chat. No files or repository needed.</span></button>
        <button class="input-path" type="button" role="tab" data-input="repository"><strong data-en="Use a repository" data-zh="从代码库开始">Use a repository</strong><span data-en="Let the agent inspect code when source evidence matters." data-zh="需要源码证据时,再让 Agent 检查代码。">Let the agent inspect code when source evidence matters.</span></button>
      </div>
      <p class="type-label" id="type-label"><span data-en="Choose the question shape" data-zh="选择问题形态">Choose the question shape</span><strong data-en="5 typed renderers" data-zh="5 种类型化渲染器">5 typed renderers</strong></p>
      <div class="type-tabs" role="tablist" aria-label="Diagram type">
        <button class="type-tab" type="button" role="tab" data-type="architecture" data-en="[[DIAGRAM_TYPE_ARCHITECTURE_EN]]" data-zh="[[DIAGRAM_TYPE_ARCHITECTURE_ZH]]">[[DIAGRAM_TYPE_ARCHITECTURE_EN]]</button>
        <button class="type-tab" type="button" role="tab" data-type="workflow" data-en="[[DIAGRAM_TYPE_WORKFLOW_EN]]" data-zh="[[DIAGRAM_TYPE_WORKFLOW_ZH]]">[[DIAGRAM_TYPE_WORKFLOW_EN]]</button>
        <button class="type-tab" type="button" role="tab" data-type="sequence" data-en="[[DIAGRAM_TYPE_SEQUENCE_EN]]" data-zh="[[DIAGRAM_TYPE_SEQUENCE_ZH]]">[[DIAGRAM_TYPE_SEQUENCE_EN]]</button>
        <button class="type-tab" type="button" role="tab" data-type="dataflow" data-en="[[DIAGRAM_TYPE_DATAFLOW_EN]]" data-zh="[[DIAGRAM_TYPE_DATAFLOW_ZH]]">[[DIAGRAM_TYPE_DATAFLOW_EN]]</button>
        <button class="type-tab" type="button" role="tab" data-type="lifecycle" data-en="[[DIAGRAM_TYPE_LIFECYCLE_EN]]" data-zh="[[DIAGRAM_TYPE_LIFECYCLE_ZH]]">[[DIAGRAM_TYPE_LIFECYCLE_EN]]</button>
      </div>
    </section>

    <section class="workbench" aria-label="Archify quick start">
      <article class="panel" id="install">
        <div class="panel-kicker"><b>01</b><span data-en="Install the skill" data-zh="安装 Skill">Install the skill</span></div>
        <h2 data-en="Keep the tool local." data-zh="让工具留在本地。">Keep the tool local.</h2>
        <p class="panel-intro" data-en="Choose Cursor, Codex, Claude Code, or OpenCode. The switcher gives each one the same checked Skill and zero-dependency renderers—no vendor-specific fork." data-zh="选择 Cursor、Codex、Claude Code 或 OpenCode。切换器为每个 Agent 提供同一份经过检查的 Skill 与零依赖渲染器,不维护厂商专属分叉。">Choose Cursor, Codex, Claude Code, or OpenCode. The switcher gives each one the same checked Skill and zero-dependency renderers—no vendor-specific fork.</p>

        <div class="agent-picker">
          <p class="agent-picker-head"><span data-en="Choose your coding agent" data-zh="选择你的编码 Agent">Choose your coding agent</span><strong id="agent-state">Codex · same Skill</strong></p>
          <div class="agent-tabs" role="tablist" aria-label="Coding agent">
            <button class="agent-tab" type="button" role="tab" data-agent="cursor">Cursor</button>
            <button class="agent-tab" type="button" role="tab" data-agent="codex">Codex</button>
            <button class="agent-tab" type="button" role="tab" data-agent="claude-code">Claude Code</button>
            <button class="agent-tab" type="button" role="tab" data-agent="opencode">OpenCode</button>
          </div>
        </div>

        <div class="command-block">
          <div class="command-bar"><span data-en="Global install" data-zh="全局安装">Global install</span><button class="copy-button" type="button" data-copy-source="install-command" data-en="Copy" data-zh="复制">Copy</button></div>
          <pre id="install-command">npx -y skills add tt-a1i/archify --skill archify --agent codex --global --copy --yes</pre>
        </div>
        <div class="command-block">
          <div class="command-bar"><span data-en="This repository only" data-zh="仅安装到当前仓库">This repository only</span><button class="copy-button" type="button" data-copy-source="project-command" data-en="Copy" data-zh="复制">Copy</button></div>
          <pre id="project-command">npx -y skills add tt-a1i/archify --skill archify --agent codex --copy --yes</pre>
        </div>
        <p class="secondary-note" data-en="Raven is supported through a manual ZIP installation, not a generated agent-switcher command. Extract archify.zip into ~/.raven/workspace/skills, which yields ~/.raven/workspace/skills/archify." data-zh="Raven 采用 ZIP 手动安装,不使用 Agent 切换器生成命令。将 archify.zip 解压到 ~/.raven/workspace/skills,解压后会得到 ~/.raven/workspace/skills/archify。">Raven is supported through a manual ZIP installation, not a generated agent-switcher command. Extract archify.zip into ~/.raven/workspace/skills, which yields ~/.raven/workspace/skills/archify.</p>
        <p class="secondary-note" data-en="The Start link carries only your agent, language, diagram type, input mode, and a coarse source label. Journey events stay in this browser session and are never sent by Archify. No repository path, title, node, relationship, or source JSON is recorded." data-zh="Start 链接只携带 Agent、语言、图表类型、输入模式和粗粒度来源标签。转化步骤只保存在当前浏览器会话中,Archify 不会发送这些数据,也不会记录仓库路径、标题、节点、关系或源 JSON。">The Start link carries only your agent, language, diagram type, input mode, and a coarse source label. Journey events stay in this browser session and are never sent by Archify. No repository path, title, node, relationship, or source JSON is recorded.</p>
      </article>

      <article class="panel" aria-live="polite">
        <div class="panel-kicker"><b>02</b><span data-en="Ask one bounded question" data-zh="只问一个有边界的问题">Ask one bounded question</span></div>
        <h2 id="recipe-title">System overview</h2>
        <p class="question" id="recipe-question"></p>
        <ul class="include-list" id="include-list" aria-label="Required evidence"></ul>
        <p class="prompt-box" id="recipe-prompt"></p>
        <div class="actions">
          <button class="action action-primary" id="copy-starter" type="button" data-en="Copy install + prompt" data-zh="复制安装命令 + 提示词">Copy install + prompt</button>
          <button class="action" id="copy-prompt" type="button" data-en="Prompt only" data-zh="仅复制提示词">Prompt only</button>
          <a class="action" id="proof-link" href="gallery.html" data-en="Open verified proof ↗" data-zh="打开验证成品 ↗">Open verified proof ↗</a>
          <a class="action" href="guide.html" data-en="Need another recipe?" data-zh="需要其他配方?">Need another recipe?</a>
        </div>
        <p class="proof-meta" id="proof-meta"></p>
      </article>
    </section>

    <footer class="page-footer">
      <span data-en="Archify v[[ARCHIFY_VERSION]] · development · self-contained HTML · typed JSON source" data-zh="Archify v[[ARCHIFY_VERSION]] · 开发版 · 独立 HTML · 类型化 JSON 源">Archify v[[ARCHIFY_VERSION]] · development · self-contained HTML · typed JSON source</span>
      <span id="copy-status" role="status" aria-live="polite"></span>
      <a href="https://github.com/tt-a1i/archify" data-en="View source on GitHub ↗" data-zh="在 GitHub 查看源码 ↗">View source on GitHub ↗</a>
    </footer>
  </main>

  <script id="start-data" type="application/json">[[START_JSON]]</script>
  <script src="assets/site-language.js"></script>
  <script>
    (function () {
      'use strict';

      var DATA = JSON.parse(document.getElementById('start-data').textContent);
      var KNOWN_TYPES = new Set(['architecture', 'workflow', 'sequence', 'dataflow', 'lifecycle']);
      var KNOWN_AGENTS = new Set(['cursor', 'codex', 'claude-code', 'opencode']);
      var KNOWN_INPUTS = new Set(['description', 'repository']);
      var KNOWN_SOURCES = new Set(['artifact', 'gallery', 'readme', 'direct']);
      var EVENT_KEY = 'archify.start.events.v1';
      var params = new URLSearchParams(window.location.search);
      var requestedType = params.get('type');
      var requestedAgent = params.get('agent');
      var requestedSource = params.get('source');
      var requestedInput = params.get('input');
      var type = KNOWN_TYPES.has(requestedType) ? requestedType : 'architecture';
      var agent = KNOWN_AGENTS.has(requestedAgent) ? requestedAgent : 'codex';
      var source = KNOWN_SOURCES.has(requestedSource) ? requestedSource : 'direct';
      var input = KNOWN_INPUTS.has(requestedInput) ? requestedInput : 'description';
      var language = ArchifySiteLanguage.read();

      var title = document.getElementById('recipe-title');
      var question = document.getElementById('recipe-question');
      var prompt = document.getElementById('recipe-prompt');
      var includeList = document.getElementById('include-list');
      var proofLink = document.getElementById('proof-link');
      var proofMeta = document.getElementById('proof-meta');
      var copyStatus = document.getElementById('copy-status');
      var languageButton = document.getElementById('language');
      var agentState = document.getElementById('agent-state');
      var installCommand = document.getElementById('install-command');
      var projectCommand = document.getElementById('project-command');

      function copyForElement(element) {
        return language === 'zh' ? element.dataset.zh : element.dataset.en;
      }

      function updateStaticCopy() {
        document.documentElement.lang = language === 'zh' ? 'zh-CN' : 'en';
        document.querySelectorAll('[data-en][data-zh]').forEach(function (element) {
          element.textContent = copyForElement(element);
        });
        languageButton.textContent = language === 'zh' ? 'EN' : '中文';
        languageButton.setAttribute('aria-label', language === 'zh' ? 'Switch to English' : '切换到中文');
      }

      function updateUrl() {
        var next = new URL(window.location.href);
        next.searchParams.set('type', type);
        next.searchParams.set('agent', agent);
        next.searchParams.delete('lang');
        next.searchParams.set('source', source);
        next.searchParams.set('input', input);
        history.replaceState(null, '', next.pathname + next.search + next.hash);
      }

      function recordStep(step) {
        var detail = {
          schemaVersion: 1,
          step: step,
          source: source,
          type: type,
          agent: agent,
          language: language
        };
        try {
          var events = JSON.parse(sessionStorage.getItem(EVENT_KEY) || '[]');
          if (!Array.isArray(events)) events = [];
          events.push(detail);
          sessionStorage.setItem(EVENT_KEY, JSON.stringify(events.slice(-24)));
        } catch (_) {}
        try { window.dispatchEvent(new CustomEvent('archify:start-funnel', { detail: detail })); } catch (_) {}
      }

      window.ArchifyStartMetrics = {
        snapshot: function () {
          try {
            var events = JSON.parse(sessionStorage.getItem(EVENT_KEY) || '[]');
            return Array.isArray(events) ? events.slice() : [];
          } catch (_) { return []; }
        }
      };

      function currentPrompt() {
        return input === 'description'
          ? DATA[type][language].descriptionPrompt
          : DATA[type][language].repositoryPrompt;
      }

      function render() {
        language = ArchifySiteLanguage.write(language);
        var recipe = DATA[type];
        var copy = recipe[language];
        updateStaticCopy();
        document.querySelectorAll('[data-type]').forEach(function (button) {
          var active = button.dataset.type === type;
          button.setAttribute('aria-selected', String(active));
          button.tabIndex = active ? 0 : -1;
        });
        document.querySelectorAll('[data-agent]').forEach(function (button) {
          var active = button.dataset.agent === agent;
          button.setAttribute('aria-selected', String(active));
          button.tabIndex = active ? 0 : -1;
        });
        document.querySelectorAll('[data-input]').forEach(function (button) {
          var active = button.dataset.input === input;
          button.setAttribute('aria-selected', String(active));
          button.tabIndex = active ? 0 : -1;
        });
        var agentName = document.querySelector('[data-agent="' + agent + '"]').textContent;
        agentState.textContent = agentName + (language === 'zh' ? ' · 同一份 Skill' : ' · same Skill');
        installCommand.textContent = 'npx -y skills add tt-a1i/archify --skill archify --agent ' + agent + ' --global --copy --yes';
        projectCommand.textContent = 'npx -y skills add tt-a1i/archify --skill archify --agent ' + agent + ' --copy --yes';
        title.textContent = copy.title;
        question.textContent = copy.question;
        prompt.textContent = currentPrompt();
        includeList.replaceChildren.apply(includeList, copy.include.map(function (item) {
          var entry = document.createElement('li');
          entry.textContent = item;
          return entry;
        }));
        proofLink.href = 'gallery.html#proof-' + encodeURIComponent(recipe.proof);
        proofMeta.textContent = language === 'zh'
          ? '验证成品 · ' + recipe.presentation.preset + ' · ' + recipe.presentation.motion
          : 'Verified proof · ' + recipe.presentation.preset + ' · ' + recipe.presentation.motion;
        copyStatus.textContent = '';
        updateUrl();
      }

      function fallbackCopy(text) {
        var area = document.createElement('textarea');
        area.value = text;
        area.setAttribute('readonly', '');
        area.style.position = 'fixed';
        area.style.opacity = '0';
        document.body.appendChild(area);
        area.select();
        var ok = document.execCommand('copy');
        area.remove();
        if (!ok) throw new Error('copy failed');
      }

      function starterText() {
        var agentName = document.querySelector('[data-agent="' + agent + '"]').textContent;
        if (language === 'zh') {
          return '为 ' + agentName + ' 安装 Archify:\n' + installCommand.textContent.trim()
            + (input === 'description' ? '\n\n然后在任意新对话中直接告诉 ' : '\n\n然后在目标仓库中让 ') + agentName + ':\n' + currentPrompt();
        }
        return 'Install Archify for ' + agentName + ':\n' + installCommand.textContent.trim()
          + (input === 'description' ? '\n\nThen start any new chat and tell ' : '\n\nThen, in your target repository, ask ') + agentName + ':\n' + currentPrompt();
      }

      async function copyText(text, step) {
        try {
          if (navigator.clipboard && window.isSecureContext) await navigator.clipboard.writeText(text);
          else fallbackCopy(text);
          if (step) recordStep(step);
          copyStatus.textContent = language === 'zh' ? '已复制到剪贴板。' : 'Copied to clipboard.';
        } catch (_) {
          copyStatus.textContent = language === 'zh' ? '复制失败,请手动选择文本。' : 'Copy failed. Select the text manually.';
        }
      }

      document.querySelectorAll('[data-type]').forEach(function (button) {
        button.addEventListener('click', function () {
          type = button.dataset.type;
          render();
        });
        button.addEventListener('keydown', function (event) {
          var buttons = Array.from(document.querySelectorAll('[data-type]'));
          var index = buttons.indexOf(button);
          if (event.key === 'ArrowRight' || event.key === 'ArrowDown') index = (index + 1) % buttons.length;
          else if (event.key === 'ArrowLeft' || event.key === 'ArrowUp') index = (index - 1 + buttons.length) % buttons.length;
          else if (event.key === 'Home') index = 0;
          else if (event.key === 'End') index = buttons.length - 1;
          else return;
          event.preventDefault();
          buttons[index].click();
          buttons[index].focus();
        });
      });

      document.querySelectorAll('[data-agent]').forEach(function (button) {
        button.addEventListener('click', function () {
          agent = button.dataset.agent;
          render();
        });
        button.addEventListener('keydown', function (event) {
          var buttons = Array.from(document.querySelectorAll('[data-agent]'));
          var index = buttons.indexOf(button);
          if (event.key === 'ArrowRight' || event.key === 'ArrowDown') index = (index + 1) % buttons.length;
          else if (event.key === 'ArrowLeft' || event.key === 'ArrowUp') index = (index - 1 + buttons.length) % buttons.length;
          else if (event.key === 'Home') index = 0;
          else if (event.key === 'End') index = buttons.length - 1;
          else return;
          event.preventDefault();
          buttons[index].click();
          buttons[index].focus();
        });
      });

      document.querySelectorAll('[data-input]').forEach(function (button) {
        button.addEventListener('click', function () {
          input = button.dataset.input;
          render();
        });
        button.addEventListener('keydown', function (event) {
          var buttons = Array.from(document.querySelectorAll('[data-input]'));
          var index = buttons.indexOf(button);
          if (event.key === 'ArrowRight' || event.key === 'ArrowDown') index = (index + 1) % buttons.length;
          else if (event.key === 'ArrowLeft' || event.key === 'ArrowUp') index = (index - 1 + buttons.length) % buttons.length;
          else if (event.key === 'Home') index = 0;
          else if (event.key === 'End') index = buttons.length - 1;
          else return;
          event.preventDefault();
          buttons[index].click();
          buttons[index].focus();
        });
      });

      document.querySelectorAll('[data-copy-source]').forEach(function (button) {
        button.addEventListener('click', function () {
          var step = button.dataset.copySource === 'install-command' ? 'global_install_copy' : 'project_install_copy';
          copyText(document.getElementById(button.dataset.copySource).textContent.trim(), step);
        });
      });
      document.getElementById('copy-prompt').addEventListener('click', function () {
        copyText(currentPrompt(), 'prompt_copy');
      });
      document.getElementById('copy-starter').addEventListener('click', function () {
        copyText(starterText(), 'starter_copy');
      });
      proofLink.addEventListener('click', function () { recordStep('proof_open'); });
      languageButton.addEventListener('click', function () {
        language = language === 'zh' ? 'en' : 'zh';
        render();
      });

      render();
      recordStep('start_view');
    })();
  </script>
</body>
</html>