@piagent/platform 1.1.8 → 1.2.0

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 (71) hide show
  1. package/CHANGELOG.md +51 -1
  2. package/README.md +2 -2
  3. package/docs/command-reference-vietnamese.md +13 -4
  4. package/docs/distribution-standard.md +7 -7
  5. package/docs/mcp-and-tools.md +108 -2
  6. package/docs/model-options.md +10 -8
  7. package/docs/operator-manual-vietnamese.md +12 -12
  8. package/docs/publishing-for-teams.md +2 -0
  9. package/docs/quickstart-vietnamese.md +2 -2
  10. package/docs/release-install-policy.md +6 -6
  11. package/docs/security-threat-model.md +1 -1
  12. package/docs/team-onboarding.md +4 -4
  13. package/docs/vercel-docs-site.md +34 -4
  14. package/docs-site/architecture.html +152 -0
  15. package/docs-site/assets/docs.css +1001 -0
  16. package/docs-site/assets/docs.js +84 -0
  17. package/docs-site/commands.html +203 -0
  18. package/docs-site/content/architecture.html +29 -0
  19. package/docs-site/content/commands.html +80 -0
  20. package/docs-site/content/index.html +80 -0
  21. package/docs-site/content/mcp-approval.html +81 -0
  22. package/docs-site/content/mcp-auth.html +76 -0
  23. package/docs-site/content/mcp-servers.html +111 -0
  24. package/docs-site/content/mcp.html +120 -0
  25. package/docs-site/content/permissions.html +54 -0
  26. package/docs-site/content/profiles.html +68 -0
  27. package/docs-site/content/quickstart.html +144 -0
  28. package/docs-site/content/runtime.html +45 -0
  29. package/docs-site/content/scope.html +71 -0
  30. package/docs-site/content/security.html +51 -0
  31. package/docs-site/content/team.html +23 -0
  32. package/docs-site/content/workflows.html +47 -0
  33. package/docs-site/index.html +131 -1534
  34. package/docs-site/mcp-approval.html +204 -0
  35. package/docs-site/mcp-auth.html +199 -0
  36. package/docs-site/mcp-servers.html +234 -0
  37. package/docs-site/mcp.html +243 -0
  38. package/docs-site/permissions.html +177 -0
  39. package/docs-site/profiles.html +191 -0
  40. package/docs-site/quickstart.html +267 -0
  41. package/docs-site/runtime.html +168 -0
  42. package/docs-site/scope.html +194 -0
  43. package/docs-site/security.html +174 -0
  44. package/docs-site/team.html +142 -0
  45. package/docs-site/workflows.html +170 -0
  46. package/package.json +4 -2
  47. package/packages/piagent-core/capabilities/capability-core.js +17 -1
  48. package/packages/piagent-core/extensions/document-intake.ts +5 -5
  49. package/packages/piagent-core/extensions/piagent-guard.ts +319 -4
  50. package/packages/piagent-core/extensions/update-check.js +41 -0
  51. package/packages/piagent-core/mcp/mcp-approval-store.js +175 -0
  52. package/packages/piagent-core/mcp/mcp-auth-readiness.js +197 -0
  53. package/packages/piagent-core/mcp/mcp-command-actions.js +291 -0
  54. package/packages/piagent-core/mcp/mcp-config-layers.js +133 -0
  55. package/packages/piagent-core/mcp/mcp-server-catalog.js +150 -0
  56. package/packages/piagent-core/mcp/mcp-server-entry.js +242 -0
  57. package/packages/piagent-core/mcp/mcp-session-view.js +185 -0
  58. package/packages/piagent-core/package.json +7 -3
  59. package/packages/piagent-core/prompts/model-options.md +8 -8
  60. package/scripts/build-docs-site.mjs +421 -0
  61. package/scripts/configure-model-scope.sh +2 -2
  62. package/scripts/configure-subagents.sh +1 -1
  63. package/scripts/install-global.sh +5 -5
  64. package/scripts/mcp-manage.mjs +567 -0
  65. package/scripts/piagent-cli.mjs +1 -1
  66. package/scripts/preview-docs-site.mjs +88 -0
  67. package/scripts/setup.sh +2 -2
  68. package/scripts/team-doctor.sh +18 -2
  69. package/scripts/verify-local.sh +46 -19
  70. package/scripts/verify-release-identity.mjs +8 -2
  71. package/scripts/configure-mcp.sh +0 -349
