File size: 32,648 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
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta name="generator" content="archify guide [[ARCHIFY_VERSION]]">
  <title>Archify Scenario Guide — Choose the Right Diagram</title>
  <meta name="description" content="Describe the technical question you need to answer. Archify recommends a bounded diagram recipe, evidence checklist, and copy-ready prompt.">
  <meta name="theme-color" content="#eff2f1">
  <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; --rose:#be123c; --violet:#6d28d9;
      --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); }
    button,textarea { font:inherit; }
    button { color:inherit; }
    a { color: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%);
    }

    .btn { display:inline-flex; align-items:center; gap:.5rem; padding:.55rem 1.15rem; border-radius:6px; font-family:var(--font-body); font-size:.8125rem; font-weight:500; letter-spacing:-.005em; cursor:pointer; text-decoration:none; transition:all .2s var(--ease-out); border:1px solid transparent; }
    .btn-primary { background:var(--ink); color:var(--paper); }
    .btn-primary:hover { background:#272c31; transform:translateY(-1px); }
    .shell { position:relative; z-index:1; width:min(1180px,calc(100% - 48px)); margin:0 auto; }

    /* HERO */
    .hero { padding:10rem 0 4rem; display:grid; grid-template-columns:minmax(0,1.35fr) minmax(280px,.65fr); gap:4.5rem; align-items:end; }
    .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:770px; 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); }
    .lede { max-width:680px; margin-top:1.5rem; color:var(--muted); font-size:.9375rem; line-height:1.72; text-wrap:pretty; }
    .metrics { display:grid; gap:1px; background:var(--line); border:1px solid var(--line-hi); border-radius:12px; overflow:hidden; }
    .metric { display:flex; justify-content:space-between; align-items:center; gap:1rem; padding:1rem 1.25rem; background:var(--paper-raised); }
    .metric strong { font-family:var(--font-display); font-style:italic; font-optical-sizing:auto; font-weight:400; font-size:1.625rem; line-height:1; color:var(--ink); }
    .metric span { color:var(--dim); font-family:var(--font-mono); font-size:.5625rem; letter-spacing:.14em; text-transform:uppercase; line-height:1.5; text-align:right; }

    /* CHOOSER */
    .chooser { padding:1.75rem 2rem 2rem; border:1px solid var(--line-hi); border-radius:14px; background:var(--paper-raised); position:relative; }
    .chooser-head { display:flex; align-items:flex-start; justify-content:space-between; gap:1.25rem; margin-bottom:1.125rem; }
    .chooser-head h2 { margin-bottom:.375rem; font-family:var(--font-display); font-optical-sizing:auto; font-size:1.5rem; font-weight:500; letter-spacing:-.02em; }
    .chooser-head p { color:var(--muted); font-size:.8125rem; line-height:1.6; }
    .kbd { flex:none; border:1px solid var(--line-hi); border-radius:5px; padding:.3rem .5rem; color:var(--dim); font-family:var(--font-mono); font-size:.5625rem; background:var(--paper); }
    textarea { width:100%; min-height:104px; resize:vertical; border:1px solid var(--line-hi); border-radius:10px; padding:.9rem 1rem; background:var(--paper); color:var(--ink); outline:none; font-family:var(--font-mono); font-size:.75rem; line-height:1.7; transition:border-color .18s var(--ease-out),box-shadow .18s var(--ease-out); }
    textarea::placeholder { color:var(--dim); }
    textarea:focus { border-color:var(--accent); box-shadow:0 0 0 3px var(--accent-soft); }
    .sample-row { margin:.875rem 0 1.125rem; display:flex; gap:.45rem; flex-wrap:wrap; }
    .chip { border:1px solid var(--line); border-radius:999px; background:var(--paper); color:var(--muted); padding:.45rem .75rem; font-family:var(--font-mono); font-size:.5625rem; letter-spacing:.06em; cursor:pointer; transition:all .18s var(--ease-out); }
    .chip:hover { color:var(--accent); border-color:var(--accent); }
    .actions { display:flex; align-items:center; gap:.625rem; }
    .primary,.secondary { min-height:44px; border-radius:8px; padding:.65rem 1.15rem; border:1px solid transparent; font-size:.8125rem; font-weight:500; cursor:pointer; transition:all .2s var(--ease-out); }
    .primary { background:var(--ink); color:var(--paper); border-color:var(--ink); }
    .primary:hover { background:var(--accent); border-color:var(--accent); }
    .secondary { background:transparent; border-color:var(--line-hi); color:var(--ink-soft); }
    .secondary:hover { color:var(--ink); border-color:var(--ink); }

    /* RESULT */
    .result { margin-top:1.25rem; border:1px solid var(--line-hi); border-radius:14px; background:var(--paper-raised); overflow:hidden; display:none; }
    .result.visible { display:block; animation:reveal .3s var(--ease-out); }
    @keyframes reveal { from { opacity:0; transform:translateY(6px); } }
    .result-main { padding:1.75rem 2rem; display:grid; grid-template-columns:minmax(0,1.1fr) minmax(260px,.9fr); gap:2rem; }
    .result-kicker { color:var(--accent); font-family:var(--font-mono); font-size:.5625rem; font-weight:600; letter-spacing:.16em; text-transform:uppercase; }
    .result h3 { margin:.5rem 0 .375rem; font-family:var(--font-display); font-optical-sizing:auto; font-size:1.625rem; font-weight:500; letter-spacing:-.02em; }
    .result-question { color:var(--ink-soft); font-size:.875rem; font-weight:500; line-height:1.6; }
    .result-summary { margin-top:.875rem; color:var(--muted); font-size:.8125rem; line-height:1.7; }
    .proof-link { display:inline-flex; align-items:center; margin-top:1.125rem; padding:.5rem .75rem; border:1px solid rgba(4,120,87,.35); border-radius:999px; background:rgba(4,120,87,.06); color:var(--emerald); text-decoration:none; font-family:var(--font-mono); font-size:.5625rem; font-weight:600; letter-spacing:.12em; text-transform:uppercase; transition:all .18s var(--ease-out); }
    .proof-link:hover { border-color:var(--emerald); background:rgba(4,120,87,.1); }
    .boundary { display:grid; gap:1rem; align-content:start; }
    .boundary-item small { display:block; margin-bottom:.375rem; color:var(--emerald); font-family:var(--font-mono); font-size:.5625rem; font-weight:600; letter-spacing:.14em; text-transform:uppercase; }
    .boundary-item.avoid small { color:var(--rose); }
    .boundary-item p { color:var(--muted); font-size:.8125rem; line-height:1.65; }
    .result-grid { display:grid; grid-template-columns:minmax(230px,.7fr) minmax(0,1.3fr); border-top:1px solid var(--line); }
    .checklist,.prompt-box { padding:1.5rem 2rem; }
    .checklist { border-right:1px solid var(--line); }
    .mini-heading { margin-bottom:.875rem; color:var(--dim); font-family:var(--font-mono); font-size:.5625rem; font-weight:500; letter-spacing:.16em; text-transform:uppercase; }
    .checklist ul { list-style:none; display:grid; gap:.55rem; }
    .checklist li { color:var(--muted); font-size:.75rem; line-height:1.55; display:flex; gap:.5rem; }
    .checklist li::before { content:'✓'; color:var(--emerald); flex:0 0 auto; }
    .presentation { display:flex; flex-wrap:wrap; gap:.4rem; margin-top:1.125rem; }
    .tag { padding:.35rem .6rem; border-radius:999px; border:1px solid var(--line); background:var(--paper); color:var(--muted); font-family:var(--font-mono); font-size:.5625rem; letter-spacing:.06em; }
    .prompt-bar { display:flex; align-items:center; justify-content:space-between; gap:.75rem; margin-bottom:.75rem; }
    .copy { border:0; background:none; color:var(--accent); padding:0; font-family:var(--font-mono); font-size:.5625rem; font-weight:600; letter-spacing:.12em; text-transform:uppercase; cursor:pointer; }
    .copy:hover { color:var(--ink); }
    .prompt-text { color:var(--ink-soft); font-family:var(--font-mono); font-size:.6875rem; line-height:1.75; white-space:pre-wrap; }
    .alternatives { padding:.9rem 2rem; border-top:1px solid var(--line); color:var(--dim); font-size:.75rem; }
    .alternatives button { margin-left:.5rem; padding:0; border:0; background:none; color:var(--muted); cursor:pointer; font-size:.75rem; text-decoration:underline; text-underline-offset:3px; text-decoration-color:var(--line-hi); }
    .alternatives button:hover { color:var(--accent); text-decoration-color:var(--accent); }

    /* LIBRARY */
    .library { padding:5rem 0 6rem; }
    .section-head { display:flex; align-items:end; justify-content:space-between; gap:1.75rem; margin-bottom:1.75rem; }
    .section-head h2 { margin-top:.5rem; font-family:var(--font-display); font-optical-sizing:auto; font-size:clamp(1.75rem,3vw,2.5rem); font-weight:400; letter-spacing:-.026em; }
    .section-head p { max-width:440px; color:var(--muted); font-size:.8125rem; line-height:1.7; }
    .filters { display:flex; flex-wrap:wrap; gap:.45rem; margin-bottom:1.25rem; }
    .filter { border:1px solid var(--line-hi); border-radius:999px; background:transparent; color:var(--muted); padding:.5rem .85rem; font-family:var(--font-mono); font-size:.5625rem; font-weight:500; letter-spacing:.1em; text-transform:uppercase; cursor:pointer; transition:all .18s var(--ease-out); }
    .filter:hover { color:var(--ink); border-color:var(--ink); }
    .filter.active { color:var(--paper); background:var(--ink); border-color:var(--ink); }
    .cards { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:14px; }
    .card { min-width:0; min-height:206px; padding:1.375rem 1.5rem; text-align:left; border:1px solid var(--line-hi); border-radius:12px; background:var(--paper-raised); cursor:pointer; transition:transform .22s var(--ease-out),border-color .22s var(--ease-out),box-shadow .22s var(--ease-out); position:relative; font-family:inherit; }
    .card:hover,.card:focus-visible { transform:translateY(-3px); border-color:var(--ink); box-shadow:0 14px 36px rgba(20,23,26,.1); outline:none; }
    .card-type { color:var(--type-color,var(--accent)); font-family:var(--font-mono); font-size:.5625rem; font-weight:600; letter-spacing:.14em; text-transform:uppercase; }
    .card h3 { margin:.875rem 0 .5rem; font-family:var(--font-display); font-optical-sizing:auto; font-size:1.125rem; font-weight:500; letter-spacing:-.015em; color:var(--ink); }
    .card-question { color:var(--ink-soft); font-size:.75rem; line-height:1.6; }
    .card-summary { margin:.75rem 0 0; color:var(--dim); font-size:.6875rem; line-height:1.6; }
    .card-foot { position:absolute; left:1.5rem; right:1.5rem; bottom:1.125rem; display:flex; justify-content:space-between; gap:.75rem; color:var(--dim); font-family:var(--font-mono); font-size:.5625rem; letter-spacing:.06em; }
    .card { padding-bottom:2.75rem; }

    footer { border-top:1px solid var(--line); padding:1.75rem 0 2.5rem; color:var(--dim); font-family:var(--font-mono); font-size:.625rem; letter-spacing:.04em; }
    footer .shell { display:flex; justify-content:space-between; gap:1rem; }

    /* ENTRANCE */
    @keyframes rise { from { opacity:0; transform:translateY(14px); } to { opacity:1; transform:none; } }
    .hero, .chooser, .library { animation:rise .7s var(--ease-out) both; }
    .chooser { animation-delay:.08s; }
    .library { animation-delay:.16s; }

    @media(max-width:900px) {
      .hero { grid-template-columns:1fr; gap:2.25rem; padding-top:8.5rem; }
      .metrics { grid-template-columns:repeat(3,1fr); }
      .metric { display:grid; gap:.4rem; }
      .metric span { text-align:left; }
      .cards { grid-template-columns:repeat(2,minmax(0,1fr)); }
      .result-main,.result-grid { grid-template-columns:1fr; }
      .checklist { border-right:0; border-bottom:1px solid var(--line); }
    }
    @media(max-width:620px) {
      .shell { width:min(100% - 28px,1180px); }
      .hero { padding:7.5rem 0 2.5rem; }
      h1 { font-size:2.2rem; }
      .lede { font-size:.875rem; }
      .metrics { grid-template-columns:1fr; }
      .metric { display:flex; }
      .metric span { text-align:right; }
      .chooser { padding:1.25rem; }
      .chooser-head .kbd { display:none; }
      .sample-row { flex-wrap:nowrap; overflow:auto; padding-bottom:4px; }
      .chip { white-space:nowrap; }
      .result-main { padding:1.25rem; }
      .checklist,.prompt-box { padding:1.125rem 1.25rem; }
      .cards { grid-template-columns:1fr; }
      .section-head { align-items:flex-start; flex-direction:column; }
      .library { padding:3.5rem 0 4.5rem; }
      footer .shell { flex-direction:column; }
    }
    @media (prefers-reduced-motion:reduce) {
      html { scroll-behavior:auto; }
      .hero, .chooser, .library, .result.visible { 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 home">
      <span class="nav-logo-text">Archify</span>
      <span class="nav-logo-path" data-en="/ guide" data-zh="/ 场景指南">/ guide</span>
    </a>
    <div class="nav-right">
      <a class="nav-link" href="guide.html" aria-current="page" data-i18n="navGuide">Guide</a>
      <a class="nav-link" href="gallery.html" data-i18n="navProof">Proof Lab</a>
      <a class="nav-link" href="start.html" data-i18n="navStart">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="start.html" data-i18n="navInstall">Install Skill</a>
    </div>
  </nav>

  <main class="shell">
    <section class="hero">
      <div>
        <div class="lead-label" data-i18n="eyebrow">Question-first diagramming</div>
        <h1 data-i18n-html="headline">Choose the question.<br>Get the <em>right diagram.</em></h1>
        <p class="lede" data-i18n="lede">Describe what your audience needs to understand. Archify recommends one bounded visual recipe—plus the evidence it must contain, when not to use it, and a prompt you can copy.</p>
      </div>
      <div class="metrics" aria-label="Guide metrics">
        <div class="metric"><strong>[[RECIPE_COUNT]]</strong><span data-i18n-html="metricRecipes">real-world<br>recipes</span></div>
        <div class="metric"><strong>5</strong><span data-i18n-html="metricModes">typed diagram<br>modes</span></div>
        <div class="metric"><strong>0</strong><span data-i18n-html="metricRuntime">runtime<br>dependencies</span></div>
      </div>
    </section>

    <section class="chooser" aria-labelledby="chooser-title">
      <div class="chooser-head">
        <div><h2 id="chooser-title" data-i18n="chooserTitle">What must the diagram explain?</h2><p data-i18n="chooserBody">Write a situation, not a diagram type. Specific system facts produce a stronger recommendation.</p></div>
        <span class="kbd">⌘ / Ctrl + Enter</span>
      </div>
      <textarea id="scenario" data-i18n-placeholder="placeholder" placeholder="Example: Show an API request with JWT auth, a Redis cache miss, database fallback, and async tracing."></textarea>
      <div class="sample-row" id="samples"></div>
      <div class="actions">
        <button class="primary" id="recommend" type="button" data-i18n="recommend">Recommend a recipe →</button>
        <button class="secondary" id="clear" type="button" data-i18n="clear">Clear</button>
      </div>
      <div class="result" id="result" aria-live="polite"></div>
    </section>

    <section class="library" id="library">
      <div class="section-head">
        <div><div class="lead-label" data-i18n="libraryEyebrow">Recipe library</div><h2 data-i18n="libraryTitle">Eleven small, opinionated starting points.</h2></div>
        <p data-i18n="libraryBody">Each recipe answers one technical question. That boundary keeps the result legible, reviewable, and honest about missing evidence.</p>
      </div>
      <div class="filters" id="filters" aria-label="Filter recipes"></div>
      <div class="cards" id="cards"></div>
    </section>
  </main>

  <footer><div class="shell"><span data-i18n="footerLeft">Generated from the same recipe source as the Archify CLI.</span><span>archify guide "your scenario"</span><span data-i18n="versionLabel">Scenario guide / development / v[[ARCHIFY_VERSION]]</span></div></footer>

  <script id="guide-data" type="application/json">[[GUIDE_JSON]]</script>
  <script src="assets/site-language.js"></script>
  <script>
    (function () {
      'use strict';
      var recipes = JSON.parse(document.getElementById('guide-data').textContent);
      var types = [[DIAGRAM_TYPES_JSON]];
      var colors = { architecture:'#0891b2', workflow:'#047857', sequence:'#6d28d9', dataflow:'#b45309', lifecycle:'#be123c' };
      var language = ArchifySiteLanguage.read();
      var activeType = 'all';
      var lastRecipe = null;
      var copy = {
        en: {
          navGuide:'Guide',navProof:'Proof Lab',navStart:'Start',navInstall:'Install Skill',versionLabel:'Scenario guide / development / v[[ARCHIFY_VERSION]]',eyebrow:'Question-first diagramming', headline:'Choose the question.<br>Get the <em>right diagram.</em>', lede:'Describe what your audience needs to understand. Archify recommends one bounded visual recipe—plus the evidence it must contain, when not to use it, and a prompt you can copy.',
          metricRecipes:'real-world<br>recipes',metricModes:'typed diagram<br>modes',metricRuntime:'runtime<br>dependencies',chooserTitle:'What must the diagram explain?',chooserBody:'Write a situation, not a diagram type. Specific system facts produce a stronger recommendation.',placeholder:'Example: Show an API request with JWT auth, a Redis cache miss, database fallback, and async tracing.',recommend:'Recommend a recipe →',clear:'Clear',libraryEyebrow:'Recipe library',libraryTitle:'Eleven small, opinionated starting points.',libraryBody:'Each recipe answers one technical question. That boundary keeps the result legible, reviewable, and honest about missing evidence.',footerLeft:'Generated from the same recipe source as the Archify CLI.',all:'All recipes',recommended:'Recommended recipe',use:'Use when',avoid:'Avoid when',must:'Evidence to include',presentation:'Presentation',prompt:'Copy-ready prompt',copyPrompt:'Copy prompt',copied:'Copied',alternatives:'Other possible fits:',confidence:'confidence',open:'Open recipe',proofReady:'Verified proof',proofLink:'Open verified example ↗',
          samples:[['API + cache miss','Show an API request with JWT auth, a Redis cache miss, database fallback, and async tracing.'],['Kafka + DLQ','Map Kafka topics, ordered processors, consumer groups, replay, state stores, and the dead-letter queue.'],['Incident response','Show how responders detect, triage, mitigate, escalate, communicate, and verify recovery.']]
        },
        zh: {
          navGuide:'场景指南',navProof:'验证作品集',navStart:'快速上手',navInstall:'安装技能',versionLabel:'场景指南 / 开发版 / v[[ARCHIFY_VERSION]]',eyebrow:'先问题,后图表',headline:'先选对问题,<br>再得到<em>对的图。</em>',lede:'描述受众真正需要理解的内容。Archify 会推荐一个有边界的视觉配方,同时给出证据清单、禁用条件和可复制提示词。',
          metricRecipes:'个真实场景<br>配方',metricModes:'种类型化<br>图表模式',metricRuntime:'个运行时<br>依赖',chooserTitle:'这张图必须解释什么?',chooserBody:'写清场景,不要只写图表类型。系统事实越具体,推荐越可靠。',placeholder:'例如:展示带 JWT 鉴权、Redis 缓存未命中、数据库回退和异步追踪的 API 请求。',recommend:'推荐配方 →',clear:'清空',libraryEyebrow:'配方库',libraryTitle:'十一个小而专的起点。',libraryBody:'每个配方只回答一个技术问题。清晰的边界让图更易读、可评审,也不会掩盖证据缺口。',footerLeft:'网页与 Archify CLI 使用同一份配方数据生成。',all:'全部配方',recommended:'推荐配方',use:'适合',avoid:'不要这样用',must:'必须包含的证据',presentation:'表现建议',prompt:'可直接复制的提示词',copyPrompt:'复制提示词',copied:'已复制',alternatives:'其他可能:',confidence:'置信度',open:'打开配方',proofReady:'已验证成品',proofLink:'打开验证成品 ↗',
          samples:[['API + 缓存未命中','展示带 JWT 鉴权、Redis 缓存未命中、数据库回退和异步追踪的 API 请求。'],['Kafka + 死信','梳理 Kafka Topic、有序处理器、消费者组、重放、状态存储和死信队列。'],['事故处置','展示响应者如何发现、分诊、缓解、升级、沟通并验证恢复。']]
        }
      };

      function t(key) { return copy[language][key]; }
      function local(recipe) { return Object.assign({}, recipe, recipe[language]); }
      function normalize(value) { return String(value || '').normalize('NFKC').toLowerCase().replace(/[\\s_]+/g,' ').trim(); }
      function rank(query) {
        var text = normalize(query);
        return recipes.map(function (recipe,index) {
          var score = 0, matched = [];
          if (text === recipe.id || text === recipe.id.replace(/-/g,' ')) { score = 100; matched = [recipe.id]; }
          else recipe.signals.forEach(function (signal) { if (text.includes(normalize(signal[0]))) { score += signal[1]; matched.push(signal[0]); } });
          return { recipe:recipe, score:score, matched:matched, index:index };
        }).sort(function (a,b) { return b.score - a.score || a.index - b.index; });
      }
      function recommendation(query) {
        var ranked = rank(query), winner = ranked[0].score > 0 ? ranked[0] : { recipe:recipes[0], score:0, matched:[] };
        return { recipe:winner.recipe, confidence:winner.score >= 14 ? 'high' : winner.score >= 7 ? 'medium' : 'low', alternatives:ranked.filter(function (entry) { return entry.recipe.id !== winner.recipe.id && entry.score > 0; }).slice(0,2) };
      }
      function escapeHtml(value) { var node = document.createElement('span'); node.textContent = String(value); return node.innerHTML; }
      function renderSamples() {
        document.getElementById('samples').innerHTML = t('samples').map(function (sample) { return '<button class="chip" type="button" data-query="'+escapeHtml(sample[1])+'">'+escapeHtml(sample[0])+'</button>'; }).join('');
      }
      function renderFilters() {
        var labels = [[DIAGRAM_TYPE_LABELS_JSON]];
        document.getElementById('filters').innerHTML = ['all'].concat(types).map(function (type) { return '<button class="filter '+(activeType === type ? 'active':'')+'" type="button" data-filter="'+type+'">'+escapeHtml(type === 'all' ? t('all') : labels[language][type])+'</button>'; }).join('');
      }
      function renderCards() {
        var visible = recipes.filter(function (recipe) { return activeType === 'all' || recipe.type === activeType; });
        document.getElementById('cards').innerHTML = visible.map(function (raw) {
          var recipe = local(raw);
          return '<button class="card" type="button" data-recipe="'+recipe.id+'" style="--type-color:'+colors[recipe.type]+'"><span class="card-type">'+escapeHtml(recipe.type)+'</span><h3>'+escapeHtml(recipe.title)+'</h3><p class="card-question">'+escapeHtml(recipe.question)+'</p><p class="card-summary">'+escapeHtml(recipe.summary)+'</p><span class="card-foot"><span>'+escapeHtml(recipe.presentation.preset)+' · '+escapeHtml(recipe.presentation.motion)+'</span><span>'+escapeHtml(recipe.proof ? t('proofReady') : t('open'))+' ↗</span></span></button>';
        }).join('');
      }
      function renderResult(rawRecipe, confidence, alternatives) {
        var recipe = local(rawRecipe);
        lastRecipe = rawRecipe;
        var alt = alternatives || [];
        var html = '<div class="result-main"><div><span class="result-kicker">'+escapeHtml(t('recommended'))+' · '+escapeHtml(confidence)+' '+escapeHtml(t('confidence'))+'</span><h3>'+escapeHtml(recipe.title)+'</h3><p class="result-question">'+escapeHtml(recipe.question)+'</p><p class="result-summary">'+escapeHtml(recipe.summary)+'</p>'+(recipe.proof ? '<a class="proof-link" href="gallery.html#proof-'+encodeURIComponent(recipe.proof)+'">'+escapeHtml(t('proofLink'))+'</a>' : '')+'</div><div class="boundary"><div class="boundary-item"><small>'+escapeHtml(t('use'))+'</small><p>'+escapeHtml(recipe.useWhen)+'</p></div><div class="boundary-item avoid"><small>'+escapeHtml(t('avoid'))+'</small><p>'+escapeHtml(recipe.avoidWhen)+'</p></div></div></div>';
        html += '<div class="result-grid"><div class="checklist"><div class="mini-heading">'+escapeHtml(t('must'))+'</div><ul>'+recipe.include.map(function (item) { return '<li>'+escapeHtml(item)+'</li>'; }).join('')+'</ul><div class="presentation"><span class="tag">'+escapeHtml(recipe.type)+'</span><span class="tag">'+escapeHtml(recipe.presentation.preset)+'</span><span class="tag">'+escapeHtml(recipe.presentation.motion)+'</span><span class="tag">views '+escapeHtml(recipe.presentation.views)+'</span></div></div>';
        html += '<div class="prompt-box"><div class="prompt-bar"><div class="mini-heading" style="margin:0">'+escapeHtml(t('prompt'))+'</div><button class="copy" id="copy-prompt" type="button">'+escapeHtml(t('copyPrompt'))+'</button></div><p class="prompt-text">'+escapeHtml(recipe.prompt)+'</p></div></div>';
        if (alt.length) html += '<div class="alternatives">'+escapeHtml(t('alternatives'))+alt.map(function (entry) { var item=local(entry.recipe); return '<button type="button" data-alt="'+item.id+'">'+escapeHtml(item.title)+' ['+item.type+']</button>'; }).join('')+'</div>';
        var result = document.getElementById('result');
        result.innerHTML = html;
        result.classList.add('visible');
      }
      function runRecommendation() {
        var query = document.getElementById('scenario').value.trim();
        if (!query) { document.getElementById('scenario').focus(); return; }
        var picked = recommendation(query);
        renderResult(picked.recipe,picked.confidence,picked.alternatives);
      }
      function applyLanguage(next) {
        language = ArchifySiteLanguage.write(next);
        document.documentElement.lang = language === 'zh' ? 'zh-CN' : 'en';
        document.getElementById('language').textContent = language === 'zh' ? 'EN' : '中文';
        document.getElementById('language').setAttribute('aria-label', language === 'zh' ? 'Switch to English' : '切换到中文');
        document.querySelectorAll('[data-en][data-zh]').forEach(function (node) { node.textContent=node.getAttribute(language === 'zh' ? 'data-zh' : 'data-en'); });
        document.querySelectorAll('[data-i18n]').forEach(function (node) { node.textContent=t(node.dataset.i18n); });
        document.querySelectorAll('[data-i18n-html]').forEach(function (node) { node.innerHTML=t(node.dataset.i18nHtml); });
        document.querySelectorAll('[data-i18n-placeholder]').forEach(function (node) { node.placeholder=t(node.dataset.i18nPlaceholder); });
        renderSamples(); renderFilters(); renderCards();
        if (lastRecipe) renderResult(lastRecipe,'selected',[]);
      }
      async function copyPrompt() {
        if (!lastRecipe) return;
        var text = local(lastRecipe).prompt, button = document.getElementById('copy-prompt');
        try { await navigator.clipboard.writeText(text); } catch (_) {
          var area=document.createElement('textarea'); area.value=text; document.body.appendChild(area); area.select(); document.execCommand('copy'); area.remove();
        }
        button.textContent=t('copied'); setTimeout(function () { if (button.isConnected) button.textContent=t('copyPrompt'); },1200);
      }
      document.getElementById('recommend').addEventListener('click',runRecommendation);
      document.getElementById('clear').addEventListener('click',function () { document.getElementById('scenario').value=''; document.getElementById('result').classList.remove('visible'); lastRecipe=null; });
      document.getElementById('language').addEventListener('click',function () { applyLanguage(language === 'en' ? 'zh':'en'); });
      document.getElementById('scenario').addEventListener('keydown',function (event) { if ((event.metaKey || event.ctrlKey) && event.key === 'Enter') runRecommendation(); });
      document.getElementById('samples').addEventListener('click',function (event) { var chip=event.target.closest('[data-query]'); if (!chip) return; document.getElementById('scenario').value=chip.dataset.query; runRecommendation(); });
      document.getElementById('filters').addEventListener('click',function (event) { var filter=event.target.closest('[data-filter]'); if (!filter) return; activeType=filter.dataset.filter; renderFilters(); renderCards(); });
      document.getElementById('cards').addEventListener('click',function (event) { var card=event.target.closest('[data-recipe]'); if (!card) return; var recipe=recipes.find(function (item) { return item.id === card.dataset.recipe; }); renderResult(recipe,'selected',[]); document.getElementById('result').scrollIntoView({behavior:'smooth',block:'center'}); });
      document.getElementById('result').addEventListener('click',function (event) { if (event.target.id === 'copy-prompt') copyPrompt(); var alt=event.target.closest('[data-alt]'); if (alt) renderResult(recipes.find(function (item) { return item.id === alt.dataset.alt; }),'selected',[]); });
      applyLanguage(language);
    }());
  </script>
</body>
</html>