@cyanheads/mcp-ts-core 0.6.8 → 0.6.9

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 (77) hide show
  1. package/CLAUDE.md +1 -1
  2. package/README.md +1 -1
  3. package/changelog/0.6.x/0.6.9.md +21 -0
  4. package/dist/core/serverManifest.d.ts +12 -0
  5. package/dist/core/serverManifest.d.ts.map +1 -1
  6. package/dist/core/serverManifest.js +25 -0
  7. package/dist/core/serverManifest.js.map +1 -1
  8. package/dist/linter/rules/landing-rules.d.ts.map +1 -1
  9. package/dist/linter/rules/landing-rules.js +1 -20
  10. package/dist/linter/rules/landing-rules.js.map +1 -1
  11. package/dist/mcp-server/transports/http/httpTransport.js +1 -1
  12. package/dist/mcp-server/transports/http/httpTransport.js.map +1 -1
  13. package/dist/mcp-server/transports/http/landing-page/assets/copy-script.d.ts +11 -0
  14. package/dist/mcp-server/transports/http/landing-page/assets/copy-script.d.ts.map +1 -0
  15. package/dist/mcp-server/transports/http/landing-page/assets/copy-script.js +36 -0
  16. package/dist/mcp-server/transports/http/landing-page/assets/copy-script.js.map +1 -0
  17. package/dist/mcp-server/transports/http/landing-page/assets/styles.d.ts +21 -0
  18. package/dist/mcp-server/transports/http/landing-page/assets/styles.d.ts.map +1 -0
  19. package/dist/mcp-server/transports/http/landing-page/assets/styles.js +921 -0
  20. package/dist/mcp-server/transports/http/landing-page/assets/styles.js.map +1 -0
  21. package/dist/mcp-server/transports/http/landing-page/handler.d.ts +32 -0
  22. package/dist/mcp-server/transports/http/landing-page/handler.d.ts.map +1 -0
  23. package/dist/mcp-server/transports/http/landing-page/handler.js +92 -0
  24. package/dist/mcp-server/transports/http/landing-page/handler.js.map +1 -0
  25. package/dist/mcp-server/transports/http/landing-page/index.d.ts +27 -0
  26. package/dist/mcp-server/transports/http/landing-page/index.d.ts.map +1 -0
  27. package/dist/mcp-server/transports/http/landing-page/index.js +27 -0
  28. package/dist/mcp-server/transports/http/landing-page/index.js.map +1 -0
  29. package/dist/mcp-server/transports/http/landing-page/primitives.d.ts +19 -0
  30. package/dist/mcp-server/transports/http/landing-page/primitives.d.ts.map +1 -0
  31. package/dist/mcp-server/transports/http/landing-page/primitives.js +38 -0
  32. package/dist/mcp-server/transports/http/landing-page/primitives.js.map +1 -0
  33. package/dist/mcp-server/transports/http/landing-page/render.d.ts +16 -0
  34. package/dist/mcp-server/transports/http/landing-page/render.d.ts.map +1 -0
  35. package/dist/mcp-server/transports/http/landing-page/render.js +57 -0
  36. package/dist/mcp-server/transports/http/landing-page/render.js.map +1 -0
  37. package/dist/mcp-server/transports/http/landing-page/sections/connect.d.ts +19 -0
  38. package/dist/mcp-server/transports/http/landing-page/sections/connect.d.ts.map +1 -0
  39. package/dist/mcp-server/transports/http/landing-page/sections/connect.js +130 -0
  40. package/dist/mcp-server/transports/http/landing-page/sections/connect.js.map +1 -0
  41. package/dist/mcp-server/transports/http/landing-page/sections/extensions.d.ts +10 -0
  42. package/dist/mcp-server/transports/http/landing-page/sections/extensions.d.ts.map +1 -0
  43. package/dist/mcp-server/transports/http/landing-page/sections/extensions.js +30 -0
  44. package/dist/mcp-server/transports/http/landing-page/sections/extensions.js.map +1 -0
  45. package/dist/mcp-server/transports/http/landing-page/sections/footer.d.ts +12 -0
  46. package/dist/mcp-server/transports/http/landing-page/sections/footer.d.ts.map +1 -0
  47. package/dist/mcp-server/transports/http/landing-page/sections/footer.js +49 -0
  48. package/dist/mcp-server/transports/http/landing-page/sections/footer.js.map +1 -0
  49. package/dist/mcp-server/transports/http/landing-page/sections/head.d.ts +11 -0
  50. package/dist/mcp-server/transports/http/landing-page/sections/head.d.ts.map +1 -0
  51. package/dist/mcp-server/transports/http/landing-page/sections/head.js +68 -0
  52. package/dist/mcp-server/transports/http/landing-page/sections/head.js.map +1 -0
  53. package/dist/mcp-server/transports/http/landing-page/sections/hero.d.ts +12 -0
  54. package/dist/mcp-server/transports/http/landing-page/sections/hero.d.ts.map +1 -0
  55. package/dist/mcp-server/transports/http/landing-page/sections/hero.js +48 -0
  56. package/dist/mcp-server/transports/http/landing-page/sections/hero.js.map +1 -0
  57. package/dist/mcp-server/transports/http/landing-page/sections/prompts.d.ts +11 -0
  58. package/dist/mcp-server/transports/http/landing-page/sections/prompts.d.ts.map +1 -0
  59. package/dist/mcp-server/transports/http/landing-page/sections/prompts.js +48 -0
  60. package/dist/mcp-server/transports/http/landing-page/sections/prompts.js.map +1 -0
  61. package/dist/mcp-server/transports/http/landing-page/sections/resources.d.ts +10 -0
  62. package/dist/mcp-server/transports/http/landing-page/sections/resources.d.ts.map +1 -0
  63. package/dist/mcp-server/transports/http/landing-page/sections/resources.js +44 -0
  64. package/dist/mcp-server/transports/http/landing-page/sections/resources.js.map +1 -0
  65. package/dist/mcp-server/transports/http/landing-page/sections/status-strip.d.ts +18 -0
  66. package/dist/mcp-server/transports/http/landing-page/sections/status-strip.d.ts.map +1 -0
  67. package/dist/mcp-server/transports/http/landing-page/sections/status-strip.js +71 -0
  68. package/dist/mcp-server/transports/http/landing-page/sections/status-strip.js.map +1 -0
  69. package/dist/mcp-server/transports/http/landing-page/sections/tools.d.ts +13 -0
  70. package/dist/mcp-server/transports/http/landing-page/sections/tools.d.ts.map +1 -0
  71. package/dist/mcp-server/transports/http/landing-page/sections/tools.js +130 -0
  72. package/dist/mcp-server/transports/http/landing-page/sections/tools.js.map +1 -0
  73. package/package.json +1 -1
  74. package/dist/mcp-server/transports/http/landing-page.d.ts +0 -48
  75. package/dist/mcp-server/transports/http/landing-page.d.ts.map +0 -1
  76. package/dist/mcp-server/transports/http/landing-page.js +0 -1621
  77. package/dist/mcp-server/transports/http/landing-page.js.map +0 -1