@@ -0,0 +1,1001 @@
1
+ :root {
2
+ color-scheme: dark;
3
+ --bg: #050505;
4
+ --bg-soft: #0b0b0d;
5
+ --panel: #101114;
6
+ --panel-strong: #15171b;
7
+ --text: #f4f4ef;
8
+ --muted: #a4a6ad;
9
+ --muted-2: #71747d;
10
+ --line: #24262d;
11
+ --line-soft: #191b20;
12
+ --accent: #d8ff7a;
13
+ --accent-2: #8be9c8;
14
+ --danger: #ff8f8f;
15
+ --warning: #ffd166;
16
+ --ok: #8be9c8;
17
+ --shadow: 0 24px 90px rgba(0, 0, 0, 0.45);
18
+ --radius: 22px;
19
+ --sidebar: 294px;
20
+ --content: 1260px;
21
+ }
22
+
23
+ * {
24
+ box-sizing: border-box;
25
+ }
26
+
27
+ html {
28
+ scroll-behavior: smooth;
29
+ }
30
+
31
+ body {
32
+ margin: 0;
33
+ min-height: 100vh;
34
+ background:
35
+ radial-gradient(circle at 18% -10%, rgba(216, 255, 122, 0.12), transparent 34rem),
36
+ radial-gradient(circle at 88% 8%, rgba(139, 233, 200, 0.1), transparent 30rem),
37
+ linear-gradient(180deg, #050505 0%, #07080a 55%, #050505 100%);
38
+ color: var(--text);
39
+ font-family: "Be Vietnam Pro", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
40
+ line-height: 1.65;
41
+ }
42
+
43
+ a {
44
+ color: inherit;
45
+ text-decoration: none;
46
+ }
47
+
48
+ a:hover {
49
+ color: var(--accent);
50
+ }
51
+
52
+ code,
53
+ pre {
54
+ font-family: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
55
+ }
56
+
57
+ .topbar {
58
+ position: sticky;
59
+ top: 0;
60
+ z-index: 30;
61
+ display: flex;
62
+ align-items: center;
63
+ justify-content: space-between;
64
+ height: 62px;
65
+ padding: 0 28px;
66
+ border-bottom: 1px solid rgba(255, 255, 255, 0.08);
67
+ background: rgba(5, 5, 5, 0.78);
68
+ backdrop-filter: blur(20px);
69
+ }
70
+
71
+ .brand {
72
+ display: inline-flex;
73
+ align-items: center;
74
+ gap: 12px;
75
+ min-width: 0;
76
+ font-weight: 700;
77
+ letter-spacing: -0.03em;
78
+ }
79
+
80
+ .brand-mark {
81
+ display: grid;
82
+ place-items: center;
83
+ width: 34px;
84
+ height: 34px;
85
+ border: 1px solid rgba(216, 255, 122, 0.32);
86
+ border-radius: 11px;
87
+ background:
88
+ linear-gradient(135deg, rgba(216, 255, 122, 0.12), transparent),
89
+ #0d0f12;
90
+ color: var(--accent);
91
+ font-family: "JetBrains Mono", monospace;
92
+ font-size: 13px;
93
+ overflow: hidden;
94
+ box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.04);
95
+ }
96
+
97
+ .brand-mark img {
98
+ display: block;
99
+ width: 100%;
100
+ height: 100%;
101
+ }
102
+
103
+ .brand span:last-child {
104
+ overflow: hidden;
105
+ text-overflow: ellipsis;
106
+ white-space: nowrap;
107
+ }
108
+
109
+ .top-actions {
110
+ display: flex;
111
+ align-items: center;
112
+ gap: 10px;
113
+ }
114
+
115
+ .pill {
116
+ display: inline-flex;
117
+ align-items: center;
118
+ gap: 8px;
119
+ min-height: 34px;
120
+ padding: 6px 12px;
121
+ border: 1px solid rgba(255, 255, 255, 0.1);
122
+ border-radius: 999px;
123
+ background: rgba(255, 255, 255, 0.035);
124
+ color: var(--muted);
125
+ font-size: 12px;
126
+ font-weight: 600;
127
+ }
128
+
129
+ .pill-dot {
130
+ width: 7px;
131
+ height: 7px;
132
+ border-radius: 999px;
133
+ background: var(--ok);
134
+ box-shadow: 0 0 18px rgba(139, 233, 200, 0.6);
135
+ }
136
+
137
+ .layout {
138
+ display: grid;
139
+ grid-template-columns: var(--sidebar) minmax(0, 1fr);
140
+ gap: 0;
141
+ width: 100%;
142
+ }
143
+
144
+ .sidebar {
145
+ position: sticky;
146
+ top: 62px;
147
+ align-self: start;
148
+ height: calc(100vh - 62px);
149
+ padding: 28px 22px 28px 28px;
150
+ overflow-y: auto;
151
+ border-right: 1px solid rgba(255, 255, 255, 0.08);
152
+ background: linear-gradient(180deg, rgba(255, 255, 255, 0.025), rgba(255, 255, 255, 0));
153
+ }
154
+
155
+ .sidebar-search {
156
+ position: relative;
157
+ margin-bottom: 26px;
158
+ }
159
+
160
+ .sidebar-search input {
161
+ width: 100%;
162
+ height: 42px;
163
+ padding: 0 14px 0 38px;
164
+ border: 1px solid var(--line);
165
+ border-radius: 14px;
166
+ outline: none;
167
+ background: rgba(255, 255, 255, 0.04);
168
+ color: var(--text);
169
+ font: inherit;
170
+ font-size: 13px;
171
+ }
172
+
173
+ .sidebar-search input:focus {
174
+ border-color: rgba(216, 255, 122, 0.5);
175
+ box-shadow: 0 0 0 4px rgba(216, 255, 122, 0.08);
176
+ }
177
+
178
+ .sidebar-search svg {
179
+ position: absolute;
180
+ left: 13px;
181
+ top: 50%;
182
+ width: 15px;
183
+ height: 15px;
184
+ color: var(--muted-2);
185
+ transform: translateY(-50%);
186
+ }
187
+
188
+ .nav-group {
189
+ margin: 0 0 22px;
190
+ }
191
+
192
+ .nav-title {
193
+ margin: 0 0 9px;
194
+ color: var(--muted-2);
195
+ font-size: 11px;
196
+ font-weight: 700;
197
+ letter-spacing: 0.11em;
198
+ text-transform: uppercase;
199
+ }
200
+
201
+ .nav-link {
202
+ display: flex;
203
+ align-items: center;
204
+ min-height: 34px;
205
+ padding: 7px 10px;
206
+ border-radius: 11px;
207
+ color: var(--muted);
208
+ font-size: 13px;
209
+ font-weight: 500;
210
+ transition: background 160ms ease, color 160ms ease, transform 160ms ease;
211
+ }
212
+
213
+ .nav-link:hover,
214
+ .nav-link.active {
215
+ background: rgba(255, 255, 255, 0.06);
216
+ color: var(--text);
217
+ }
218
+
219
+ .nav-link.active {
220
+ box-shadow: inset 2px 0 0 var(--accent);
221
+ }
222
+
223
+ main {
224
+ min-width: 0;
225
+ display: flex;
226
+ justify-content: center;
227
+ }
228
+
229
+ .content-shell {
230
+ width: min(100%, var(--content));
231
+ padding: 58px 56px 96px;
232
+ }
233
+
234
+ .hero {
235
+ position: relative;
236
+ overflow: hidden;
237
+ padding: 42px;
238
+ border: 1px solid rgba(255, 255, 255, 0.1);
239
+ border-radius: 30px;
240
+ background:
241
+ linear-gradient(135deg, rgba(216, 255, 122, 0.13), transparent 38%),
242
+ linear-gradient(180deg, rgba(255, 255, 255, 0.055), rgba(255, 255, 255, 0.018)),
243
+ var(--panel);
244
+ box-shadow: var(--shadow);
245
+ }
246
+
247
+ .hero::after {
248
+ content: "";
249
+ position: absolute;
250
+ inset: auto -18% -58% 32%;
251
+ height: 280px;
252
+ border-radius: 50%;
253
+ background: radial-gradient(circle, rgba(139, 233, 200, 0.16), transparent 64%);
254
+ pointer-events: none;
255
+ }
256
+
257
+ .eyebrow {
258
+ display: inline-flex;
259
+ align-items: center;
260
+ gap: 9px;
261
+ margin: 0 0 18px;
262
+ color: var(--accent);
263
+ font-size: 12px;
264
+ font-weight: 700;
265
+ letter-spacing: 0.12em;
266
+ text-transform: uppercase;
267
+ }
268
+
269
+ .eyebrow::before {
270
+ content: "";
271
+ width: 8px;
272
+ height: 8px;
273
+ border-radius: 999px;
274
+ background: var(--accent);
275
+ box-shadow: 0 0 24px rgba(216, 255, 122, 0.8);
276
+ }
277
+
278
+ h1,
279
+ h2,
280
+ h3 {
281
+ margin: 0;
282
+ line-height: 1.12;
283
+ letter-spacing: -0.055em;
284
+ }
285
+
286
+ h1 {
287
+ max-width: 860px;
288
+ font-size: clamp(42px, 8vw, 82px);
289
+ font-weight: 800;
290
+ }
291
+
292
+ h2 {
293
+ font-size: clamp(30px, 4vw, 48px);
294
+ font-weight: 800;
295
+ }
296
+
297
+ h3 {
298
+ font-size: 20px;
299
+ font-weight: 700;
300
+ letter-spacing: -0.035em;
301
+ }
302
+
303
+ p {
304
+ margin: 0;
305
+ color: var(--muted);
306
+ }
307
+
308
+ .hero p {
309
+ position: relative;
310
+ z-index: 1;
311
+ max-width: 760px;
312
+ margin-top: 20px;
313
+ color: #d6d7dc;
314
+ font-size: 17px;
315
+ }
316
+
317
+ .hero-actions {
318
+ position: relative;
319
+ z-index: 1;
320
+ display: flex;
321
+ flex-wrap: wrap;
322
+ gap: 12px;
323
+ margin-top: 28px;
324
+ }
325
+
326
+ .button {
327
+ display: inline-flex;
328
+ align-items: center;
329
+ justify-content: center;
330
+ gap: 9px;
331
+ min-height: 42px;
332
+ padding: 10px 16px;
333
+ border: 1px solid rgba(255, 255, 255, 0.12);
334
+ border-radius: 999px;
335
+ background: rgba(255, 255, 255, 0.055);
336
+ color: var(--text);
337
+ font-size: 13px;
338
+ font-weight: 700;
339
+ cursor: pointer;
340
+ transition: background 160ms ease, border-color 160ms ease, color 160ms ease;
341
+ }
342
+
343
+ .button:hover,
344
+ .button:focus-visible {
345
+ border-color: rgba(216, 255, 122, 0.45);
346
+ background: rgba(216, 255, 122, 0.1);
347
+ color: var(--accent);
348
+ }
349
+
350
+ .button.primary {
351
+ border-color: transparent;
352
+ background: var(--accent);
353
+ color: #111300;
354
+ }
355
+
356
+ .button.primary:hover,
357
+ .button.primary:focus-visible {
358
+ background: #e5ff98;
359
+ color: #111300;
360
+ }
361
+
362
+ .button.social {
363
+ min-height: 34px;
364
+ padding: 7px 12px;
365
+ color: #d6d7dc;
366
+ }
367
+
368
+ .button.social svg {
369
+ width: 14px;
370
+ height: 14px;
371
+ }
372
+
373
+ .owner-strip {
374
+ position: relative;
375
+ z-index: 1;
376
+ display: flex;
377
+ flex-wrap: wrap;
378
+ align-items: center;
379
+ gap: 10px;
380
+ margin-top: 18px;
381
+ }
382
+
383
+ .owner-label {
384
+ color: var(--muted-2);
385
+ font-size: 12px;
386
+ font-weight: 800;
387
+ letter-spacing: 0.12em;
388
+ text-transform: uppercase;
389
+ }
390
+
391
+ .owner-strip a {
392
+ display: inline-flex;
393
+ align-items: center;
394
+ gap: 7px;
395
+ padding: 7px 11px;
396
+ border: 1px solid rgba(255, 255, 255, 0.1);
397
+ border-radius: 999px;
398
+ background: rgba(255, 255, 255, 0.04);
399
+ color: #d6d7dc;
400
+ font-size: 12px;
401
+ font-weight: 700;
402
+ }
403
+
404
+ .owner-strip a:hover,
405
+ .owner-strip a:focus-visible {
406
+ border-color: rgba(216, 255, 122, 0.42);
407
+ color: var(--accent);
408
+ }
409
+
410
+ .section {
411
+ padding-top: 86px;
412
+ scroll-margin-top: 86px;
413
+ }
414
+
415
+ .section-kicker {
416
+ margin-bottom: 12px;
417
+ color: var(--accent-2);
418
+ font-size: 12px;
419
+ font-weight: 800;
420
+ letter-spacing: 0.12em;
421
+ text-transform: uppercase;
422
+ }
423
+
424
+ .section-lead {
425
+ max-width: 820px;
426
+ margin-top: 18px;
427
+ font-size: 16px;
428
+ }
429
+
430
+ .grid {
431
+ display: grid;
432
+ gap: 16px;
433
+ margin-top: 28px;
434
+ }
435
+
436
+ .grid.cols-2 {
437
+ grid-template-columns: repeat(2, minmax(0, 1fr));
438
+ }
439
+
440
+ .grid.cols-3 {
441
+ grid-template-columns: repeat(3, minmax(0, 1fr));
442
+ }
443
+
444
+ .card {
445
+ padding: 22px;
446
+ border: 1px solid rgba(255, 255, 255, 0.1);
447
+ border-radius: var(--radius);
448
+ background: linear-gradient(180deg, rgba(255, 255, 255, 0.045), rgba(255, 255, 255, 0.018));
449
+ }
450
+
451
+ .card strong {
452
+ color: var(--text);
453
+ }
454
+
455
+ .card p {
456
+ margin-top: 10px;
457
+ font-size: 14px;
458
+ }
459
+
460
+ .steps {
461
+ display: grid;
462
+ gap: 14px;
463
+ margin-top: 28px;
464
+ counter-reset: steps;
465
+ }
466
+
467
+ .step {
468
+ counter-increment: steps;
469
+ display: grid;
470
+ grid-template-columns: 44px minmax(0, 1fr);
471
+ gap: 16px;
472
+ padding: 20px;
473
+ border: 1px solid rgba(255, 255, 255, 0.1);
474
+ border-radius: var(--radius);
475
+ background: rgba(255, 255, 255, 0.028);
476
+ }
477
+
478
+ .step::before {
479
+ content: counter(steps, decimal-leading-zero);
480
+ display: grid;
481
+ place-items: center;
482
+ width: 42px;
483
+ height: 42px;
484
+ border-radius: 14px;
485
+ background: rgba(216, 255, 122, 0.12);
486
+ color: var(--accent);
487
+ font-family: "JetBrains Mono", monospace;
488
+ font-size: 13px;
489
+ font-weight: 800;
490
+ }
491
+
492
+ .step p {
493
+ margin-top: 8px;
494
+ font-size: 14px;
495
+ }
496
+
497
+ /* One card per row. Half the content width holds about 45 characters, which is
498
+ shorter than most of the commands these cards exist to show — the rest ran
499
+ off the edge behind a scrollbar. Wrapping them instead is no better here,
500
+ because a wrapped line and a second command look alike. */
501
+ .command-grid {
502
+ display: grid;
503
+ grid-template-columns: minmax(0, 1fr);
504
+ gap: 14px;
505
+ margin-top: 28px;
506
+ }
507
+
508
+ .command-card {
509
+ overflow: hidden;
510
+ border: 1px solid rgba(255, 255, 255, 0.1);
511
+ border-radius: var(--radius);
512
+ background: #08090b;
513
+ }
514
+
515
+ .command-card header {
516
+ display: flex;
517
+ align-items: center;
518
+ justify-content: space-between;
519
+ gap: 16px;
520
+ padding: 14px 16px;
521
+ border-bottom: 1px solid var(--line-soft);
522
+ background: rgba(255, 255, 255, 0.025);
523
+ }
524
+
525
+ .command-card header span {
526
+ color: var(--text);
527
+ font-size: 13px;
528
+ font-weight: 700;
529
+ }
530
+
531
+ /* The card carries no padding of its own — `header` and `pre` bring theirs. A
532
+ heading or paragraph placed directly in the card would otherwise sit on the
533
+ border, where the rounded corner clips its first letter. */
534
+ .command-card > h3,
535
+ .command-card > p {
536
+ padding: 0 16px;
537
+ }
538
+
539
+ .command-card > h3 {
540
+ padding-top: 16px;
541
+ }
542
+
543
+ .command-card > h3 + p {
544
+ margin-top: 8px;
545
+ }
546
+
547
+ .command-card > p:last-child {
548
+ padding-bottom: 16px;
549
+ }
550
+
551
+ .command-card > p + pre {
552
+ margin-top: 14px;
553
+ }
554
+
555
+ .clip-btn {
556
+ min-width: 74px;
557
+ border: 1px solid rgba(255, 255, 255, 0.1);
558
+ border-radius: 999px;
559
+ background: rgba(255, 255, 255, 0.05);
560
+ color: var(--muted);
561
+ font: inherit;
562
+ font-size: 12px;
563
+ font-weight: 700;
564
+ cursor: pointer;
565
+ padding: 6px 10px;
566
+ }
567
+
568
+ .clip-btn:hover,
569
+ .clip-btn:focus-visible {
570
+ color: var(--accent);
571
+ border-color: rgba(216, 255, 122, 0.45);
572
+ }
573
+
574
+ pre {
575
+ margin: 0;
576
+ padding: 16px;
577
+ overflow-x: auto;
578
+ color: #e9e9e3;
579
+ font-size: 13px;
580
+ line-height: 1.65;
581
+ }
582
+
583
+ code {
584
+ color: #f5f5f0;
585
+ }
586
+
587
+ .inline-code {
588
+ padding: 2px 6px;
589
+ border: 1px solid rgba(255, 255, 255, 0.1);
590
+ border-radius: 7px;
591
+ background: rgba(255, 255, 255, 0.05);
592
+ color: var(--accent-2);
593
+ font-family: "JetBrains Mono", monospace;
594
+ font-size: 0.91em;
595
+ }
596
+
597
+ .table-wrap {
598
+ margin-top: 28px;
599
+ overflow: hidden;
600
+ border: 1px solid rgba(255, 255, 255, 0.1);
601
+ border-radius: var(--radius);
602
+ }
603
+
604
+ table {
605
+ width: 100%;
606
+ border-collapse: collapse;
607
+ background: rgba(255, 255, 255, 0.02);
608
+ }
609
+
610
+ th,
611
+ td {
612
+ padding: 16px;
613
+ border-bottom: 1px solid var(--line-soft);
614
+ text-align: left;
615
+ vertical-align: top;
616
+ font-size: 14px;
617
+ }
618
+
619
+ th {
620
+ color: var(--text);
621
+ font-size: 12px;
622
+ letter-spacing: 0.09em;
623
+ text-transform: uppercase;
624
+ }
625
+
626
+ td {
627
+ color: var(--muted);
628
+ }
629
+
630
+ tr:last-child td {
631
+ border-bottom: 0;
632
+ }
633
+
634
+ .tag-list {
635
+ display: flex;
636
+ flex-wrap: wrap;
637
+ gap: 8px;
638
+ margin-top: 16px;
639
+ }
640
+
641
+ .tag {
642
+ padding: 6px 10px;
643
+ border: 1px solid rgba(255, 255, 255, 0.1);
644
+ border-radius: 999px;
645
+ color: var(--muted);
646
+ font-family: "JetBrains Mono", monospace;
647
+ font-size: 12px;
648
+ }
649
+
650
+ .callout {
651
+ margin-top: 28px;
652
+ padding: 20px;
653
+ border: 1px solid rgba(255, 209, 102, 0.26);
654
+ border-radius: var(--radius);
655
+ background: rgba(255, 209, 102, 0.07);
656
+ }
657
+
658
+ .callout strong {
659
+ color: var(--warning);
660
+ }
661
+
662
+ .callout p {
663
+ margin-top: 8px;
664
+ }
665
+
666
+ .callout ul {
667
+ margin: 12px 0 0;
668
+ padding-left: 20px;
669
+ color: var(--muted);
670
+ }
671
+
672
+ .ok-callout {
673
+ border-color: rgba(139, 233, 200, 0.22);
674
+ background: rgba(139, 233, 200, 0.065);
675
+ }
676
+
677
+ .ok-callout strong {
678
+ color: var(--ok);
679
+ }
680
+
681
+ .split {
682
+ display: grid;
683
+ grid-template-columns: 1fr 1fr;
684
+ gap: 16px;
685
+ margin-top: 28px;
686
+ }
687
+
688
+ .footer {
689
+ margin-top: 90px;
690
+ padding-top: 28px;
691
+ border-top: 1px solid rgba(255, 255, 255, 0.1);
692
+ color: var(--muted-2);
693
+ font-size: 13px;
694
+ }
695
+
696
+ .footer-links {
697
+ display: flex;
698
+ flex-wrap: wrap;
699
+ gap: 12px;
700
+ margin-top: 14px;
701
+ }
702
+
703
+ .footer-links a {
704
+ color: var(--muted);
705
+ font-weight: 700;
706
+ }
707
+
708
+ .footer-links a:hover,
709
+ .footer-links a:focus-visible {
710
+ color: var(--accent);
711
+ }
712
+
713
+ .mobile-menu {
714
+ display: none;
715
+ }
716
+
717
+ @media (max-width: 1020px) {
718
+ .layout {
719
+ grid-template-columns: 1fr;
720
+ }
721
+
722
+ .sidebar {
723
+ position: fixed;
724
+ inset: 62px 0 auto;
725
+ z-index: 25;
726
+ display: none;
727
+ height: calc(100vh - 62px);
728
+ padding: 22px;
729
+ background: rgba(5, 5, 5, 0.96);
730
+ }
731
+
732
+ .sidebar.open {
733
+ display: block;
734
+ }
735
+
736
+ .mobile-menu {
737
+ display: inline-flex;
738
+ }
739
+
740
+ .content-shell {
741
+ width: min(100%, 980px);
742
+ padding: 38px 22px 76px;
743
+ }
744
+
745
+ .hero {
746
+ padding: 30px;
747
+ }
748
+ }
749
+
750
+ @media (max-width: 760px) {
751
+ .topbar {
752
+ padding: 0 16px;
753
+ }
754
+
755
+ .top-actions .pill {
756
+ display: none;
757
+ }
758
+
759
+ .button.social {
760
+ display: none;
761
+ }
762
+
763
+ .grid.cols-2,
764
+ .grid.cols-3,
765
+ .split {
766
+ grid-template-columns: 1fr;
767
+ }
768
+
769
+ th,
770
+ td {
771
+ display: block;
772
+ width: 100%;
773
+ }
774
+
775
+ th {
776
+ border-bottom: 0;
777
+ padding-bottom: 4px;
778
+ }
779
+
780
+ td {
781
+ padding-top: 4px;
782
+ }
783
+ }
784
+
785
+ @media (prefers-reduced-motion: reduce) {
786
+ html {
787
+ scroll-behavior: auto;
788
+ }
789
+
790
+ *,
791
+ *::before,
792
+ *::after {
793
+ transition: none !important;
794
+ }
795
+ }
796
+
797
+ /* ---------------------------------------------------------------------------
798
+ Multi-page shell
799
+ The single-page site had one column of prose under a sidebar. A page per topic
800
+ needs three things it did not: a place to say where you are, a map of the page
801
+ you are on, and a way to the next page without going back to the sidebar.
802
+ --------------------------------------------------------------------------- */
803
+
804
+ .layout.with-toc {
805
+ grid-template-columns: var(--sidebar) minmax(0, 1fr) 232px;
806
+ }
807
+
808
+ .toc {
809
+ position: sticky;
810
+ top: 62px;
811
+ align-self: start;
812
+ max-height: calc(100vh - 62px);
813
+ overflow-y: auto;
814
+ padding: 58px 26px 60px 8px;
815
+ border-left: 1px solid var(--line-soft);
816
+ }
817
+
818
+ .toc-title {
819
+ margin: 0 0 12px;
820
+ font-size: 11px;
821
+ letter-spacing: 0.16em;
822
+ text-transform: uppercase;
823
+ color: var(--muted-2);
824
+ }
825
+
826
+ .toc a {
827
+ display: block;
828
+ padding: 5px 0 5px 12px;
829
+ border-left: 2px solid transparent;
830
+ color: var(--muted);
831
+ font-size: 13px;
832
+ line-height: 1.45;
833
+ text-decoration: none;
834
+ transition: color 0.15s ease, border-color 0.15s ease;
835
+ }
836
+
837
+ .toc a:hover {
838
+ color: var(--text);
839
+ }
840
+
841
+ .toc a.active {
842
+ color: var(--accent);
843
+ border-left-color: var(--accent);
844
+ }
845
+
846
+ .toc a.toc-h3 {
847
+ padding-left: 24px;
848
+ font-size: 12.5px;
849
+ }
850
+
851
+ .breadcrumb {
852
+ display: flex;
853
+ flex-wrap: wrap;
854
+ align-items: center;
855
+ gap: 8px;
856
+ margin-bottom: 18px;
857
+ font-size: 12.5px;
858
+ color: var(--muted-2);
859
+ }
860
+
861
+ .breadcrumb a {
862
+ color: var(--muted);
863
+ text-decoration: none;
864
+ }
865
+
866
+ .breadcrumb a:hover {
867
+ color: var(--text);
868
+ }
869
+
870
+ .breadcrumb span[aria-hidden] {
871
+ color: var(--line);
872
+ }
873
+
874
+ .page-head {
875
+ margin-bottom: 34px;
876
+ }
877
+
878
+ .page-head h1 {
879
+ margin: 0 0 12px;
880
+ font-size: clamp(30px, 3.4vw, 42px);
881
+ line-height: 1.12;
882
+ letter-spacing: -0.02em;
883
+ }
884
+
885
+ .page-head p {
886
+ margin: 0;
887
+ max-width: 62ch;
888
+ color: var(--muted);
889
+ font-size: 16px;
890
+ line-height: 1.6;
891
+ }
892
+
893
+ .pager {
894
+ display: grid;
895
+ grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
896
+ gap: 14px;
897
+ margin-top: 56px;
898
+ padding-top: 30px;
899
+ border-top: 1px solid var(--line-soft);
900
+ }
901
+
902
+ .pager a {
903
+ display: flex;
904
+ flex-direction: column;
905
+ gap: 5px;
906
+ padding: 16px 18px;
907
+ border: 1px solid var(--line);
908
+ border-radius: 14px;
909
+ background: var(--panel);
910
+ color: var(--text);
911
+ text-decoration: none;
912
+ transition: border-color 0.15s ease, transform 0.15s ease;
913
+ }
914
+
915
+ .pager a:hover {
916
+ border-color: var(--accent);
917
+ transform: translateY(-1px);
918
+ }
919
+
920
+ .pager .pager-next {
921
+ text-align: right;
922
+ grid-column: -2;
923
+ }
924
+
925
+ .pager-label {
926
+ font-size: 11px;
927
+ letter-spacing: 0.14em;
928
+ text-transform: uppercase;
929
+ color: var(--muted-2);
930
+ }
931
+
932
+ .pager-title {
933
+ font-weight: 600;
934
+ font-size: 15px;
935
+ }
936
+
937
+ /* Landing-page card grid: the entry points, as cards rather than a wall of prose. */
938
+ .card-grid {
939
+ display: grid;
940
+ grid-template-columns: repeat(auto-fit, minmax(248px, 1fr));
941
+ gap: 14px;
942
+ }
943
+
944
+ .doc-card {
945
+ display: flex;
946
+ flex-direction: column;
947
+ gap: 8px;
948
+ padding: 22px;
949
+ border: 1px solid var(--line);
950
+ border-radius: 16px;
951
+ background: var(--panel);
952
+ color: inherit;
953
+ text-decoration: none;
954
+ transition: border-color 0.15s ease, transform 0.15s ease;
955
+ }
956
+
957
+ .doc-card:hover {
958
+ border-color: var(--accent);
959
+ transform: translateY(-2px);
960
+ }
961
+
962
+ .doc-card h3 {
963
+ margin: 0;
964
+ font-size: 16px;
965
+ }
966
+
967
+ .doc-card p {
968
+ margin: 0;
969
+ color: var(--muted);
970
+ font-size: 14px;
971
+ line-height: 1.55;
972
+ }
973
+
974
+ .doc-card .card-kicker {
975
+ font-size: 11px;
976
+ letter-spacing: 0.14em;
977
+ text-transform: uppercase;
978
+ color: var(--accent);
979
+ }
980
+
981
+ /* An anchor target under a sticky header lands with its heading hidden. */
982
+ .section[id],
983
+ h2[id],
984
+ h3[id] {
985
+ scroll-margin-top: 84px;
986
+ }
987
+
988
+ .nav-link.current {
989
+ color: var(--accent);
990
+ background: var(--panel-strong);
991
+ }
992
+
993
+ @media (max-width: 1180px) {
994
+ .layout.with-toc {
995
+ grid-template-columns: var(--sidebar) minmax(0, 1fr);
996
+ }
997
+
998
+ .toc {
999
+ display: none;
1000
+ }
1001
+ }