@smarter.sh/ui-widgets 0.35.4-alpha.2 → 0.36.0-alpha.4

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.
package/README.md CHANGED
@@ -4,10 +4,18 @@ React widgets from the [Smarter](https://smarter.sh) web console's dashboard: th
4
4
  no account data. The web console's dashboard uses them, and so does [smarter.sh](https://smarter.sh),
5
5
  so that the two look the same.
6
6
 
7
- | Widget | What it shows |
8
- | ---------- | ------------------------------------------------------------------------------- |
9
- | `SelfHost` | The path from a laptop to production: Docker Compose, the Helm chart, Terraform |
10
- | `Sdk` | The Smarter SDKs, with their install commands, and links to the API reference |
7
+ | Widget | What it shows |
8
+ | ----------------- | --------------------------------------------------------------------------------- |
9
+ | `Cli` | The Smarter command-line interface, as a terminal session |
10
+ | `Contribute` | Ways to help the project, its repository's activity badges and contributing guide |
11
+ | `Extensions` | Smarter Extensions: the official ones, a manifest that uses one, the registry |
12
+ | `Instructors` | The Instructor Guide and the Free Course Designs |
13
+ | `Integrations` | The Smarter Chat integrations: WordPress, Drupal, Shopify, Docusaurus, ... |
14
+ | `McpServer` | The Smarter Project MCP Server, with the command that adds it to Claude Code |
15
+ | `Sdk` | The Smarter SDKs, with their install commands, and links to the API reference |
16
+ | `SelfHost` | The path from a laptop to production: Docker Compose, the Helm chart, Terraform |
17
+ | `VSCodeExtension` | The Smarter Manifest VS Code extension, with a mock editor |
18
+ | `WhatsNew` | Notable features of recent Smarter releases |
11
19
 
12
20
  ## Install
13
21
 
@@ -44,9 +52,12 @@ is. This package doesn't include the theme. A page provides:
44
52
  - **The Keen stylesheet.** The web console loads it on every page. A page with a design of its own,
45
53
  such as smarter.sh, can scope it to the elements that hold the widgets, as smarter.sh does with
46
54
  its `.keen` wrapper.
47
- - **The Keen theme's images**, at their `/static/assets/` paths: the Sdk widget's illustration
48
- (`media/illustrations/dozzy-1/4.png`) and its React and Python logos
49
- (`media/svg/brand-logos/react.svg`, `python-5.svg`).
55
+ - **The Keen theme's images**, at their `/static/assets/media/` paths:
56
+ - `illustrations/dozzy-1/4.png` (Sdk), `illustrations/dozzy-1/13.png` (Contribute),
57
+ `illustrations/sigma-1/2.png` (Instructors), `illustrations/sketchy-1/17-dark.png` (Integrations)
58
+ - `svg/brand-logos/react.svg` and `python-5.svg` (Sdk), `google-tag-manager.svg` (Integrations)
59
+ - **The VS Code logo**, at `/static/images/vs-code-logo.png` (VSCodeExtension). Library mode would
60
+ inline it, and it is 115 kB.
50
61
 
51
62
  The widgets' other logos are [Simple Icons](https://simpleicons.org/) (CC0), and are inlined in
52
63
  the library.
@@ -58,24 +69,30 @@ The widgets' text is English. In the web console, which defines Django's JavaScr
58
69
 
59
70
  ## Props
60
71
 
61
- | Widget | Prop | Default | Purpose |
62
- | ------ | ------------ | ---------------- | -------------------------------------------------------------------------------- |
63
- | `Sdk` | `openapiUrl` | `/docs/openapi/` | The API reference button's url. Outside a web console, a platform's absolute url |
64
- | `Sdk` | `className` | `col-xl-4` | The card's grid column classes |
72
+ Outside a web console, pass the urls of a platform, and set the cards' widths to fit the page.
65
73
 
66
- `SelfHost` has no props.
74
+ | Widget | Prop | Default | Purpose |
75
+ | -------------- | ------------ | ------------------------------------------------- | ------------------------------------------------ |
76
+ | `Sdk` | `openapiUrl` | `/docs/openapi/` | The API reference button's url |
77
+ | `McpServer` | `serverUrl` | the page's domain, `/api/v1/mcp/smarter-project/` | The MCP server's url, in the Claude Code command |
78
+ | `Cli` | `className` | `col-xl-4` | The card's grid column classes |
79
+ | `Instructors` | `className` | `col-xl-6` | The card's grid column classes |
80
+ | `Integrations` | `className` | `col-xl-4` | The card's grid column classes |
81
+ | `Sdk` | `className` | `col-xl-4` | The card's grid column classes |
82
+
83
+ The other widgets have no props. They fill the element that holds them.
67
84
 
68
85
  ## Development
69
86
 
70
87
  The package is part of the Smarter web console's npm workspace, in
71
- [smarter/react/packages/smarter-widgets](https://github.com/smarter-sh/smarter/tree/main/smarter/react/packages/smarter-widgets).
88
+ [smarter/react/packages/smarter.sh-widgets](https://github.com/smarter-sh/smarter/tree/main/smarter/react/packages/smarter.sh-widgets).
72
89
 
73
90
  ```console
74
91
  cd smarter/react
75
- npx vitest run --project smarter-widgets # tests, including every story
92
+ npx vitest run --project smarter.sh-widgets # tests, including every story
76
93
  npm run build:lib -w @smarter.sh/ui-widgets # dist/
77
94
  npm run check:dist -w @smarter.sh/ui-widgets # checks dist/ before it is published
78
- make react-storybook APP=smarter-widgets # Storybook, from the repository's root
95
+ make react-storybook APP=smarter.sh-widgets # Storybook, from the repository's root
79
96
  ```
80
97
 
81
98
  Each Smarter release publishes the package, at the platform's version:
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Cli dashboard widget.
3
+ *
4
+ * This component renders a dashboard call-to-action card for the Smarter
5
+ * command-line interface, styled as a terminal window that shows a typical
6
+ * session (install, configure, apply, deploy, list), followed by links to
7
+ * download the CLI and open its documentation.
8
+ *
9
+ * :param className: The card's grid column classes, so that the page can set its width.
10
+ * :type className: str
11
+ * :returns: A JSX fragment containing the CLI promotion widget.
12
+ * :rtype: JSX.Element
13
+ *
14
+ * :example:
15
+ *
16
+ * <Cli />
17
+ * <Cli className="col-12" />
18
+ */
19
+ import "./styles.css";
20
+ export interface CliProps {
21
+ /** The card's grid column classes, so that the page can set its width. */
22
+ className?: string;
23
+ }
24
+ declare function Cli({ className }: CliProps): import("react").JSX.Element;
25
+ export default Cli;
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Contribute dashboard widget.
3
+ *
4
+ * This component renders a dashboard contribution-focused card that encourages community
5
+ * participation in the Smarter project: a few ways to help, the repository's activity
6
+ * badges, links to the contributing guide and the open issues, and a supporting
7
+ * illustration.
8
+ *
9
+ * :returns: A JSX fragment containing the contribution engagement widget.
10
+ * :rtype: JSX.Element
11
+ *
12
+ * :example:
13
+ *
14
+ * <Contribute />
15
+ */
16
+ import "./styles.css";
17
+ declare function Contribute(): import("react").JSX.Element;
18
+ export default Contribute;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Extensions dashboard widget.
3
+ *
4
+ * This component renders a card about Smarter Extensions: Python packages
5
+ * that add tools to a platform's LLMs, installed by superusers from the
6
+ * signed Smarter Extension registry without a redeploy, and listed in an
7
+ * LLMClient's ``spec.extensions``. It shows the three official extensions
8
+ * with their trust badge and a link to its GitHub repository, a manifest that uses one, and links to the
9
+ * documentation, the registry, and the guide to building an extension.
10
+ *
11
+ * :returns: A JSX fragment containing the Extensions widget.
12
+ * :rtype: JSX.Element
13
+ *
14
+ * :example:
15
+ *
16
+ * <Extensions />
17
+ */
18
+ import "./styles.css";
19
+ declare function Extensions(): import("react").JSX.Element;
20
+ export default Extensions;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Instructors dashboard widget.
3
+ *
4
+ * This component renders a promotional card for teaching with Smarter: the
5
+ * Smarter Instructor Guide and the Free Course Designs, 21 ready-to-teach
6
+ * course designs (19 micro courses and 2 master classes) that are free and
7
+ * open source. It shows the catalog's headline numbers, two scrolling
8
+ * ribbons of every course, each linked to its course design, the three
9
+ * formats of a micro course, and links to the catalog and the guide.
10
+ *
11
+ * :param className: The card's grid column classes, so that the page can set its width.
12
+ * :type className: str
13
+ * :returns: A JSX fragment containing the instructors call-to-action widget.
14
+ * :rtype: JSX.Element
15
+ *
16
+ * :example:
17
+ *
18
+ * <Instructors />
19
+ * <Instructors className="col-12" />
20
+ */
21
+ import "./styles.css";
22
+ export interface InstructorsProps {
23
+ /** The card's grid column classes, so that the page can set its width. */
24
+ className?: string;
25
+ }
26
+ declare function Instructors({ className }: InstructorsProps): import("react").JSX.Element;
27
+ export default Instructors;
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Integrations dashboard widget.
3
+ *
4
+ * This component renders a promotional card for the Smarter Chat
5
+ * integrations, which add a deployed LLMClient's chat to a third-party
6
+ * platform with @smarter.sh/ui-chat's embed script: the WordPress plugin, the
7
+ * Drupal module, the Shopify app, the Google Tag Manager template, and the
8
+ * plugins for the Docusaurus, MkDocs, Sphinx and VitePress documentation site
9
+ * generators. Each integration is a logo tile that links to its
10
+ * documentation, followed by links to the embedding guide and the source code.
11
+ *
12
+ * :param className: The card's grid column classes, so that the page can set its width.
13
+ * :type className: str
14
+ * :returns: A JSX fragment containing the integrations call-to-action widget.
15
+ * :rtype: JSX.Element
16
+ *
17
+ * :example:
18
+ *
19
+ * <Integrations />
20
+ * <Integrations className="col-12" />
21
+ */
22
+ import "./styles.css";
23
+ export interface IntegrationsProps {
24
+ /** The card's grid column classes, so that the page can set its width. */
25
+ className?: string;
26
+ }
27
+ declare function Integrations({ className }: IntegrationsProps): import("react").JSX.Element;
28
+ export default Integrations;
@@ -0,0 +1,28 @@
1
+ /**
2
+ * McpServer dashboard widget.
3
+ *
4
+ * This component renders a promotional card for the Smarter Project MCP
5
+ * Server, which every platform runs at ``/api/v1/mcp/smarter-project/``: a
6
+ * read-only Model Context Protocol server, without authentication, that answers
7
+ * questions about The Smarter Project from its own code and documentation. It
8
+ * shows the command that adds this platform's server to Claude Code, its main
9
+ * tools, and a link to its documentation.
10
+ *
11
+ * :param serverUrl: The MCP server's url, in the command. Defaults to this platform's, on the page's
12
+ * own domain. A page outside the web console, such as smarter.sh, passes a platform's absolute url.
13
+ * :type serverUrl: str
14
+ * :returns: A JSX fragment containing the MCP server call-to-action widget.
15
+ * :rtype: JSX.Element
16
+ *
17
+ * :example:
18
+ *
19
+ * <McpServer />
20
+ * <McpServer serverUrl="https://platform.smarter.sh/api/v1/mcp/smarter-project/" />
21
+ */
22
+ import "./styles.css";
23
+ export interface McpServerProps {
24
+ /** The MCP server's url, in the command. */
25
+ serverUrl?: string;
26
+ }
27
+ declare function McpServer({ serverUrl }: McpServerProps): import("react").JSX.Element;
28
+ export default McpServer;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * VSCodeExtension dashboard widget.
3
+ *
4
+ * This component renders a promotional card for the Smarter Manifest VS Code
5
+ * extension: its main features, direct links to the Visual Studio Marketplace
6
+ * listing and official documentation, its install count, and a mock editor
7
+ * that shows the extension flagging a misspelled key in a manifest.
8
+ *
9
+ * :returns: A JSX fragment containing the VS Code extension call-to-action
10
+ * widget.
11
+ * :rtype: JSX.Element
12
+ *
13
+ * :example:
14
+ *
15
+ * <VSCodeExtension />
16
+ */
17
+ import "./styles.css";
18
+ declare function VSCodeExtension(): import("react").JSX.Element;
19
+ export default VSCodeExtension;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * WhatsNew dashboard widget.
3
+ *
4
+ * This component renders a card that highlights notable features added in
5
+ * recent Smarter releases, with each entry linking to its documentation page
6
+ * on docs.smarter.sh.
7
+ *
8
+ * :returns: A JSX fragment containing the new features widget.
9
+ * :rtype: JSX.Element
10
+ *
11
+ * :example:
12
+ *
13
+ * <WhatsNew />
14
+ */
15
+ import "./styles.css";
16
+ declare function WhatsNew(): import("react").JSX.Element;
17
+ export default WhatsNew;
@@ -5,6 +5,18 @@
5
5
  * The widgets are styled for the Keen Bootstrap theme, which the page provides. The library imports
6
6
  * the widgets' own stylesheet, so a page's bundler loads it along with them.
7
7
  */
8
+ export { default as Cli } from "./components/Cli/Component";
9
+ export type { CliProps } from "./components/Cli/Component";
10
+ export { default as Contribute } from "./components/Contribute/Component";
11
+ export { default as Extensions } from "./components/Extensions/Component";
12
+ export { default as Instructors } from "./components/Instructors/Component";
13
+ export type { InstructorsProps } from "./components/Instructors/Component";
14
+ export { default as Integrations } from "./components/Integrations/Component";
15
+ export type { IntegrationsProps } from "./components/Integrations/Component";
16
+ export { default as McpServer } from "./components/McpServer/Component";
17
+ export type { McpServerProps } from "./components/McpServer/Component";
8
18
  export { default as Sdk } from "./components/Sdk/Component";
9
19
  export type { SdkProps } from "./components/Sdk/Component";
10
20
  export { default as SelfHost } from "./components/SelfHost/Component";
21
+ export { default as VSCodeExtension } from "./components/VSCodeExtension/Component";
22
+ export { default as WhatsNew } from "./components/WhatsNew/Component";
@@ -1,2 +1,2 @@
1
- .sdk-card{background:linear-gradient(135deg,#e6f4ff 0%,#fff1e6 100%);overflow:hidden}.sdk-lede{max-width:65%}.sdk-list{flex-direction:column;gap:.75rem;margin-bottom:0;padding-left:0;list-style:none;display:flex}.sdk-item{align-items:center;gap:.85rem;display:flex}.sdk-logo{background-color:#fff;border-radius:.75rem;flex-shrink:0;justify-content:center;align-items:center;width:44px;height:44px;display:flex;box-shadow:0 .4rem 1rem #1c325e26}.sdk-logo img{width:24px;height:24px}.sdk-text{flex-direction:column;min-width:0;display:flex}.sdk-name{color:#1c325e;font-weight:600}.sdk-name:hover{color:#f1416c}.sdk-install{color:#a6e3a1;max-width:100%;font-family:var(--bs-font-monospace,monospace);text-overflow:ellipsis;white-space:nowrap;-webkit-user-select:all;user-select:all;background-color:#1e1e2e;border-radius:.4rem;align-self:flex-start;margin-top:.2rem;padding:.1rem .45rem;font-size:.75rem;overflow:hidden}.selfhost-card{background:radial-gradient(circle at 15% 110%,#2496ed59 0%,#2496ed00 50%),radial-gradient(circle at 95% 0,#844fba59 0%,#844fba00 45%),linear-gradient(135deg,#0b1d3a 0%,#1c325e 100%);overflow:hidden}.selfhost-eyebrow{color:#7cc4ff;letter-spacing:.08em;text-transform:uppercase;background-color:#2496ed33;border-radius:999px;align-self:flex-start;padding:.25rem .7rem;font-size:.7rem;font-weight:700}.selfhost-underline{opacity:.8;border-color:#2496ed!important}.selfhost-lede{color:#ffffffbf;max-width:70%}.selfhost-steps{grid-template-columns:repeat(3,minmax(0,1fr));gap:1rem;margin:0;padding:0;list-style:none;display:grid;position:relative}.selfhost-steps:before{content:"";border-top:2px dashed #ffffff4d;position:absolute;top:28px;left:16.66%;right:16.66%}.selfhost-step-link{text-align:center;flex-direction:column;align-items:center;height:100%;padding:0 .25rem;text-decoration:none;display:flex;position:relative}.selfhost-logo{background-color:#fff;border-radius:1rem;justify-content:center;align-items:center;width:56px;height:56px;margin-bottom:.75rem;display:flex;position:relative;box-shadow:0 .5rem 1.25rem #00000059}.selfhost-logo img{width:30px;height:30px}.selfhost-number{color:#fff;background-color:#2496ed;border:2px solid #1c325e;border-radius:50%;justify-content:center;align-items:center;width:1.4rem;height:1.4rem;font-size:.7rem;font-weight:700;display:flex;position:absolute;top:-.5rem;right:-.5rem}.selfhost-where{color:#7cc4ff;letter-spacing:.06em;text-transform:uppercase;font-size:.7rem;font-weight:700}.selfhost-name{color:#fff;font-size:1.05rem;font-weight:700}.selfhost-description{color:#ffffffa6;font-size:.8rem;line-height:1.3}.selfhost-step-link:hover .selfhost-name{color:#7cc4ff}.selfhost-btn{color:#fff;background-color:#2496ed}.selfhost-btn:hover{color:#fff;background-color:#1a7bc7}.selfhost-license{color:#ffffff8c;font-size:.8rem}@media (width<=575.98px){.selfhost-lede{max-width:none}.selfhost-steps{grid-template-columns:1fr}.selfhost-steps:before{display:none}}
1
+ .cli-card{background-color:#1e1e2e}.cli-terminal{background-color:#11111b;border-radius:.75rem;overflow:hidden;box-shadow:0 .75rem 1.5rem #00000059}.cli-terminal-bar{background-color:#2a2a3c;gap:.4rem;padding:.6rem .8rem;display:flex}.cli-dot{border-radius:50%;width:.7rem;height:.7rem}.cli-dot-red{background-color:#ff5f56}.cli-dot-yellow{background-color:#ffbd2e}.cli-dot-green{background-color:#27c93f}.cli-terminal-body{color:#cdd6f4;white-space:pre-wrap;word-break:break-word;background:0 0;margin:0;padding:.9rem 1rem;font-size:.8rem;line-height:1.7}.cli-prompt{color:#a6e3a1;font-weight:600}.cli-comment{color:#6c7086}.cli-cursor{vertical-align:text-bottom;background-color:#cdd6f4;width:.55em;height:1em;animation:1s step-end infinite cli-blink;display:inline-block}@keyframes cli-blink{50%{opacity:0}}@media (prefers-reduced-motion:reduce){.cli-cursor{animation:none}}.contribute-card{background:linear-gradient(135deg,#fff7ed 0%,#ffedd5 60%,#fed7aa 100%);overflow:hidden}.contribute-illustration{opacity:.95}.contribute-underline{opacity:.6;border-color:#ea580c!important}.contribute-lede{max-width:55%}.contribute-chips,.contribute-badges{flex-wrap:wrap;gap:.5rem;max-width:60%;padding-left:0;list-style:none;display:flex}.contribute-chips{margin-bottom:1.25rem}.contribute-badges{margin-bottom:0}.contribute-chip{color:#9a3412;background-color:#fff;border:1px solid #ea580c40;border-radius:999px;padding:.3rem .75rem;font-size:.8rem;font-weight:600;box-shadow:0 .25rem .75rem #ea580c1f}.contribute-btn{color:#fff;background-color:#ea580c}.contribute-btn:hover{color:#fff;background-color:#c2410c}.extensions-card{background:radial-gradient(circle at 100% 0,#7c3aed24 0%,#7c3aed00 45%),linear-gradient(135deg,#fff 0%,#f5f3ff 100%);overflow:hidden}.extensions-eyebrow{color:#6d28d9;letter-spacing:.08em;text-transform:uppercase;background-color:#ede9fe;border-radius:999px;padding:.25rem .7rem;font-size:.7rem;font-weight:700;display:inline-block}.extensions-underline{opacity:.5;border-color:#7c3aed!important}.extensions-steps{color:var(--bs-gray-800);flex-direction:column;gap:.5rem;margin:0;padding:0;font-size:.9rem;font-weight:600;list-style:none;display:flex}.extensions-steps li{align-items:center;display:flex}.extensions-step-number{color:#fff;background-color:#7c3aed;border-radius:50%;flex-shrink:0;justify-content:center;align-items:center;width:1.5rem;height:1.5rem;margin-right:.6rem;font-size:.75rem;font-weight:700;display:inline-flex}.extensions-btn{color:#fff;background-color:#7c3aed}.extensions-btn:hover{color:#fff;background-color:#6d28d9}.extensions-link{color:#6d28d9}.extensions-link:hover{color:#4c1d95}.extensions-list{flex-direction:column;gap:.6rem;margin:0 0 .75rem;padding:0;list-style:none;display:flex}.extensions-item{background-color:#fff;border:1px solid #ede9fe;border-radius:.85rem;align-items:center;gap:.85rem;padding:.55rem .85rem;text-decoration:none;transition:border-color .15s,box-shadow .15s;display:flex;box-shadow:0 .4rem 1rem #4c1d9514}.extensions-item:hover{border-color:#c4b5fd;box-shadow:0 .4rem 1.2rem #4c1d9529}.extensions-icon{background:linear-gradient(135deg,#8b5cf6 0%,#6366f1 100%);border-radius:.7rem;flex-shrink:0;justify-content:center;align-items:center;width:40px;height:40px;display:flex}.extensions-icon i{color:#fff}.extensions-text{flex-direction:column;min-width:0;display:flex}.extensions-name{color:var(--bs-gray-900);align-items:center;gap:.5rem;font-weight:700;display:flex}.extensions-badge{color:#15803d;background-color:#dcfce7;border-radius:999px;padding:.05rem .45rem;font-size:.65rem;font-weight:700}.extensions-description{color:var(--bs-gray-600);font-size:.8rem}.extensions-manifest{color:#cdd6f4;background-color:#1e1e2e;border-radius:.75rem;margin:0;padding:.75rem 1rem;font-size:.78rem;line-height:1.6}.extensions-key{color:#89b4fa}.extensions-str{color:#a6e3a1}.instructors-card{background:radial-gradient(#ffffff14 1px,#0000 1px) 0 0/18px 18px,linear-gradient(135deg,#064e3b 0%,#0f766e 55%,#14b8a6 100%);overflow:hidden}.instructors-illustration{filter:drop-shadow(0 .75rem 1.5rem #00000040)}.instructors-eyebrow{color:#422006;letter-spacing:.08em;text-transform:uppercase;background-color:#facc15;border-radius:999px;align-self:flex-start;padding:.25rem .7rem;font-size:.7rem;font-weight:700}.instructors-headline,.instructors-lede{max-width:62%}.instructors-underline{opacity:.8;border-color:#facc15!important}.instructors-lede{color:#fffc}.instructors-stats{grid-template-columns:repeat(4,minmax(0,1fr));gap:.75rem;margin-bottom:1.5rem;display:grid}.instructors-stat{-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);text-align:center;background-color:#ffffff1a;border:1px solid #ffffff2e;border-radius:.85rem;flex-direction:column-reverse;padding:.75rem .5rem;display:flex}.instructors-stat dd{color:#facc15;margin:0;font-size:1.9rem;font-weight:800;line-height:1.1}.instructors-stat dt{color:#ffffffd9;font-size:.75rem;font-weight:500}.instructors-ribbons{flex-direction:column;gap:.4rem;margin-bottom:1.5rem;display:flex}.instructors-ribbon{margin:0 -2rem;overflow:hidden;-webkit-mask-image:linear-gradient(90deg,#0000 0,#000 2.5rem calc(100% - 2.5rem),#0000 100%);mask-image:linear-gradient(90deg,#0000 0,#000 2.5rem calc(100% - 2.5rem),#0000 100%)}.instructors-ribbon-track{width:max-content;animation:60s linear infinite instructors-scroll;display:flex}.instructors-ribbon-reverse{animation-direction:reverse}.instructors-ribbon:hover .instructors-ribbon-track,.instructors-ribbon:focus-within .instructors-ribbon-track{animation-play-state:paused}.instructors-ribbon-set{gap:.5rem;margin:0;padding:.25rem .25rem .25rem .5rem;list-style:none;display:flex}.instructors-chip{color:#065f46;white-space:nowrap;background-color:#fff;border-radius:999px;padding:.35rem .8rem;font-size:.8rem;font-weight:600;display:inline-block;box-shadow:0 .25rem .75rem #00000026}.instructors-chip:hover,.instructors-chip:focus,.instructors-btn{color:#422006;background-color:#facc15}.instructors-btn:hover{color:#422006;background-color:#eab308}.instructors-formats{color:#ffffffd9;background-color:#0000002e;border-left:4px solid #facc15;border-radius:.5rem;flex-wrap:wrap;align-items:center;gap:.5rem 1rem;padding:.75rem 1rem;font-size:.8rem;display:flex}.instructors-formats-label{color:#fff;font-weight:700}.instructors-formats ul{flex-wrap:wrap;gap:.5rem 1rem;margin:0;padding:0;list-style:none;display:flex}.instructors-formats li:before{color:#facc15;content:"●";margin-right:.4rem}.instructors-formats strong{color:#facc15}@keyframes instructors-scroll{to{transform:translate(-50%)}}@media (prefers-reduced-motion:reduce){.instructors-ribbon{margin:0;-webkit-mask-image:none;mask-image:none}.instructors-ribbon-track{width:auto;animation:none}.instructors-ribbon-set{flex-wrap:wrap;padding:0}.instructors-ribbon-set[aria-hidden=true]{display:none}}@media (width<=767.98px){.instructors-headline,.instructors-lede{max-width:none}.instructors-stats{grid-template-columns:repeat(2,minmax(0,1fr))}}.integrations-card{background:linear-gradient(135deg,#3b1d8f 0%,#1c325e 100%);overflow:hidden}.integrations-illustration{opacity:.9}.integrations-lede{max-width:65%}.integrations-grid{grid-template-columns:repeat(4,minmax(0,1fr));gap:.75rem;margin-bottom:0;padding-left:0;list-style:none;display:grid}.integrations-tile{flex-direction:column;align-items:center;gap:.4rem;text-decoration:none;display:flex}.integrations-logo{background-color:#fff;border-radius:.85rem;justify-content:center;align-items:center;width:52px;height:52px;display:flex;box-shadow:0 .5rem 1.25rem #00000040}.integrations-logo img{width:28px;height:28px}.integrations-name{color:#fffc;text-align:center;font-size:.75rem;line-height:1.1}.integrations-tile:hover .integrations-name{color:#fff}.mcp-card{background:radial-gradient(circle at 100% 100%,#f472b659 0%,#f472b600 50%),linear-gradient(135deg,#4c0519 0%,#881337 55%,#be123c 100%);overflow:hidden}.mcp-eyebrow{color:#fecdd3;letter-spacing:.08em;text-transform:uppercase;background-color:#ffffff26;border-radius:999px;align-self:flex-start;padding:.25rem .7rem;font-size:.7rem;font-weight:700}.mcp-card .mcp-headline{color:#fff}.mcp-underline{opacity:.8;border-color:#fda4af!important}.mcp-lede{color:#fffc}.mcp-command{color:#ffe4e6;white-space:pre-wrap;overflow-wrap:anywhere;background-color:#00000059;border-radius:.75rem;margin:0 0 1rem;padding:.75rem .9rem;font-size:.75rem;line-height:1.5}.mcp-prompt{color:#fda4af;font-weight:700}.mcp-tools{flex-wrap:wrap;gap:.4rem;margin:0;padding:0;list-style:none;display:flex}.mcp-tools li{color:#ffe4e6;font-family:var(--bs-font-monospace,monospace);border:1px solid #ffffff40;border-radius:999px;padding:.2rem .6rem;font-size:.7rem}.mcp-btn{color:#881337;background-color:#fff}.mcp-btn:hover{color:#881337;background-color:#ffe4e6}.sdk-card{background:linear-gradient(135deg,#e6f4ff 0%,#fff1e6 100%);overflow:hidden}.sdk-lede{max-width:65%}.sdk-list{flex-direction:column;gap:.75rem;margin-bottom:0;padding-left:0;list-style:none;display:flex}.sdk-item{align-items:center;gap:.85rem;display:flex}.sdk-logo{background-color:#fff;border-radius:.75rem;flex-shrink:0;justify-content:center;align-items:center;width:44px;height:44px;display:flex;box-shadow:0 .4rem 1rem #1c325e26}.sdk-logo img{width:24px;height:24px}.sdk-text{flex-direction:column;min-width:0;display:flex}.sdk-name{color:#1c325e;font-weight:600}.sdk-name:hover{color:#f1416c}.sdk-install{color:#a6e3a1;max-width:100%;font-family:var(--bs-font-monospace,monospace);text-overflow:ellipsis;white-space:nowrap;-webkit-user-select:all;user-select:all;background-color:#1e1e2e;border-radius:.4rem;align-self:flex-start;margin-top:.2rem;padding:.1rem .45rem;font-size:.75rem;overflow:hidden}.selfhost-card{background:radial-gradient(circle at 15% 110%,#2496ed59 0%,#2496ed00 50%),radial-gradient(circle at 95% 0,#844fba59 0%,#844fba00 45%),linear-gradient(135deg,#0b1d3a 0%,#1c325e 100%);overflow:hidden}.selfhost-eyebrow{color:#7cc4ff;letter-spacing:.08em;text-transform:uppercase;background-color:#2496ed33;border-radius:999px;align-self:flex-start;padding:.25rem .7rem;font-size:.7rem;font-weight:700}.selfhost-underline{opacity:.8;border-color:#2496ed!important}.selfhost-lede{color:#ffffffbf;max-width:70%}.selfhost-steps{grid-template-columns:repeat(3,minmax(0,1fr));gap:1rem;margin:0;padding:0;list-style:none;display:grid;position:relative}.selfhost-steps:before{content:"";border-top:2px dashed #ffffff4d;position:absolute;top:28px;left:16.66%;right:16.66%}.selfhost-step-link{text-align:center;flex-direction:column;align-items:center;height:100%;padding:0 .25rem;text-decoration:none;display:flex;position:relative}.selfhost-logo{background-color:#fff;border-radius:1rem;justify-content:center;align-items:center;width:56px;height:56px;margin-bottom:.75rem;display:flex;position:relative;box-shadow:0 .5rem 1.25rem #00000059}.selfhost-logo img{width:30px;height:30px}.selfhost-number{color:#fff;background-color:#2496ed;border:2px solid #1c325e;border-radius:50%;justify-content:center;align-items:center;width:1.4rem;height:1.4rem;font-size:.7rem;font-weight:700;display:flex;position:absolute;top:-.5rem;right:-.5rem}.selfhost-where{color:#7cc4ff;letter-spacing:.06em;text-transform:uppercase;font-size:.7rem;font-weight:700}.selfhost-name{color:#fff;font-size:1.05rem;font-weight:700}.selfhost-description{color:#ffffffa6;font-size:.8rem;line-height:1.3}.selfhost-step-link:hover .selfhost-name{color:#7cc4ff}.selfhost-btn{color:#fff;background-color:#2496ed}.selfhost-btn:hover{color:#fff;background-color:#1a7bc7}.selfhost-license{color:#ffffff8c;font-size:.8rem}@media (width<=575.98px){.selfhost-lede{max-width:none}.selfhost-steps{grid-template-columns:1fr}.selfhost-steps:before{display:none}}.vscode-card{background:radial-gradient(circle at 85% 20%,#007acc59 0%,#007acc00 55%),#23272e;overflow:hidden}.vscode-title-link{color:#3794ff}.vscode-title-link:hover{color:#75beff}.vscode-underline{opacity:.5;border-color:#3794ff!important}.vscode-inline{border-radius:.3rem;font-size:.85em;color:#9cdcfe!important;background-color:#ffffff14!important;padding:.05rem .35rem!important}.vscode-features{color:#e6e6e6;grid-template-columns:repeat(2,minmax(0,1fr));gap:.5rem 1rem;margin-bottom:0;padding-left:0;font-size:.9rem;list-style:none;display:grid}.vscode-features li{align-items:flex-start;display:flex}.vscode-check{color:#3794ff;background-color:#3794ff33;border-radius:50%;flex-shrink:0;justify-content:center;align-items:center;width:1.2rem;height:1.2rem;margin-top:.1rem;margin-right:.5rem;font-size:.7rem;font-weight:700;display:inline-flex}.vscode-btn{color:#fff;background-color:#007acc}.vscode-btn:hover{color:#fff;background-color:#0062a3}.vscode-editor{background-color:#1e1e1e;border:1px solid #333842;border-radius:.75rem;overflow:hidden;box-shadow:0 1rem 2rem #00000073}.vscode-editor-bar{background-color:#2d2d2d;align-items:center;gap:.4rem;padding:0 .8rem;display:flex}.vscode-dot{border-radius:50%;width:.7rem;height:.7rem}.vscode-dot-red{background-color:#ff5f56}.vscode-dot-yellow{background-color:#ffbd2e}.vscode-dot-green{background-color:#27c93f}.vscode-tab{color:#fff;background-color:#1e1e1e;border-top:2px solid #007acc;align-items:center;gap:.4rem;margin-left:.8rem;padding:.45rem .8rem;font-size:.75rem;display:inline-flex}.vscode-tab img{width:14px;height:14px}.vscode-code{color:#d4d4d4;white-space:pre;background:0 0;margin:0;padding:.8rem 0;font-size:.78rem;line-height:1.65;overflow:visible}.vscode-ln{color:#858585;text-align:right;-webkit-user-select:none;user-select:none;width:2.2rem;padding-right:.8rem;display:inline-block}.vscode-key{color:#569cd6}.vscode-str{color:#ce9178}.vscode-squiggle{background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='6' height='3'%3E%3Cpath d='M0 2.5 L1.5 0.5 L3 2.5 L4.5 0.5 L6 2.5' fill='none' stroke='%23f14c4c' stroke-width='1'/%3E%3C/svg%3E") 0 100% repeat-x;padding-bottom:3px}.vscode-hover{color:#ccc;width:fit-content;max-width:calc(100% - 4rem);font-family:var(--bs-font-sans-serif,sans-serif);white-space:normal;background-color:#252526;border:1px solid #454545;border-left:3px solid #f14c4c;border-radius:.3rem;margin:.2rem 0 .3rem 3rem;padding:.35rem .6rem;font-size:.72rem;line-height:1.4;display:block;box-shadow:0 .4rem 1rem #00000080}.whats-new-list .badge{min-width:3rem}
2
2
  /*$vite$:1*/