@@ -0,0 +1,921 @@
1
+ /**
2
+ * @fileoverview Inlined `<style>` block for the landing page. Defines design
3
+ * tokens, `prefers-color-scheme`-aware color system, hero/connect/card/section
4
+ * component styles, and responsive + reduced-motion overrides. The only
5
+ * interpolation is the accent color, which the caller supplies from the
6
+ * server manifest theme.
7
+ *
8
+ * @module src/mcp-server/transports/http/landing-page/assets/styles
9
+ */
10
+ import { isSafeCssColor } from '../../../../../core/serverManifest.js';
11
+ import { unsafeRaw } from '../../../../../utils/formatting/html.js';
12
+ /** Fallback when the caller-supplied accent fails the CSS-safety check. */
13
+ const DEFAULT_ACCENT = '#6366f1';
14
+ /**
15
+ * Single inlined `<style>` block. No external CSS, no fonts.
16
+ *
17
+ * `buildServerManifest` is the primary defense against CSS injection through
18
+ * `accent` — it throws on malformed values at startup. This function adds a
19
+ * second line of defense for callers that construct a manifest directly
20
+ * (tests, programmatic use): anything that fails the CSS-safety check is
21
+ * silently replaced with the default indigo.
22
+ */
23
+ export function renderTokens(accent) {
24
+ const safeAccent = isSafeCssColor(accent) ? accent : DEFAULT_ACCENT;
25
+ const css = `
26
+ :root {
27
+ --space-1: 4px; --space-2: 8px; --space-3: 12px; --space-4: 16px;
28
+ --space-5: 20px; --space-6: 24px; --space-8: 32px; --space-10: 40px;
29
+ --space-12: 48px; --space-16: 64px; --space-20: 80px;
30
+
31
+ --text-xs: 0.75rem; --text-sm: 0.875rem; --text-base: 1rem;
32
+ --text-lg: 1.125rem; --text-xl: 1.25rem; --text-2xl: 1.5rem;
33
+ --text-3xl: 1.875rem;
34
+ --text-display: clamp(2rem, 4.5vw + 0.5rem, 3.5rem);
35
+
36
+ --radius-xs: 4px; --radius-sm: 6px; --radius-md: 10px;
37
+ --radius-lg: 14px; --radius-pill: 999px;
38
+
39
+ --font-sans: -apple-system, BlinkMacSystemFont, "Inter", "Segoe UI", "Helvetica Neue", Helvetica, Arial, sans-serif;
40
+ --font-mono: ui-monospace, "JetBrains Mono", SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
41
+
42
+ --duration-fast: 120ms; --duration-base: 200ms; --duration-slow: 320ms;
43
+ --ease-out: cubic-bezier(0.2, 0.8, 0.2, 1);
44
+
45
+ --accent: ${safeAccent};
46
+ --accent-hover: color-mix(in oklab, ${safeAccent}, black 10%);
47
+ --accent-edge: color-mix(in oklab, ${safeAccent}, transparent 65%);
48
+ --accent-soft: color-mix(in oklab, ${safeAccent}, transparent 82%);
49
+ --accent-softer: color-mix(in oklab, ${safeAccent}, transparent 92%);
50
+ /* Secondary accent — hue-shifted companion for richer gradients. */
51
+ /* Fallback (lighter tonal variant) first; modern relative-color value overrides on supported engines. */
52
+ --accent-2: color-mix(in oklab, var(--accent), white 30%);
53
+ --accent-2: oklch(from var(--accent) l c calc(h + 30));
54
+ --accent-glow: color-mix(in oklab, var(--accent), transparent 72%);
55
+
56
+ /* Warn palette — amber. Pre-release chip today; reusable for future warning surfaces. */
57
+ --warn: #f59e0b;
58
+ --warn-text: #b45309;
59
+ --warn-bg: color-mix(in oklab, var(--warn), transparent 88%);
60
+ --warn-edge: color-mix(in oklab, var(--warn), transparent 65%);
61
+
62
+ --bg: #fbfbfd;
63
+ --bg-subtle: #f4f4f7;
64
+ --bg-elevated: #ffffff;
65
+ --bg-code: #f6f7fa;
66
+ --fg: #09090b;
67
+ --fg-muted: #52525b;
68
+ --fg-subtle: #71717a;
69
+ --border: #e4e4e7;
70
+ --border-subtle: #ececf0;
71
+ --border-strong: #d4d4d8;
72
+ --shadow-sm: 0 1px 2px rgb(0 0 0 / 0.04);
73
+ --shadow-md: 0 4px 20px -8px rgb(0 0 0 / 0.08), 0 1px 2px rgb(0 0 0 / 0.04);
74
+ --grid-dot: rgb(0 0 0 / 0.045);
75
+ --glow-strength: 0.10;
76
+ }
77
+
78
+ @media (prefers-color-scheme: dark) {
79
+ :root {
80
+ --bg: #0a0b12;
81
+ --bg-subtle: #11131a;
82
+ --bg-elevated: #10121a;
83
+ --bg-code: #0c0d14;
84
+ --fg: #ededef;
85
+ --fg-muted: #a1a1a8;
86
+ --fg-subtle: #8a8a93;
87
+ --border: #22232b;
88
+ --border-subtle: #191a21;
89
+ --border-strong: #2d2e37;
90
+ --shadow-sm: 0 1px 2px rgb(0 0 0 / 0.35);
91
+ --shadow-md: 0 4px 24px -8px rgb(0 0 0 / 0.55), 0 1px 2px rgb(0 0 0 / 0.3);
92
+ --grid-dot: rgb(255 255 255 / 0.032);
93
+ --glow-strength: 0.17;
94
+ --accent-glow: color-mix(in oklab, var(--accent), transparent 60%);
95
+ --warn-text: #fbbf24;
96
+ }
97
+ }
98
+
99
+ *, *::before, *::after { box-sizing: border-box; }
100
+ html { color-scheme: light dark; }
101
+
102
+ body {
103
+ margin: 0;
104
+ min-height: 100vh;
105
+ font-family: var(--font-sans);
106
+ font-size: var(--text-base);
107
+ line-height: 1.5;
108
+ color: var(--fg);
109
+ background: var(--bg);
110
+ -webkit-font-smoothing: antialiased;
111
+ -moz-osx-font-smoothing: grayscale;
112
+ text-rendering: optimizeLegibility;
113
+ position: relative;
114
+ overflow-x: hidden;
115
+ }
116
+
117
+ /* Top accent hairline — spans viewport, dual-accent gradient. */
118
+ body::before {
119
+ content: "";
120
+ position: fixed;
121
+ top: 0; left: 0; right: 0;
122
+ height: 1px;
123
+ background: linear-gradient(90deg,
124
+ transparent 0%,
125
+ color-mix(in oklab, var(--accent), transparent 60%) 12%,
126
+ var(--accent) 35%,
127
+ var(--accent-2) 65%,
128
+ color-mix(in oklab, var(--accent-2), transparent 60%) 88%,
129
+ transparent 100%);
130
+ z-index: 100;
131
+ pointer-events: none;
132
+ }
133
+
134
+ /* Ambient background — dual radial glow (accent top-left, accent-2 top-right) + fine dot grid. */
135
+ body::after {
136
+ content: "";
137
+ position: fixed;
138
+ inset: 0;
139
+ background-image:
140
+ radial-gradient(ellipse 70% 55% at 12% -5%, color-mix(in oklab, var(--accent), transparent calc((1 - var(--glow-strength)) * 100%)), transparent 60%),
141
+ radial-gradient(ellipse 55% 45% at 92% 10%, color-mix(in oklab, var(--accent-2), transparent calc((1 - var(--glow-strength)) * 115%)), transparent 55%),
142
+ radial-gradient(circle at center, var(--grid-dot) 1px, transparent 1.5px);
143
+ background-size: 100% 100%, 100% 100%, 24px 24px;
144
+ pointer-events: none;
145
+ z-index: -1;
146
+ }
147
+
148
+ ::selection { background: var(--accent-soft); color: var(--fg); }
149
+
150
+ main {
151
+ max-width: 1120px;
152
+ margin: 0 auto;
153
+ padding: var(--space-10) var(--space-6) var(--space-20);
154
+ position: relative;
155
+ }
156
+
157
+ a {
158
+ color: var(--accent);
159
+ text-decoration: none;
160
+ transition: color var(--duration-fast) var(--ease-out);
161
+ }
162
+ a:hover { color: var(--accent-hover); }
163
+ a:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 2px; }
164
+
165
+ code, pre {
166
+ font-family: var(--font-mono);
167
+ font-size: 0.875em;
168
+ font-feature-settings: "liga" 0, "calt" 0;
169
+ }
170
+ code {
171
+ background: var(--bg-subtle);
172
+ padding: 0.1em 0.35em;
173
+ border-radius: var(--radius-xs);
174
+ border: 1px solid var(--border-subtle);
175
+ font-size: 0.85em;
176
+ }
177
+ pre {
178
+ background: var(--bg-code);
179
+ border: 1px solid var(--border-subtle);
180
+ border-radius: var(--radius-sm);
181
+ padding: var(--space-4);
182
+ margin: 0;
183
+ overflow-x: auto;
184
+ line-height: 1.55;
185
+ white-space: pre;
186
+ color: var(--fg);
187
+ }
188
+ pre code { background: transparent; padding: 0; border: 0; font-size: inherit; }
189
+
190
+ /* -------------------- Hero -------------------- */
191
+
192
+ .hero {
193
+ padding: var(--space-12) 0 var(--space-10);
194
+ display: flex;
195
+ flex-direction: column;
196
+ gap: var(--space-6);
197
+ }
198
+
199
+ .hero-eyebrow {
200
+ display: inline-flex;
201
+ align-items: center;
202
+ gap: var(--space-2);
203
+ font-family: var(--font-mono);
204
+ font-size: 0.6875rem;
205
+ font-weight: 500;
206
+ letter-spacing: 0.14em;
207
+ text-transform: uppercase;
208
+ color: var(--accent);
209
+ }
210
+ .hero-eyebrow::before {
211
+ content: "";
212
+ width: 5px; height: 5px;
213
+ background: var(--accent);
214
+ border-radius: 50%;
215
+ box-shadow: 0 0 10px var(--accent);
216
+ }
217
+
218
+ .hero-title-row {
219
+ display: flex;
220
+ align-items: center;
221
+ gap: var(--space-4);
222
+ flex-wrap: wrap;
223
+ }
224
+ .hero-logo {
225
+ width: 44px; height: 44px;
226
+ border-radius: var(--radius-md);
227
+ object-fit: contain;
228
+ border: 1px solid var(--border);
229
+ background: var(--bg-elevated);
230
+ flex-shrink: 0;
231
+ }
232
+ .hero-heading {
233
+ margin: 0;
234
+ font-size: var(--text-display);
235
+ font-weight: 700;
236
+ letter-spacing: -0.04em;
237
+ line-height: 1.02;
238
+ color: var(--fg);
239
+ word-break: break-word;
240
+ flex: 1 1 auto;
241
+ min-width: 0;
242
+ }
243
+ @supports ((-webkit-background-clip: text) or (background-clip: text)) {
244
+ .hero-heading {
245
+ background: linear-gradient(180deg,
246
+ color-mix(in oklab, var(--fg), var(--accent) 10%) 0%,
247
+ var(--fg) 45%,
248
+ color-mix(in oklab, var(--fg), transparent 22%) 100%);
249
+ -webkit-background-clip: text;
250
+ background-clip: text;
251
+ -webkit-text-fill-color: transparent;
252
+ color: transparent;
253
+ }
254
+ }
255
+ .hero-tagline {
256
+ margin: 0;
257
+ color: var(--fg-muted);
258
+ font-size: var(--text-lg);
259
+ line-height: 1.5;
260
+ max-width: 62ch;
261
+ }
262
+
263
+ /* Version + pre-release chips */
264
+ .badge-version {
265
+ display: inline-flex;
266
+ align-items: center;
267
+ padding: 4px 10px;
268
+ border-radius: var(--radius-pill);
269
+ font-family: var(--font-mono);
270
+ font-size: 0.75rem;
271
+ font-weight: 600;
272
+ letter-spacing: -0.01em;
273
+ color: var(--accent);
274
+ background: var(--accent-softer);
275
+ border: 1px solid var(--accent-edge);
276
+ text-decoration: none;
277
+ transition: background var(--duration-fast) var(--ease-out), transform var(--duration-fast) var(--ease-out);
278
+ }
279
+ .badge-version:hover {
280
+ background: var(--accent-soft);
281
+ color: var(--accent);
282
+ text-decoration: none;
283
+ transform: translateY(-1px);
284
+ }
285
+ .badge-pre {
286
+ display: inline-flex;
287
+ align-items: center;
288
+ padding: 4px 10px;
289
+ border-radius: var(--radius-pill);
290
+ font-family: var(--font-mono);
291
+ font-size: 0.75rem;
292
+ font-weight: 600;
293
+ letter-spacing: -0.01em;
294
+ color: var(--warn-text);
295
+ background: var(--warn-bg);
296
+ border: 1px solid var(--warn-edge);
297
+ }
298
+
299
+ /* Status strip — single line under the tagline. */
300
+ .status-strip {
301
+ display: flex;
302
+ flex-wrap: wrap;
303
+ align-items: center;
304
+ gap: var(--space-4);
305
+ padding: var(--space-3) 0;
306
+ border-top: 1px solid var(--border-subtle);
307
+ border-bottom: 1px solid var(--border-subtle);
308
+ font-family: var(--font-mono);
309
+ font-size: var(--text-xs);
310
+ color: var(--fg-muted);
311
+ letter-spacing: 0.01em;
312
+ }
313
+ .status-item {
314
+ display: inline-flex;
315
+ align-items: center;
316
+ gap: 6px;
317
+ position: relative;
318
+ }
319
+ .status-item + .status-item::before {
320
+ content: "·";
321
+ color: var(--fg-subtle);
322
+ margin-right: var(--space-2);
323
+ opacity: 0.7;
324
+ }
325
+ .status-dot {
326
+ width: 6px; height: 6px;
327
+ border-radius: 50%;
328
+ display: inline-block;
329
+ flex-shrink: 0;
330
+ }
331
+ .status-dot-public {
332
+ background: #22c55e;
333
+ box-shadow: 0 0 0 3px color-mix(in oklab, #22c55e, transparent 80%);
334
+ animation: status-pulse 2.4s ease-in-out infinite;
335
+ }
336
+ .status-dot-gated {
337
+ background: var(--accent);
338
+ box-shadow: 0 0 0 3px color-mix(in oklab, var(--accent), transparent 75%);
339
+ }
340
+ @keyframes status-pulse {
341
+ 0%, 100% { box-shadow: 0 0 0 3px color-mix(in oklab, #22c55e, transparent 80%); }
342
+ 50% { box-shadow: 0 0 0 6px color-mix(in oklab, #22c55e, transparent 92%); }
343
+ }
344
+ .status-value {
345
+ color: var(--fg);
346
+ font-weight: 500;
347
+ }
348
+ .status-value-accent {
349
+ color: var(--accent);
350
+ }
351
+ .status-signin {
352
+ color: var(--fg-muted);
353
+ text-decoration: none;
354
+ border-bottom: 1px dotted var(--fg-subtle);
355
+ }
356
+ .status-signin:hover { color: var(--accent); border-color: var(--accent); }
357
+ .status-link {
358
+ color: inherit;
359
+ text-decoration: none;
360
+ transition: color var(--duration-fast) var(--ease-out);
361
+ }
362
+ .status-link .status-value { transition: color var(--duration-fast) var(--ease-out); }
363
+ .status-link:hover,
364
+ .status-link:hover .status-value { color: var(--accent); }
365
+ .status-link:focus-visible {
366
+ outline: 2px solid var(--accent);
367
+ outline-offset: 3px;
368
+ border-radius: 2px;
369
+ }
370
+
371
+ /* -------------------- Connect card -------------------- */
372
+
373
+ /* Registered custom property enables animation of a gradient angle.
374
+ Without @property the custom-property value would change discretely rather
375
+ than tweening, so the beam would jump instead of sweep. Widely supported
376
+ since 2023 — engines without it fall through to the static border. */
377
+ @property --beam-angle {
378
+ syntax: "<angle>";
379
+ initial-value: 0deg;
380
+ inherits: false;
381
+ }
382
+
383
+ .connect {
384
+ border: 1px solid var(--border);
385
+ border-radius: var(--radius-lg);
386
+ background: var(--bg-elevated);
387
+ overflow: hidden;
388
+ box-shadow: var(--shadow-md);
389
+ position: relative;
390
+ isolation: isolate;
391
+ }
392
+
393
+ /* Animated conic-gradient beam sweeping the inside of the card edge. Uses the
394
+ "mask-composite: exclude" trick to render only the outer ring. Sits just
395
+ inside the static border so it reads as accent light traveling along the
396
+ rim; the static border remains as a fallback for engines without
397
+ mask-composite or @property. */
398
+ .connect::before {
399
+ content: "";
400
+ position: absolute;
401
+ inset: 0;
402
+ padding: 1.5px;
403
+ border-radius: inherit;
404
+ background: conic-gradient(
405
+ from var(--beam-angle),
406
+ transparent 0deg 40deg,
407
+ var(--accent) 90deg,
408
+ var(--accent-2) 160deg,
409
+ transparent 220deg 360deg
410
+ );
411
+ mask:
412
+ linear-gradient(#000, #000) content-box,
413
+ linear-gradient(#000, #000);
414
+ mask-composite: exclude;
415
+ -webkit-mask-composite: xor;
416
+ animation: connect-beam 7s linear infinite;
417
+ pointer-events: none;
418
+ z-index: 1;
419
+ opacity: 0.9;
420
+ }
421
+
422
+ @keyframes connect-beam {
423
+ to {
424
+ --beam-angle: 360deg;
425
+ }
426
+ }
427
+
428
+ /* Chrome header — three dots + endpoint path */
429
+ .connect-chrome {
430
+ display: flex;
431
+ align-items: center;
432
+ gap: var(--space-3);
433
+ padding: var(--space-3) var(--space-4);
434
+ border-bottom: 1px solid var(--border-subtle);
435
+ background: var(--bg-subtle);
436
+ }
437
+ .connect-chrome-dots {
438
+ display: inline-flex;
439
+ gap: 6px;
440
+ flex-shrink: 0;
441
+ }
442
+ .connect-chrome-dot {
443
+ width: 10px; height: 10px;
444
+ border-radius: 50%;
445
+ background: color-mix(in oklab, var(--fg-subtle), transparent 60%);
446
+ display: inline-block;
447
+ }
448
+ .connect-chrome-endpoint {
449
+ margin-left: auto;
450
+ font-family: var(--font-mono);
451
+ font-size: 0.6875rem;
452
+ color: var(--fg-muted);
453
+ white-space: nowrap;
454
+ overflow: hidden;
455
+ text-overflow: ellipsis;
456
+ min-width: 0;
457
+ }
458
+
459
+ /* Radio-hack tabs */
460
+ .connect-tab-input { position: absolute; opacity: 0; pointer-events: none; }
461
+ .connect-tabs {
462
+ display: flex;
463
+ gap: 0;
464
+ padding: 0 var(--space-4);
465
+ border-bottom: 1px solid var(--border-subtle);
466
+ overflow-x: auto;
467
+ scrollbar-width: none;
468
+ }
469
+ .connect-tabs::-webkit-scrollbar { display: none; }
470
+ .connect-tab-label {
471
+ padding: var(--space-3) var(--space-4);
472
+ font-size: var(--text-sm);
473
+ font-weight: 500;
474
+ color: var(--fg-muted);
475
+ cursor: pointer;
476
+ border-bottom: 3px solid transparent;
477
+ margin-bottom: -1px;
478
+ white-space: nowrap;
479
+ transition: color var(--duration-fast) var(--ease-out),
480
+ border-color var(--duration-fast) var(--ease-out),
481
+ background var(--duration-fast) var(--ease-out);
482
+ }
483
+ .connect-tab-label:hover { color: var(--fg); }
484
+ .connect-tab-input:checked + .connect-tab-label {
485
+ color: var(--fg);
486
+ font-weight: 600;
487
+ border-bottom-color: var(--accent);
488
+ background: linear-gradient(to top, var(--accent-softer), transparent 70%);
489
+ }
490
+ .connect-tab-input:focus-visible + .connect-tab-label {
491
+ outline: 2px solid var(--accent);
492
+ outline-offset: -6px;
493
+ border-radius: var(--radius-sm);
494
+ }
495
+
496
+ .connect-panels { position: relative; padding: var(--space-5) var(--space-4); }
497
+ .connect-panel { display: none; }
498
+ .connect:has(#connect-tab-stdio:checked) .panel-stdio,
499
+ .connect:has(#connect-tab-http:checked) .panel-http,
500
+ .connect:has(#connect-tab-claude:checked) .panel-claude,
501
+ .connect:has(#connect-tab-curl:checked) .panel-curl { display: block; }
502
+ /* Fallback when :has() unsupported — show first visible panel */
503
+ @supports not selector(:has(*)) {
504
+ .connect-panel:first-of-type { display: block; }
505
+ }
506
+ .connect-panel pre {
507
+ padding: var(--space-4);
508
+ padding-right: var(--space-12);
509
+ background: var(--bg-code);
510
+ border: 1px solid var(--border-subtle);
511
+ border-radius: var(--radius-sm);
512
+ font-size: 0.8125rem;
513
+ line-height: 1.6;
514
+ }
515
+ .connect-copy {
516
+ position: absolute;
517
+ top: calc(var(--space-5) + 8px);
518
+ right: calc(var(--space-4) + 8px);
519
+ font-family: var(--font-mono);
520
+ font-size: 0.6875rem;
521
+ font-weight: 500;
522
+ padding: 4px 10px;
523
+ border-radius: var(--radius-sm);
524
+ border: 1px solid var(--border);
525
+ background: var(--bg);
526
+ color: var(--fg-muted);
527
+ cursor: pointer;
528
+ transition: all var(--duration-fast) var(--ease-out);
529
+ letter-spacing: 0.02em;
530
+ }
531
+ .connect-copy:hover {
532
+ color: var(--accent);
533
+ border-color: var(--accent-edge);
534
+ background: var(--accent-softer);
535
+ }
536
+ .connect-copy:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
537
+ .connect-copy[data-copied="true"] {
538
+ color: #16a34a;
539
+ border-color: color-mix(in oklab, #16a34a, transparent 60%);
540
+ background: color-mix(in oklab, #16a34a, transparent 92%);
541
+ }
542
+
543
+ /* Framework attribution pill */
544
+ .hero-badges {
545
+ display: inline-flex;
546
+ align-items: center;
547
+ gap: var(--space-2);
548
+ }
549
+ .badge-shield {
550
+ display: inline-flex;
551
+ align-items: center;
552
+ gap: 6px;
553
+ padding: 4px 10px;
554
+ border-radius: var(--radius-pill);
555
+ font-family: var(--font-mono);
556
+ font-size: 0.6875rem;
557
+ font-weight: 500;
558
+ letter-spacing: 0.01em;
559
+ color: var(--fg-muted);
560
+ background: var(--bg-subtle);
561
+ border: 1px solid var(--border-subtle);
562
+ text-decoration: none;
563
+ transition: all var(--duration-fast) var(--ease-out);
564
+ }
565
+ .badge-shield:hover {
566
+ color: var(--accent);
567
+ border-color: var(--accent-edge);
568
+ background: var(--accent-softer);
569
+ text-decoration: none;
570
+ transform: translateY(-1px);
571
+ }
572
+ .badge-shield-label { color: var(--fg-subtle); transition: color var(--duration-fast); }
573
+ .badge-shield-value { color: var(--fg-muted); transition: color var(--duration-fast); }
574
+ .badge-shield:hover .badge-shield-label,
575
+ .badge-shield:hover .badge-shield-value { color: var(--accent); }
576
+
577
+ /* -------------------- Sections -------------------- */
578
+
579
+ section { padding: var(--space-12) 0 0; }
580
+
581
+ .section-heading {
582
+ display: flex;
583
+ align-items: baseline;
584
+ gap: var(--space-3);
585
+ margin: 0 0 var(--space-6);
586
+ padding-bottom: var(--space-3);
587
+ border-bottom: 1px solid var(--border-subtle);
588
+ }
589
+ .section-heading h2 {
590
+ margin: 0;
591
+ font-size: var(--text-2xl);
592
+ font-weight: 600;
593
+ letter-spacing: -0.025em;
594
+ color: var(--fg);
595
+ text-transform: lowercase;
596
+ display: inline-flex;
597
+ align-items: center;
598
+ gap: var(--space-3);
599
+ }
600
+ .section-heading h2::before {
601
+ content: "";
602
+ display: inline-block;
603
+ width: 3px;
604
+ height: 0.9em;
605
+ background: linear-gradient(180deg, var(--accent), var(--accent-2));
606
+ border-radius: 2px;
607
+ flex-shrink: 0;
608
+ }
609
+ .section-count {
610
+ font-family: var(--font-mono);
611
+ font-size: var(--text-2xl);
612
+ font-weight: 600;
613
+ color: var(--accent);
614
+ font-variant-numeric: tabular-nums;
615
+ letter-spacing: -0.02em;
616
+ line-height: 1;
617
+ }
618
+
619
+ .group-heading {
620
+ margin: var(--space-6) 0 var(--space-3);
621
+ color: var(--fg-muted);
622
+ font-family: var(--font-mono);
623
+ font-size: 0.6875rem;
624
+ font-weight: 600;
625
+ text-transform: uppercase;
626
+ letter-spacing: 0.12em;
627
+ }
628
+ .group-heading:first-child { margin-top: 0; }
629
+
630
+ /* -------------------- Cards -------------------- */
631
+
632
+ .card-grid {
633
+ display: grid;
634
+ grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
635
+ gap: var(--space-3);
636
+ align-items: start;
637
+ }
638
+ .card {
639
+ border: 1px solid var(--border-subtle);
640
+ border-radius: var(--radius-md);
641
+ padding: var(--space-4) var(--space-5);
642
+ background: var(--bg-elevated);
643
+ display: flex;
644
+ flex-direction: column;
645
+ gap: var(--space-2);
646
+ transition: border-color var(--duration-fast) var(--ease-out),
647
+ transform var(--duration-fast) var(--ease-out),
648
+ box-shadow var(--duration-fast) var(--ease-out);
649
+ position: relative;
650
+ }
651
+ .card:hover {
652
+ border-color: var(--accent-edge);
653
+ transform: translateY(-1px);
654
+ box-shadow: 0 8px 28px -12px var(--accent-glow), var(--shadow-md);
655
+ }
656
+ .card-head {
657
+ display: flex;
658
+ align-items: center;
659
+ gap: var(--space-2);
660
+ flex-wrap: wrap;
661
+ }
662
+ .card-title {
663
+ margin: 0;
664
+ font-size: 0.9375rem;
665
+ font-weight: 600;
666
+ font-family: var(--font-mono);
667
+ color: var(--fg);
668
+ letter-spacing: -0.015em;
669
+ }
670
+ .card-title a { color: inherit; }
671
+ .card-title a:hover { color: var(--accent); text-decoration: none; }
672
+ .card-desc {
673
+ margin: 0;
674
+ color: var(--fg-muted);
675
+ font-size: var(--text-sm);
676
+ line-height: 1.5;
677
+ }
678
+ .card-meta {
679
+ display: flex;
680
+ flex-wrap: wrap;
681
+ gap: var(--space-1) var(--space-3);
682
+ font-size: var(--text-xs);
683
+ color: var(--fg-muted);
684
+ font-family: var(--font-mono);
685
+ align-items: center;
686
+ }
687
+ .card-meta-label { color: var(--fg-subtle); }
688
+ .card-meta code {
689
+ font-size: 1em;
690
+ color: var(--fg);
691
+ background: transparent;
692
+ border: 0;
693
+ padding: 0;
694
+ }
695
+
696
+ /* Annotation pills — dot-chip style */
697
+ .pill-row { display: inline-flex; flex-wrap: wrap; gap: 5px; align-items: center; }
698
+ .pill {
699
+ display: inline-flex;
700
+ align-items: center;
701
+ gap: 5px;
702
+ padding: 2px 8px;
703
+ border-radius: var(--radius-pill);
704
+ font-family: var(--font-mono);
705
+ font-size: 0.6875rem;
706
+ font-weight: 500;
707
+ line-height: 1.4;
708
+ color: var(--fg-muted);
709
+ background: var(--bg-subtle);
710
+ border: 1px solid var(--border-subtle);
711
+ letter-spacing: 0.01em;
712
+ }
713
+ .pill::before {
714
+ content: "";
715
+ width: 4px; height: 4px;
716
+ border-radius: 50%;
717
+ background: currentColor;
718
+ flex-shrink: 0;
719
+ }
720
+ .pill-readonly { color: #16a34a; background: color-mix(in oklab, #16a34a, transparent 92%); border-color: color-mix(in oklab, #16a34a, transparent 72%); }
721
+ .pill-destructive { color: #dc2626; background: color-mix(in oklab, #dc2626, transparent 92%); border-color: color-mix(in oklab, #dc2626, transparent 72%); }
722
+ .pill-openworld { color: #2563eb; background: color-mix(in oklab, #2563eb, transparent 92%); border-color: color-mix(in oklab, #2563eb, transparent 72%); }
723
+ .pill-task { color: var(--accent); background: var(--accent-softer); border-color: var(--accent-edge); }
724
+ .pill-app { color: #9333ea; background: color-mix(in oklab, #9333ea, transparent 92%); border-color: color-mix(in oklab, #9333ea, transparent 72%); }
725
+ .pill-auth { color: var(--fg-subtle); font-size: 0.65rem; }
726
+ .pill-auth::before { display: none; }
727
+
728
+ @media (prefers-color-scheme: dark) {
729
+ .pill-readonly { color: #4ade80; }
730
+ .pill-destructive { color: #f87171; }
731
+ .pill-openworld { color: #60a5fa; }
732
+ .pill-app { color: #c084fc; }
733
+ }
734
+
735
+ .source-link {
736
+ font-size: var(--text-xs);
737
+ color: var(--fg-muted);
738
+ margin-left: auto;
739
+ font-family: var(--font-mono);
740
+ transition: color var(--duration-fast);
741
+ }
742
+ .source-link:hover { color: var(--accent); text-decoration: none; }
743
+
744
+ /* Inline snippet (tool invocation) */
745
+ .snippet {
746
+ position: relative;
747
+ margin-top: var(--space-2);
748
+ }
749
+ .snippet pre {
750
+ padding: var(--space-3);
751
+ padding-right: var(--space-12);
752
+ background: var(--bg-code);
753
+ border: 1px solid var(--border-subtle);
754
+ border-radius: var(--radius-sm);
755
+ font-size: 0.75rem;
756
+ line-height: 1.55;
757
+ }
758
+ .snippet-copy {
759
+ position: absolute;
760
+ top: 6px;
761
+ right: 6px;
762
+ font-family: var(--font-mono);
763
+ font-size: 0.65rem;
764
+ font-weight: 500;
765
+ padding: 3px 8px;
766
+ border-radius: var(--radius-xs);
767
+ border: 1px solid var(--border);
768
+ background: var(--bg);
769
+ color: var(--fg-muted);
770
+ cursor: pointer;
771
+ transition: all var(--duration-fast) var(--ease-out);
772
+ letter-spacing: 0.02em;
773
+ }
774
+ .snippet-copy:hover { color: var(--accent); border-color: var(--accent-edge); }
775
+ .snippet-copy:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
776
+ .snippet-copy[data-copied="true"] {
777
+ color: #16a34a;
778
+ border-color: color-mix(in oklab, #16a34a, transparent 60%);
779
+ }
780
+
781
+ /* Collapsible details (schema preview) */
782
+ details {
783
+ margin-top: var(--space-1);
784
+ border: 0;
785
+ border-radius: 0;
786
+ }
787
+ details > summary {
788
+ cursor: pointer;
789
+ padding: 4px 0;
790
+ font-family: var(--font-mono);
791
+ font-size: var(--text-xs);
792
+ color: var(--fg-muted);
793
+ list-style: none;
794
+ user-select: none;
795
+ display: inline-flex;
796
+ align-items: center;
797
+ gap: var(--space-2);
798
+ transition: color var(--duration-fast);
799
+ }
800
+ details > summary::-webkit-details-marker { display: none; }
801
+ details > summary::before {
802
+ content: "+";
803
+ display: inline-block;
804
+ width: 10px;
805
+ text-align: center;
806
+ color: var(--fg-muted);
807
+ font-weight: 600;
808
+ transition: transform var(--duration-fast), color var(--duration-fast);
809
+ }
810
+ details[open] > summary::before { content: "−"; color: var(--accent); }
811
+ details > summary:hover { color: var(--accent); }
812
+ details > pre {
813
+ margin-top: var(--space-2);
814
+ font-size: 0.7rem;
815
+ line-height: 1.55;
816
+ }
817
+
818
+ /* Prompt args */
819
+ .args-list {
820
+ list-style: none;
821
+ padding: 0;
822
+ margin: var(--space-1) 0 0;
823
+ display: flex;
824
+ flex-direction: column;
825
+ gap: 4px;
826
+ font-size: var(--text-xs);
827
+ color: var(--fg-muted);
828
+ font-family: var(--font-mono);
829
+ }
830
+ .args-list li { line-height: 1.6; }
831
+ .args-list code {
832
+ font-size: 1em;
833
+ background: transparent;
834
+ border: 0;
835
+ padding: 0;
836
+ color: var(--fg);
837
+ }
838
+ .args-required {
839
+ color: var(--accent);
840
+ font-size: 0.625rem;
841
+ font-weight: 600;
842
+ margin-left: 5px;
843
+ letter-spacing: 0.08em;
844
+ text-transform: uppercase;
845
+ }
846
+
847
+ /* Extensions */
848
+ .ext-card { background: var(--bg-subtle); border-color: var(--border-subtle); }
849
+ .ext-key { font-family: var(--font-mono); font-size: var(--text-sm); color: var(--fg); }
850
+ .ext-preview {
851
+ margin: var(--space-2) 0 0;
852
+ font-size: 0.7rem;
853
+ line-height: 1.55;
854
+ }
855
+
856
+ /* Empty / degraded state */
857
+ .empty-state {
858
+ padding: var(--space-10) var(--space-6);
859
+ text-align: center;
860
+ color: var(--fg-muted);
861
+ border: 1px dashed var(--border);
862
+ border-radius: var(--radius-md);
863
+ background: var(--bg-subtle);
864
+ font-size: var(--text-sm);
865
+ font-family: var(--font-mono);
866
+ }
867
+
868
+ /* -------------------- Footer -------------------- */
869
+
870
+ footer {
871
+ margin-top: var(--space-20);
872
+ padding: var(--space-6) 0;
873
+ border-top: 1px solid var(--border-subtle);
874
+ display: flex;
875
+ flex-wrap: wrap;
876
+ align-items: center;
877
+ gap: var(--space-2) var(--space-4);
878
+ font-family: var(--font-mono);
879
+ font-size: var(--text-xs);
880
+ color: var(--fg-subtle);
881
+ letter-spacing: 0.01em;
882
+ }
883
+ footer a {
884
+ color: var(--fg-muted);
885
+ text-decoration: none;
886
+ transition: color var(--duration-fast) var(--ease-out);
887
+ }
888
+ footer a:hover { color: var(--accent); text-decoration: none; }
889
+ .footer-sep { color: var(--fg-subtle); opacity: 0.5; user-select: none; }
890
+ .footer-spacer { flex: 1 0 var(--space-4); }
891
+ .footer-attrib { color: var(--fg-subtle); }
892
+ .footer-attrib a { color: var(--fg-muted); }
893
+
894
+ /* -------------------- Responsive -------------------- */
895
+
896
+ @media (max-width: 760px) {
897
+ main { padding: var(--space-6) var(--space-4) var(--space-16); }
898
+ .hero { padding: var(--space-8) 0 var(--space-6); gap: var(--space-5); }
899
+ .hero-heading { font-size: clamp(1.875rem, 7vw + 0.5rem, 2.5rem); letter-spacing: -0.035em; }
900
+ .hero-title-row { gap: var(--space-3); }
901
+ .hero-logo { width: 40px; height: 40px; }
902
+ .hero-tagline { font-size: var(--text-base); }
903
+ .status-strip { gap: var(--space-2); font-size: 0.6875rem; }
904
+ .connect-chrome-endpoint { display: none; }
905
+ .card-grid { grid-template-columns: 1fr; }
906
+ section { padding: var(--space-8) 0 0; }
907
+ .section-heading h2 { font-size: var(--text-xl); }
908
+ .section-count { font-size: var(--text-xl); }
909
+ }
910
+
911
+ @media (prefers-reduced-motion: reduce) {
912
+ *, *::before, *::after {
913
+ transition-duration: 0.01ms !important;
914
+ animation-duration: 0.01ms !important;
915
+ animation-iteration-count: 1 !important;
916
+ }
917
+ }
918
+ `;
919
+ return unsafeRaw(`<style>${css}</style>`);
920
+ }
921
+ //# sourceMappingURL=styles.js.map