@netlify/spark-ui 2.2.0 → 2.4.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 (82) hide show
  1. package/README.md +26 -3
  2. package/dist/assets/AskNetlify.css +1 -1
  3. package/dist/assets/DropZone.css +1 -1
  4. package/dist/assets/Popover.css +1 -1
  5. package/dist/assets/SearchLink.css +1 -1
  6. package/dist/assets/SearchModal.css +1 -1
  7. package/dist/assets/favicons/index.d.ts +5 -0
  8. package/dist/assets/favicons/index.test.d.ts +1 -0
  9. package/dist/assets/logos/index.d.ts +11 -0
  10. package/dist/assets/logos/index.test.d.ts +1 -0
  11. package/dist/utils/types.d.ts +16 -0
  12. package/package.json +8 -3
  13. package/packages/assets/favicons/apple-touch-icon.png +0 -0
  14. package/packages/assets/favicons/favicon.ico +0 -0
  15. package/packages/assets/favicons/icon-192-maskable.png +0 -0
  16. package/packages/assets/favicons/icon-192.png +0 -0
  17. package/packages/assets/favicons/icon-512-maskable.png +0 -0
  18. package/packages/assets/favicons/icon-512.png +0 -0
  19. package/packages/assets/favicons/icon.svg +8 -24
  20. package/packages/assets/favicons/index.test.ts +10 -0
  21. package/packages/assets/favicons/index.ts +38 -0
  22. package/packages/assets/fonts/ibm-plex-mono/IBMPlexMono-Bold.woff2 +0 -0
  23. package/packages/assets/fonts/ibm-plex-mono/IBMPlexMono-Medium.woff2 +0 -0
  24. package/packages/assets/fonts/ibm-plex-mono/IBMPlexMono-Regular.woff2 +0 -0
  25. package/packages/assets/fonts/ibm-plex-mono/IBMPlexMono-SemiBold.woff2 +0 -0
  26. package/packages/assets/fonts/ibm-plex-mono/OFL.txt +93 -0
  27. package/packages/assets/logos/index.test.ts +16 -0
  28. package/packages/assets/logos/index.ts +79 -0
  29. package/packages/assets/logos/logo-netlify-full-black.png +0 -0
  30. package/packages/assets/logos/logo-netlify-full-black.svg +4 -0
  31. package/packages/assets/logos/logo-netlify-full-darkmode.png +0 -0
  32. package/packages/assets/logos/logo-netlify-full-darkmode.svg +4 -0
  33. package/packages/assets/logos/logo-netlify-full-lightmode.png +0 -0
  34. package/packages/assets/logos/logo-netlify-full-lightmode.svg +4 -0
  35. package/packages/assets/logos/logo-netlify-monogram-black.png +0 -0
  36. package/packages/assets/logos/logo-netlify-monogram-black.svg +6 -0
  37. package/packages/assets/logos/logo-netlify-monogram-darkmode.png +0 -0
  38. package/packages/assets/logos/logo-netlify-monogram-darkmode.svg +6 -0
  39. package/packages/assets/logos/logo-netlify-monogram-lightmode.png +0 -0
  40. package/packages/assets/logos/logo-netlify-monogram-lightmode.svg +6 -0
  41. package/packages/components/Blockquote.astro +1 -1
  42. package/packages/components/Card.astro +2 -2
  43. package/packages/components/Eyebrow.astro +1 -1
  44. package/packages/components/FilterableGrid/FilterableGrid.astro +4 -4
  45. package/packages/components/HeadingBlock.astro +1 -1
  46. package/packages/components/PageHero.astro +1 -1
  47. package/packages/components/PageHeroGraphic.astro +1 -1
  48. package/packages/components/PageSection.astro +1 -1
  49. package/packages/components/TabbedContent.astro +3 -3
  50. package/packages/components/TrustBarTickerItem.astro +1 -1
  51. package/packages/components/preact/AskNetlify/AskNetlify.css +4 -4
  52. package/packages/components/preact/DropZone/DropZone.css +4 -4
  53. package/packages/components/preact/Popover/Popover.css +5 -5
  54. package/packages/components/preact/SearchModal/components/SearchLink/SearchLink.css +5 -5
  55. package/packages/components/preact/SearchModal/components/SearchModal/SearchModal.css +6 -6
  56. package/packages/styles/app/color.rgb.css +176 -0
  57. package/packages/styles/buttons.css +1 -1
  58. package/packages/styles/code-block.css +2 -2
  59. package/packages/styles/fonts.css +32 -4
  60. package/packages/styles/layout.css +2 -2
  61. package/packages/styles/tokens.compat.css +124 -1
  62. package/packages/styles/tokens.css +756 -205
  63. package/packages/tokens/app.d.ts +176 -0
  64. package/packages/tokens/app.js +176 -0
  65. package/packages/utils/types.ts +22 -0
  66. package/skills/landing-page.md +15 -10
  67. package/packages/assets/logos/logo-netlify-encapsulated-fullcolor-darkmode.svg +0 -17
  68. package/packages/assets/logos/logo-netlify-encapsulated-fullcolor-lightmode.svg +0 -17
  69. package/packages/assets/logos/logo-netlify-encapsulated-monochrome-darkmode.svg +0 -10
  70. package/packages/assets/logos/logo-netlify-encapsulated-monochrome-darkmodealt.svg +0 -10
  71. package/packages/assets/logos/logo-netlify-encapsulated-monochrome-lightmode.svg +0 -10
  72. package/packages/assets/logos/logo-netlify-large-fullcolor-darkmode.svg +0 -22
  73. package/packages/assets/logos/logo-netlify-large-fullcolor-lightmode.svg +0 -22
  74. package/packages/assets/logos/logo-netlify-large-monochrome-darkmode.svg +0 -22
  75. package/packages/assets/logos/logo-netlify-large-monochrome-lightmode.svg +0 -22
  76. package/packages/assets/logos/logo-netlify-monogram-fullcolor-darkmode.svg +0 -16
  77. package/packages/assets/logos/logo-netlify-monogram-monochrome-darkmode.svg +0 -16
  78. package/packages/assets/logos/logo-netlify-monogram-monochrome-darkmodealt.svg +0 -16
  79. package/packages/assets/logos/logo-netlify-small-fullcolor-darkmode.svg +0 -22
  80. package/packages/assets/logos/logo-netlify-small-fullcolor-lightmode.svg +0 -22
  81. package/packages/assets/logos/logo-netlify-small-monochrome-darkmode.svg +0 -22
  82. package/packages/assets/logos/logo-netlify-small-monochrome-lightmode.svg +0 -22
package/README.md CHANGED
@@ -65,6 +65,18 @@ Installing `@netlify/spark-ui` adds no other packages. Tokens, styles and assets
65
65
 
66
66
  `@netlify/spark-ui/preact` bundles the Kapa SDK, `marked`, `fflate` and `rusha`, so prefer it over the uncompiled `components` entry.
67
67
 
68
+ ## Logos
69
+
70
+ The 2026 logo kit ships in `packages/assets/logos/` and the favicon set in `packages/assets/favicons/`:
71
+
72
+ ```js
73
+ import logo from '@netlify/spark-ui/logos/logo-netlify-full-lightmode.svg';
74
+ import { LOGOS } from '@netlify/spark-ui/logos'; // LOGOS.full.lightmode.svg.src, …
75
+ import { FAVICONS } from '@netlify/spark-ui/favicons'; // FAVICONS.svg.src, …
76
+ ```
77
+
78
+ The docs site’s Logos page (`docs/src/content/docs/foundations/logos.mdx`) lists every variant, file name and import path.
79
+
68
80
  ## Design Tokens
69
81
 
70
82
  Tokens provide a shared foundation of colors, typography, spacing, and more for our sites and apps. All token information is stored in the `/tokens` directory. These aim to follow standards proposed in the [Design Tokens Format Module](https://tr.designtokens.org/format/).
@@ -73,13 +85,16 @@ Tokens are converted into CSS variables using the [terrazzo](https://terrazzo.ap
73
85
 
74
86
  - `tokens/base/`: every token, with its light-mode value in the current brand
75
87
  - `tokens/themes/dark.json`: the tokens that change in dark mode, with their dark values
88
+ - `tokens/brands/hues.dark.json`: the hues brand's own dark values, applied on top of `dark.json` by the resolver's `brandTheme` modifier
76
89
  - `tokens/brands/hues.json`: the palette ramps for the hues brand
90
+ - `tokens/brands/hues.semantic.json`: the hues brand's Play UI Kit semantics (colors, fonts), layered over `hues.json`
91
+ - `tokens/base/colors.rebrand.json`: the semantic color names the Play UI Kit adds; their base values alias the current brand. Its primitives (warm grey, off black, sky tints, alpha) live with the rest of the Hues palette in `colors.hues.json`
77
92
  - `tokens/base/app.json`: app.netlify.com's own values (fonts, sizes, weights, radii, shadows), kept out of `tokens.css`
78
93
  - `tokens/resolver.json`: how Terrazzo layers the files above. A new file in `tokens/base/` must be listed here; the build fails if it isn't.
79
94
 
80
95
  ### App tokens
81
96
 
82
- `@netlify/spark-ui/styles/app/*.css` and `@netlify/spark-ui/tokens/app` publish app.netlify.com's tokens under the names and file layout it has always read from `@netlify/netlify-design-tokens`: `color.rgb.css` has the `--colorRgbFacets*` RGB channels (with a `[data-brand="hues"]` block), `shadow.css` has `--effectShadow*`, and `tokens/app` has JS exports of hex colors, font sizes, weights, families and radii. `scripts/app-tokens-plugin.mjs` writes them during `build:tokens`.
97
+ `@netlify/spark-ui/styles/app/*.css` and `@netlify/spark-ui/tokens/app` publish app.netlify.com's tokens under the names and file layout it has always read from `@netlify/netlify-design-tokens`: `color.rgb.css` has the `--colorRgbFacets*` RGB channels (with a `[data-brand="hues"]` block) and the Hues palette as `--colorRgbHues*` (its alpha steps excluded), `shadow.css` has `--effectShadow*`, and `tokens/app` has JS exports of hex colors, font sizes, weights, families and radii. `scripts/app-tokens-plugin.mjs` writes them during `build:tokens`.
83
98
 
84
99
  To publish another CSS file, add it to `cssFiles` in `terrazzo.config.mjs` with the tokens it holds (`'palette'`, or a token ID prefix such as `'app.effect.shadow'`) and, optionally, a `format` (`'rgb'` writes a color's channels). Tokens the hues brand changes get a `[data-brand="hues"]` block automatically.
85
100
 
@@ -87,7 +102,9 @@ To publish another CSS file, add it to `cssFiles` in `terrazzo.config.mjs` with
87
102
 
88
103
  Dark mode follows `prefers-color-scheme`, and `data-theme="dark"` or `data-theme="light"` on any element overrides it for that element and its children.
89
104
 
90
- `data-brand="hues"` on `<html>` or any wrapper element switches to the hues brand. It composes with `data-theme` on the same element or nested in either direction. A wrapper can't switch back to the current brand inside a hues page.
105
+ `data-brand="hues"` on `<html>` or any wrapper element switches to the hues brand: the Hues palette mapping plus the Play UI Kit semantics and fonts. It composes with `data-theme` on the same element or nested in either direction. A wrapper can't switch back to the current brand inside a hues page.
106
+
107
+ The Play UI Kit shipped light-mode values only. Dark mode under `hues` comes from `tokens/brands/hues.dark.json`, built from the Hues palette: warm grey 950 page, warm grey 900 surfaces, warm grey 50 text. The docs tokens page lists every token to use going forward.
91
108
 
92
109
  ### Rebuild CSS token variables
93
110
 
@@ -99,9 +116,15 @@ The tokens file can also be rebuilt manually with the following command:
99
116
  npm run build:tokens
100
117
  ```
101
118
 
119
+ To see what a token change does to the published variables, compare the rebuilt file with the committed one. The report lists every variable added, changed or removed per selector, and exits non-zero when anything differs, so a change that should be additive can be checked for `0 changed, 0 removed`:
120
+
121
+ ```bash
122
+ npm run tokens:diff
123
+ ```
124
+
102
125
  ### Token Prefix and Backwards Compatibility
103
126
 
104
- All design tokens are generated with a `--ntl-` prefix (e.g., `--ntl-color-bg`, `--ntl-font-size-display-lg`). If your project still references the older unprefixed token names (e.g., `--color-bg`), you can import the compatibility file to alias them:
127
+ All design tokens are generated with a `--ntl-` prefix (e.g., `--ntl-color-bg-page`, `--ntl-font-size-heading-l`). If your project still references the older unprefixed token names (e.g., `--color-bg`), you can import the compatibility file to alias them:
105
128
 
106
129
  ```css
107
130
  @import '@netlify/spark-ui/styles/tokens.css';
@@ -1 +1 @@
1
- .n-fadeIn{opacity:0;animation:fadeIn var(--animation-duration, .3s) ease-out forwards}.n-fadeInUp{opacity:0;transform:translateY(var(--animation-transformY, 5px));animation:fadeInUp var(--animation-duration, .3s) ease-out forwards}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes fadeInUp{to{opacity:1;transform:translateY(0)}}.grecaptcha-badge{visibility:hidden}.n-ask-chat-container{opacity:0;animation:appearContainer .12s ease-in-out forwards;animation-delay:.14s}.n-ask-conversation{position:relative;display:grid;align-items:flex-end;gap:var(--space-s);height:calc(var(--n-search-container-height) + var(--n-search-footer-height));padding:var(--n-search-padding-inline);overflow-y:auto;scroll-behavior:smooth;grid-template-rows:1fr}.n-ask-form{display:flex;align-items:center;gap:var(--space-s);position:relative;height:var(--n-search-input-height);background-color:var(--search-input-bg-color)}.n-ask-form:after{content:"";display:block;position:absolute;top:0;left:0;width:100%;height:1px;background:var(--color-bg-3)}.n-ask-question{border:none;border-radius:var(--radius-pill);transform:translate(-.75rem);color:var(--color-text-1);background:none;padding:var(--space-2xs, .5rem);font-size:var(--step--1, .9rem);font-weight:var(--font-weight-regular);text-align:left;text-wrap:pretty;cursor:pointer;display:flex;align-items:center;gap:var(--space-2xs);transition:background-color .2s ease-out}.n-ask-question [data-icon=caretRight]{opacity:0;height:.8em;color:var(--color-text-weaker);transform:translate(-3px);transition:transform .2s ease-out}.n-ask-question:hover{background-color:var(--n-search-color-bg-2)}.n-ask-question:hover [data-icon=caretRight]{opacity:1;transform:translate(0)}.n-ask-question-list{padding:0}.n-ask-question-list .n-ask-question-list-item{position:relative;width:fit-content;opacity:0;transform:translateY(10px);animation:fadeInUp .5s forwards}.n-ask-message{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--space-s);font-size:var(--font-size-text-md, 1rem)}.n-ask-message:first-of-type{margin-block-start:var(--space-2xl)}.n-ask-message-bubble{width:fit-content;max-width:85%;padding:var(--space-xs) var(--space-s);background:var(--search-answer-message-color);border-radius:var(--radius-l);font-size:var(--step-0)}.n-ask-user-message{margin-inline-start:auto;background:var(--search-user-message-color)}.n-ask-sources{margin-block-start:var(--space-xs)}.n-ask-sources-title{font-size:var(--step-0);font-weight:var(--font-weight-bold)}.n-ask-sources a{font-size:var(--step--1)}.n-ask-sources details summary::marker{display:none;content:none}.n-ask-sources details{background:var(--search-source-list-color);padding:var(--space-xs) var(--space-xs);border-radius:var(--radius-l)}.n-ask-sources details summary{display:flex;align-items:center;justify-content:space-between;gap:var(--space-xs);cursor:pointer}.n-ask-sources details ul{margin-block-start:var(--space-3xs)}.n-ask-sources [data-icon=caretRight]{width:.8em;display:inline-block;transform:rotate(90deg);height:auto;color:var(--color-text-weaker)}.n-ask-sources details[open] [data-icon=caretRight]{transform:rotate(270deg)}.n-ask-action-bar{margin-block-start:var(--space-m)}.n-ask-action-bar button{display:grid;border:none}.n-ask-action-bar button svg{pointer-events:none}.n-ask-action-bar .n-popover{--n-popover-padding: var(--space-3xs) var(--space-2xs);--n-popover-bottom: 125%}.n-ask-action-bar [id*=icon-]{width:auto;height:1rem}.n-ask-input{border:none;outline:none;padding-inline:var(--n-search-padding-inline)}.n-ask-form-submit{display:flex;padding:.7rem;margin-inline-end:var(--space-2xs);border:none;border-radius:var(--radius-pill);background:var(--search-submit-btn-bg-color);color:var(--neutral-000);transition:background-color .15s ease-out}.n-ask-form-submit>svg{width:1rem;height:auto;aspect-ratio:1 / 1;border-radius:1.5px;transition:opacity .15s ease-out}.n-ask-form-submit[disabled]{background:var(--neutral-500)}.n-ask-form-submit[disabled]>*{opacity:.5}button.n-ask-button-back{position:absolute;z-index:1;width:fit-content;margin:1rem;padding:var(--space-xs) var(--space-s);background:var(--search-back-btn-bg-color);border:.5px solid var(--color-bg-3);border-radius:var(--radius-pill);font-size:var(--font-size-text-md, 1rem);font-weight:var(--font-weight-semibold, 500);color:var(--color-text-1);cursor:pointer;line-height:var(--line-height-none, 1)}button.n-ask-button-back [data-icon=caretRight]{color:var(--color-text-weak);transform:rotate(180deg)}.n-ask-prose{font-size:var(--step--0)}.n-ask-prose>*+*{margin-top:var(--flow-space, var(--space-s))}.n-ask-prose :where(ol,ul,li)>*+*{margin-top:var(--flow-space, var(--space-3xs))}.n-ask-prose h1,.n-ask-prose h2,.n-ask-prose h3{font-size:var(--step-1);font-weight:var(--font-weight-bold)}.n-ask-prose h4,.n-ask-prose h5,.n-ask-prose h6{font-size:var(--step-0);font-weight:var(--font-weight-bold)}.n-ask-prose pre{max-width:100%;background:var(--neutral-light-700, var(--neutral-700));border-radius:var(--radius-m);box-sizing:border-box;color:var(--neutral-100);color-scheme:dark;overflow-x:auto}.n-ask-prose code{overflow-x:auto;padding:var(--space-s)}.n-ask-prose code[class*=language-],.n-ask-prose pre[class*=language-]{display:block;font-size:var(--font-size-text-xs)}.n-ask-message-loader{width:2.5rem;height:auto;display:block;color:var(--search-loading-color)}.n-ask-message-loader :where(#ask-netlify-tick-1,#ask-netlify-tick-2,#ask-netlify-tick-3){opacity:0;animation:fadeIn .8s ease-in-out infinite}.n-ask-message-loader #ask-netlify-tick-1{animation-delay:.1s}.n-ask-message-loader #ask-netlify-tick-2{animation-delay:.2s}.n-ask-message-loader #ask-netlify-tick-3{animation-delay:.3s}.n-ask-message-loader :where(#ask-netlify-eyelid-left,#ask-netlify-eyelid-right){--n-ask-netlify-eyelid-color: var(--search-bg-color);transform-origin:top center;transform:scaleY(1.035);animation:askEyeBlink 4s infinite;animation-delay:1s}@keyframes askEyeBlink{0%,5%{transform:scaleY(1.035)}6%,10%{transform:scaleY(1.3)}11%,15%{transform:scaleY(1.035)}16%,20%{transform:scaleY(1.3)}21%,to{transform:scaleY(1.035)}}
1
+ .n-fadeIn{opacity:0;animation:fadeIn var(--animation-duration, .3s) ease-out forwards}.n-fadeInUp{opacity:0;transform:translateY(var(--animation-transformY, 5px));animation:fadeInUp var(--animation-duration, .3s) ease-out forwards}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes fadeInUp{to{opacity:1;transform:translateY(0)}}.grecaptcha-badge{visibility:hidden}.n-ask-chat-container{opacity:0;animation:appearContainer .12s ease-in-out forwards;animation-delay:.14s}.n-ask-conversation{position:relative;display:grid;align-items:flex-end;gap:var(--space-s);height:calc(var(--n-search-container-height) + var(--n-search-footer-height));padding:var(--n-search-padding-inline);overflow-y:auto;scroll-behavior:smooth;grid-template-rows:1fr}.n-ask-form{display:flex;align-items:center;gap:var(--space-s);position:relative;height:var(--n-search-input-height);background-color:var(--search-input-bg-color)}.n-ask-form:after{content:"";display:block;position:absolute;top:0;left:0;width:100%;height:1px;background:var(--ntl-color-bg-muted)}.n-ask-question{border:none;border-radius:var(--radius-pill);transform:translate(-.75rem);color:var(--ntl-color-text);background:none;padding:var(--space-2xs, .5rem);font-size:var(--step--1, .9rem);font-weight:var(--font-weight-regular);text-align:left;text-wrap:pretty;cursor:pointer;display:flex;align-items:center;gap:var(--space-2xs);transition:background-color .2s ease-out}.n-ask-question [data-icon=caretRight]{opacity:0;height:.8em;color:var(--color-text-weaker);transform:translate(-3px);transition:transform .2s ease-out}.n-ask-question:hover{background-color:var(--n-search-color-bg-2)}.n-ask-question:hover [data-icon=caretRight]{opacity:1;transform:translate(0)}.n-ask-question-list{padding:0}.n-ask-question-list .n-ask-question-list-item{position:relative;width:fit-content;opacity:0;transform:translateY(10px);animation:fadeInUp .5s forwards}.n-ask-message{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--space-s);font-size:var(--font-size-text-md, 1rem)}.n-ask-message:first-of-type{margin-block-start:var(--space-2xl)}.n-ask-message-bubble{width:fit-content;max-width:85%;padding:var(--space-xs) var(--space-s);background:var(--search-answer-message-color);border-radius:var(--radius-l);font-size:var(--step-0)}.n-ask-user-message{margin-inline-start:auto;background:var(--search-user-message-color)}.n-ask-sources{margin-block-start:var(--space-xs)}.n-ask-sources-title{font-size:var(--step-0);font-weight:var(--font-weight-bold)}.n-ask-sources a{font-size:var(--step--1)}.n-ask-sources details summary::marker{display:none;content:none}.n-ask-sources details{background:var(--search-source-list-color);padding:var(--space-xs) var(--space-xs);border-radius:var(--radius-l)}.n-ask-sources details summary{display:flex;align-items:center;justify-content:space-between;gap:var(--space-xs);cursor:pointer}.n-ask-sources details ul{margin-block-start:var(--space-3xs)}.n-ask-sources [data-icon=caretRight]{width:.8em;display:inline-block;transform:rotate(90deg);height:auto;color:var(--color-text-weaker)}.n-ask-sources details[open] [data-icon=caretRight]{transform:rotate(270deg)}.n-ask-action-bar{margin-block-start:var(--space-m)}.n-ask-action-bar button{display:grid;border:none}.n-ask-action-bar button svg{pointer-events:none}.n-ask-action-bar .n-popover{--n-popover-padding: var(--space-3xs) var(--space-2xs);--n-popover-bottom: 125%}.n-ask-action-bar [id*=icon-]{width:auto;height:1rem}.n-ask-input{border:none;outline:none;padding-inline:var(--n-search-padding-inline)}.n-ask-form-submit{display:flex;padding:.7rem;margin-inline-end:var(--space-2xs);border:none;border-radius:var(--radius-pill);background:var(--search-submit-btn-bg-color);color:var(--neutral-000);transition:background-color .15s ease-out}.n-ask-form-submit>svg{width:1rem;height:auto;aspect-ratio:1 / 1;border-radius:1.5px;transition:opacity .15s ease-out}.n-ask-form-submit[disabled]{background:var(--neutral-500)}.n-ask-form-submit[disabled]>*{opacity:.5}button.n-ask-button-back{position:absolute;z-index:1;width:fit-content;margin:1rem;padding:var(--space-xs) var(--space-s);background:var(--search-back-btn-bg-color);border:.5px solid var(--ntl-color-border);border-radius:var(--radius-pill);font-size:var(--font-size-text-md, 1rem);font-weight:var(--font-weight-semibold, 500);color:var(--ntl-color-text);cursor:pointer;line-height:var(--line-height-none, 1)}button.n-ask-button-back [data-icon=caretRight]{color:var(--color-text-weak);transform:rotate(180deg)}.n-ask-prose{font-size:var(--step--0)}.n-ask-prose>*+*{margin-top:var(--flow-space, var(--space-s))}.n-ask-prose :where(ol,ul,li)>*+*{margin-top:var(--flow-space, var(--space-3xs))}.n-ask-prose h1,.n-ask-prose h2,.n-ask-prose h3{font-size:var(--step-1);font-weight:var(--font-weight-bold)}.n-ask-prose h4,.n-ask-prose h5,.n-ask-prose h6{font-size:var(--step-0);font-weight:var(--font-weight-bold)}.n-ask-prose pre{max-width:100%;background:var(--neutral-light-700, var(--neutral-700));border-radius:var(--radius-m);box-sizing:border-box;color:var(--neutral-100);color-scheme:dark;overflow-x:auto}.n-ask-prose code{overflow-x:auto;padding:var(--space-s)}.n-ask-prose code[class*=language-],.n-ask-prose pre[class*=language-]{display:block;font-size:var(--font-size-text-xs)}.n-ask-message-loader{width:2.5rem;height:auto;display:block;color:var(--search-loading-color)}.n-ask-message-loader :where(#ask-netlify-tick-1,#ask-netlify-tick-2,#ask-netlify-tick-3){opacity:0;animation:fadeIn .8s ease-in-out infinite}.n-ask-message-loader #ask-netlify-tick-1{animation-delay:.1s}.n-ask-message-loader #ask-netlify-tick-2{animation-delay:.2s}.n-ask-message-loader #ask-netlify-tick-3{animation-delay:.3s}.n-ask-message-loader :where(#ask-netlify-eyelid-left,#ask-netlify-eyelid-right){--n-ask-netlify-eyelid-color: var(--search-bg-color);transform-origin:top center;transform:scaleY(1.035);animation:askEyeBlink 4s infinite;animation-delay:1s}@keyframes askEyeBlink{0%,5%{transform:scaleY(1.035)}6%,10%{transform:scaleY(1.3)}11%,15%{transform:scaleY(1.035)}16%,20%{transform:scaleY(1.3)}21%,to{transform:scaleY(1.035)}}
@@ -1 +1 @@
1
- .n-fadeIn{opacity:0;animation:fadeIn var(--animation-duration, .3s) ease-out forwards}.n-fadeInUp{opacity:0;transform:translateY(var(--animation-transformY, 5px));animation:fadeInUp var(--animation-duration, .3s) ease-out forwards}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes fadeInUp{to{opacity:1;transform:translateY(0)}}.n-dropzone{--n-dropzone-accent: var(--color-brand-primary, #0e7fe1);--n-dropzone-radius: var(--radius-2xl, 1rem);box-sizing:border-box;position:relative;min-height:4rem;color:var(--color-text-default, #14161a);border:2px dashed var(--color-border-default, rgba(0, 0, 0, .15));border-radius:var(--n-dropzone-radius);outline:none;cursor:pointer;transition:border-color .2s ease-out,background-color .2s ease-out,box-shadow .2s ease-out}.n-dropzone:focus-visible{border-color:var(--n-dropzone-accent);box-shadow:0 0 0 3px color-mix(in srgb,var(--n-dropzone-accent) 40%,transparent)}.n-dropzone.is-active{border-color:var(--n-dropzone-accent);box-shadow:0 0 0 4px color-mix(in srgb,var(--n-dropzone-accent) 18%,transparent)}.n-dropzone.is-busy{border-style:solid;border-color:var(--color-border-subtle, rgba(0, 0, 0, .08))}.n-dropzone-content{transition:opacity .15s ease-out;pointer-events:none}.n-dropzone.is-active:not(.is-bare) .n-dropzone-content,.n-dropzone.is-busy:not(.is-bare) .n-dropzone-content{opacity:0}.n-dropzone-overlay{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--space-s, 1rem);padding:var(--space-l, 1.5rem);text-align:center;border-radius:inherit;pointer-events:none;background:color-mix(in srgb,var(--n-dropzone-accent) 10%,transparent)}.n-dropzone.is-busy .n-dropzone-overlay,.n-dropzone[data-state=error] .n-dropzone-overlay{pointer-events:auto;background:color-mix(in srgb,var(--color-bg, #fff) 88%,transparent);-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.n-dropzone-hint{margin:0;font-size:1.0625rem;font-weight:var(--font-weight-semibold, 600);color:var(--n-dropzone-accent)}.n-dropzone-title{margin:0;font-size:1.125rem;font-weight:var(--font-weight-semibold, 600);line-height:var(--line-height-snug, 1.3)}.n-dropzone-title--error{color:var(--color-invalid-text, #d00)}.n-dropzone-subtitle{margin:0;max-width:30rem;font-size:.9375rem;color:var(--color-text-weak, #5c6570);line-height:var(--line-height-text, 1.5)}.n-dropzone-loading{display:flex;flex-direction:column;align-items:center;gap:var(--space-s, 1rem)}.n-dropzone-spinner{width:2.25rem;height:2.25rem;border-radius:var(--radius-pill, 999px);border:3px solid color-mix(in srgb,var(--n-dropzone-accent) 22%,transparent);border-top-color:var(--n-dropzone-accent);animation:dropSpin .72s linear infinite}@keyframes dropSpin{to{transform:rotate(360deg)}}.n-dropzone-nudge{display:block;font-size:.8125rem;color:var(--color-text-weaker, #8a929c)}.n-dropzone-progress{width:min(22rem,100%);height:.5rem;border-radius:var(--radius-pill, 999px);background:var(--color-bg-3, rgba(0, 0, 0, .08));overflow:hidden}.n-dropzone-progress-bar{height:100%;border-radius:inherit;background:var(--n-dropzone-accent);transition:width .3s cubic-bezier(.22,1,.36,1)}.n-dropzone-browse{display:inline-flex;align-items:center;justify-content:center;padding:var(--space-2xs, .5rem) var(--space-m, 1.25rem);border:none;border-radius:var(--radius-pill, 999px);background:var(--n-dropzone-accent);color:var(--neutral-000, #fff);font-size:.9375rem;font-weight:var(--font-weight-semibold, 600);line-height:var(--line-height-none, 1);text-decoration:none;cursor:pointer;transition:background-color .15s ease-out,transform .12s ease-out}.n-dropzone-browse:hover{background:var(--color-brand-primary-hover, #0b6bc0);transform:translateY(-1px)}.n-dropzone-browse:active{transform:translateY(0)}.n-dropzone-warning{margin:0;padding:var(--space-2xs, .5rem) var(--space-s, 1rem);max-width:32rem;border-radius:var(--radius-m, .5rem);background:var(--color-warning-bg, #fdf3d7);color:var(--color-warning-text, #7a5b00);font-size:.8125rem}@media (prefers-reduced-motion: reduce){.n-dropzone,.n-dropzone-overlay,.n-dropzone-spinner,.n-dropzone-progress-bar{animation:none!important;transition:none!important}.n-dropzone-spinner{border-top-color:var(--n-dropzone-accent)}}
1
+ .n-fadeIn{opacity:0;animation:fadeIn var(--animation-duration, .3s) ease-out forwards}.n-fadeInUp{opacity:0;transform:translateY(var(--animation-transformY, 5px));animation:fadeInUp var(--animation-duration, .3s) ease-out forwards}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes fadeInUp{to{opacity:1;transform:translateY(0)}}.n-dropzone{--n-dropzone-accent: var(--color-brand-primary, #0e7fe1);--n-dropzone-radius: var(--radius-2xl, 1rem);box-sizing:border-box;position:relative;min-height:4rem;color:var(--ntl-color-text, #14161a);border:2px dashed var(--ntl-color-border, rgba(0, 0, 0, .15));border-radius:var(--n-dropzone-radius);outline:none;cursor:pointer;transition:border-color .2s ease-out,background-color .2s ease-out,box-shadow .2s ease-out}.n-dropzone:focus-visible{border-color:var(--n-dropzone-accent);box-shadow:0 0 0 3px color-mix(in srgb,var(--n-dropzone-accent) 40%,transparent)}.n-dropzone.is-active{border-color:var(--n-dropzone-accent);box-shadow:0 0 0 4px color-mix(in srgb,var(--n-dropzone-accent) 18%,transparent)}.n-dropzone.is-busy{border-style:solid;border-color:var(--color-border-subtle, rgba(0, 0, 0, .08))}.n-dropzone-content{transition:opacity .15s ease-out;pointer-events:none}.n-dropzone.is-active:not(.is-bare) .n-dropzone-content,.n-dropzone.is-busy:not(.is-bare) .n-dropzone-content{opacity:0}.n-dropzone-overlay{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--space-s, 1rem);padding:var(--space-l, 1.5rem);text-align:center;border-radius:inherit;pointer-events:none;background:color-mix(in srgb,var(--n-dropzone-accent) 10%,transparent)}.n-dropzone.is-busy .n-dropzone-overlay,.n-dropzone[data-state=error] .n-dropzone-overlay{pointer-events:auto;background:color-mix(in srgb,var(--color-bg, #fff) 88%,transparent);-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.n-dropzone-hint{margin:0;font-size:1.0625rem;font-weight:var(--font-weight-semibold, 600);color:var(--n-dropzone-accent)}.n-dropzone-title{margin:0;font-size:1.125rem;font-weight:var(--font-weight-semibold, 600);line-height:var(--ntl-line-height-label)}.n-dropzone-title--error{color:var(--color-invalid-text, #d00)}.n-dropzone-subtitle{margin:0;max-width:30rem;font-size:.9375rem;color:var(--color-text-weak, #5c6570);line-height:var(--line-height-text, 1.5)}.n-dropzone-loading{display:flex;flex-direction:column;align-items:center;gap:var(--space-s, 1rem)}.n-dropzone-spinner{width:2.25rem;height:2.25rem;border-radius:var(--radius-pill, 999px);border:3px solid color-mix(in srgb,var(--n-dropzone-accent) 22%,transparent);border-top-color:var(--n-dropzone-accent);animation:dropSpin .72s linear infinite}@keyframes dropSpin{to{transform:rotate(360deg)}}.n-dropzone-nudge{display:block;font-size:.8125rem;color:var(--color-text-weaker, #8a929c)}.n-dropzone-progress{width:min(22rem,100%);height:.5rem;border-radius:var(--radius-pill, 999px);background:var(--ntl-color-bg-muted, rgba(0, 0, 0, .08));overflow:hidden}.n-dropzone-progress-bar{height:100%;border-radius:inherit;background:var(--n-dropzone-accent);transition:width .3s cubic-bezier(.22,1,.36,1)}.n-dropzone-browse{display:inline-flex;align-items:center;justify-content:center;padding:var(--space-2xs, .5rem) var(--space-m, 1.25rem);border:none;border-radius:var(--radius-pill, 999px);background:var(--n-dropzone-accent);color:var(--neutral-000, #fff);font-size:.9375rem;font-weight:var(--font-weight-semibold, 600);line-height:var(--line-height-none, 1);text-decoration:none;cursor:pointer;transition:background-color .15s ease-out,transform .12s ease-out}.n-dropzone-browse:hover{background:var(--color-brand-primary-hover, #0b6bc0);transform:translateY(-1px)}.n-dropzone-browse:active{transform:translateY(0)}.n-dropzone-warning{margin:0;padding:var(--space-2xs, .5rem) var(--space-s, 1rem);max-width:32rem;border-radius:var(--radius-m, .5rem);background:var(--color-warning-bg, #fdf3d7);color:var(--color-warning-text, #7a5b00);font-size:.8125rem}@media (prefers-reduced-motion: reduce){.n-dropzone,.n-dropzone-overlay,.n-dropzone-spinner,.n-dropzone-progress-bar{animation:none!important;transition:none!important}.n-dropzone-spinner{border-top-color:var(--n-dropzone-accent)}}
@@ -1 +1 @@
1
- .n-popover-container{position:relative;display:inline-block;font-size:var(--font-size-text-xs)}.n-popover-trigger{display:block;background-color:transparent;border:none;padding:0;font:inherit;color:var(--color-text-weak);cursor:pointer}.n-popover{position:absolute;background-color:var(--color-bg-2);color:var(--color-text);padding:var(--n-popover-padding, var(--space-xs) var(--space-s));border-radius:var(--radius-s);opacity:0;pointer-events:none;transition:opacity .2s ease-in-out;z-index:10}.n-popover:after{content:"";position:absolute;border-style:solid}.n-popover-container:hover .n-popover{opacity:1;pointer-events:auto}.n-popover-top .n-popover{bottom:var(--n-popover-bottom, 145%);left:50%;transform:translate(-50%);width:max-content;max-width:var(--n-popover-width, 255px);box-shadow:var(--shadow-light)}.n-popover-top .n-popover:after{top:100%;left:50%;margin-left:-5px;border-width:5px;border-color:var(--color-bg-2) transparent transparent transparent}.n-popover-bottom .n-popover{top:145%;left:50%;transform:translate(-50%)}.n-popover-bottom .n-popover:after{bottom:100%;left:50%;margin-left:-5px;border-width:5px;border-color:transparent transparent var(--color-bg-2) transparent}.n-popover-left .n-popover{right:125%;top:50%;transform:translateY(-50%)}.n-popover-left .n-popover:after{top:50%;left:100%;margin-top:-5px;border-width:5px;border-color:transparent transparent transparent var(--color-bg-2)}.n-popover-right .n-popover{left:125%;top:50%;transform:translateY(-50%)}.n-popover-right .n-popover:after{top:50%;right:100%;margin-top:-5px;border-width:5px;border-color:transparent var(--color-bg-2) transparent transparent}
1
+ .n-popover-container{position:relative;display:inline-block;font-size:var(--font-size-text-xs)}.n-popover-trigger{display:block;background-color:transparent;border:none;padding:0;font:inherit;color:var(--color-text-weak);cursor:pointer}.n-popover{position:absolute;background-color:var(--ntl-color-bg-subtle);color:var(--color-text);padding:var(--n-popover-padding, var(--space-xs) var(--space-s));border-radius:var(--radius-s);opacity:0;pointer-events:none;transition:opacity .2s ease-in-out;z-index:10}.n-popover:after{content:"";position:absolute;border-style:solid}.n-popover-container:hover .n-popover{opacity:1;pointer-events:auto}.n-popover-top .n-popover{bottom:var(--n-popover-bottom, 145%);left:50%;transform:translate(-50%);width:max-content;max-width:var(--n-popover-width, 255px);box-shadow:var(--shadow-light)}.n-popover-top .n-popover:after{top:100%;left:50%;margin-left:-5px;border-width:5px;border-color:var(--ntl-color-bg-subtle) transparent transparent transparent}.n-popover-bottom .n-popover{top:145%;left:50%;transform:translate(-50%)}.n-popover-bottom .n-popover:after{bottom:100%;left:50%;margin-left:-5px;border-width:5px;border-color:transparent transparent var(--ntl-color-bg-subtle) transparent}.n-popover-left .n-popover{right:125%;top:50%;transform:translateY(-50%)}.n-popover-left .n-popover:after{top:50%;left:100%;margin-top:-5px;border-width:5px;border-color:transparent transparent transparent var(--ntl-color-bg-subtle)}.n-popover-right .n-popover{left:125%;top:50%;transform:translateY(-50%)}.n-popover-right .n-popover:after{top:50%;right:100%;margin-top:-5px;border-width:5px;border-color:transparent var(--ntl-color-bg-subtle) transparent transparent}
@@ -1 +1 @@
1
- .n-search-link{--n-search-icon-size: 1.25em;box-sizing:border-box;display:flex;justify-content:space-between;flex-wrap:wrap;gap:var(--space-s, 1rem);align-items:center;padding:var(--n-search-link-padding-block, 1em) var(--n-search-link-padding-inline, 1em);font-size:var(--font-size-text-sm);font-weight:var(--font-weight-regular);text-decoration:none;cursor:pointer;width:100%;border:none;text-align:left;outline:none;border-radius:var(--radius-l)}.n-search-link-body{flex:1;width:80%;color:var(--color-text-weak);text-wrap:pretty}.n-search-link:is(:hover,:focus-visible){background:var(--n-search-color-bg-2)}.n-search-link:is(:hover,:focus-visible) .n-search-link-icon [data-icon=caretRight]{opacity:1}.n-search-link:is(:hover,:focus-visible) .n-search-link-icon :where(#ask-netlify-eyelid-left,#ask-netlify-eyelid-right){--n-ask-netlify-eyelid-color: var(--n-search-color-bg-2);animation:askEyeBlink 4s infinite;animation-delay:.2s}.n-search-link-icon :where(#ask-netlify-eyelid-left,#ask-netlify-eyelid-right){--n-ask-netlify-eyelid-color: var(--search-bg-color)}.n-search-link-title{font-weight:var(--font-weight-medium);color:var(--color-text-1);line-height:1.5}.n-search-link-excerpt{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;color:var(--color-text-weak);line-height:1.3;font-size:.9em;margin-block-start:var(--space-3xs)}.n-search-link-excerpt mark{color:var(--mark-color, currentColor);background-color:var(--mark-bg, var(--color-highlight))}.n-search-link-icon,.n-search-link-icon svg{display:flex;width:var(--n-search-icon-size);height:var(--n-search-icon-size);color:var(--n-search-color-icon)}.n-search-link-icon [data-icon=caretRight]{width:1em;opacity:0}.n-search-link-label{margin-inline-end:var(--space-3xs)}.n-search-link-badge{display:inline-block;width:max-content;font-size:.7em;padding:.1em .4em;position:relative;bottom:.3em;color:var(--n-search-link-badge-text-color, var(--color-disabled-text));background:var(--n-search-link-badge-color, var(--color-disabled-bg));border:1px solid var(--n-search-link-badge-border, var(--color-disabled-border));border-radius:3px}.n-search-link-badge[data-resource=blog]{--n-search-link-badge-color: var(--color-info-bg);--n-search-link-badge-text-color: var(--color-info-text);--n-search-link-badge-border: var(--color-info-border)}.n-search-link-badge[data-resource=changelog]{--n-search-link-badge-color: var(--color-warning-bg);--n-search-link-badge-text-color: var(--color-warning-text);--n-search-link-badge-border: var(--color-warning-border)}.n-search-link-badge[data-resource=guide]{--n-search-link-badge-color: var(--color-highlight-bg);--n-search-link-badge-text-color: var(--color-highlight-text);--n-search-link-badge-border: var(--color-highlight-border)}.n-search-link-badge[data-resource=knowledge-base]{--n-search-link-badge-color: var(--color-success-bg);--n-search-link-badge-text-color: var(--color-success-text);--n-search-link-badge-border: var(--color-success-border)}
1
+ .n-search-link{--n-search-icon-size: 1.25em;box-sizing:border-box;display:flex;justify-content:space-between;flex-wrap:wrap;gap:var(--space-s, 1rem);align-items:center;padding:var(--n-search-link-padding-block, 1em) var(--n-search-link-padding-inline, 1em);font-size:var(--font-size-text-sm);font-weight:var(--font-weight-regular);text-decoration:none;cursor:pointer;width:100%;border:none;text-align:left;outline:none;border-radius:var(--radius-l)}.n-search-link-body{flex:1;width:80%;color:var(--color-text-weak);text-wrap:pretty}.n-search-link:is(:hover,:focus-visible){background:var(--n-search-color-bg-2)}.n-search-link:is(:hover,:focus-visible) .n-search-link-icon [data-icon=caretRight]{opacity:1}.n-search-link:is(:hover,:focus-visible) .n-search-link-icon :where(#ask-netlify-eyelid-left,#ask-netlify-eyelid-right){--n-ask-netlify-eyelid-color: var(--n-search-color-bg-2);animation:askEyeBlink 4s infinite;animation-delay:.2s}.n-search-link-icon :where(#ask-netlify-eyelid-left,#ask-netlify-eyelid-right){--n-ask-netlify-eyelid-color: var(--search-bg-color)}.n-search-link-title{font-weight:var(--font-weight-medium);color:var(--ntl-color-text);line-height:1.5}.n-search-link-excerpt{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;color:var(--color-text-weak);line-height:1.3;font-size:.9em;margin-block-start:var(--space-3xs)}.n-search-link-excerpt mark{color:var(--mark-color, currentColor);background-color:var(--mark-bg, var(--ntl-color-highlight-bg))}.n-search-link-icon,.n-search-link-icon svg{display:flex;width:var(--n-search-icon-size);height:var(--n-search-icon-size);color:var(--n-search-color-icon)}.n-search-link-icon [data-icon=caretRight]{width:1em;opacity:0}.n-search-link-label{margin-inline-end:var(--space-3xs)}.n-search-link-badge{display:inline-block;width:max-content;font-size:.7em;padding:.1em .4em;position:relative;bottom:.3em;color:var(--n-search-link-badge-text-color, var(--color-disabled-text));background:var(--n-search-link-badge-color, var(--color-disabled-bg));border:1px solid var(--n-search-link-badge-border, var(--color-disabled-border));border-radius:3px}.n-search-link-badge[data-resource=blog]{--n-search-link-badge-color: var(--color-info-bg);--n-search-link-badge-text-color: var(--color-info-text);--n-search-link-badge-border: var(--color-info-border)}.n-search-link-badge[data-resource=changelog]{--n-search-link-badge-color: var(--color-warning-bg);--n-search-link-badge-text-color: var(--color-warning-text);--n-search-link-badge-border: var(--color-warning-border)}.n-search-link-badge[data-resource=guide]{--n-search-link-badge-color: var(--ntl-color-highlight-bg);--n-search-link-badge-text-color: var(--ntl-color-highlight-text);--n-search-link-badge-border: var(--ntl-color-highlight-border)}.n-search-link-badge[data-resource=knowledge-base]{--n-search-link-badge-color: var(--color-success-bg);--n-search-link-badge-text-color: var(--color-success-text);--n-search-link-badge-border: var(--color-success-border)}
@@ -1 +1 @@
1
- .n-keyboard-key{--n-key-text-size: .8em;--n-key-border-radius: 6px;--n-key-text-color: currentColor;--n-key-bg-color: transparent;display:flex;gap:calc(var(--space-3xs) * .5);font-size:var(--n-key-text-size);color:var(--n-key-text-color);background:var(--n-key-bg-color);border:1px solid currentColor;border-radius:var(--n-key-border-radius);padding:var(--n-key-padding-block, .05em) var(--n-key-padding-inline, .3em)}.n-search-heading{--n-search-heading-weight: var(--font-weight-semibold, 400);--n-search-heading-size: var(--font-size-text-xs, 13px);--n-search-heading-color: var(--color-text-weak, #757575);font-size:var(--n-search-heading-size);font-weight:var(--n-search-heading-weight);font-family:var(--font-family-mono);color:var(--n-search-heading-color);padding-inline:var(--space-xs);margin-block:var(--space-xs);letter-spacing:.2px}.n-search-link{--n-search-icon-size: 1.25em;box-sizing:border-box;display:flex;justify-content:space-between;flex-wrap:wrap;gap:var(--space-s, 1rem);align-items:center;padding:var(--n-search-link-padding-block, 1em) var(--n-search-link-padding-inline, 1em);font-size:var(--font-size-text-sm);font-weight:var(--font-weight-regular);text-decoration:none;cursor:pointer;width:100%;border:none;text-align:left;outline:none;border-radius:var(--radius-l)}.n-search-link-body{flex:1;width:80%;color:var(--color-text-weak);text-wrap:pretty}.n-search-link:is(:hover,:focus-visible){background:var(--n-search-color-bg-2)}.n-search-link:is(:hover,:focus-visible) .n-search-link-icon [data-icon=caretRight]{opacity:1}.n-search-link:is(:hover,:focus-visible) .n-search-link-icon :where(#ask-netlify-eyelid-left,#ask-netlify-eyelid-right){--n-ask-netlify-eyelid-color: var(--n-search-color-bg-2);animation:askEyeBlink 4s infinite;animation-delay:.2s}.n-search-link-icon :where(#ask-netlify-eyelid-left,#ask-netlify-eyelid-right){--n-ask-netlify-eyelid-color: var(--search-bg-color)}.n-search-link-title{font-weight:var(--font-weight-medium);color:var(--color-text-1);line-height:1.5}.n-search-link-excerpt{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;color:var(--color-text-weak);line-height:1.3;font-size:.9em;margin-block-start:var(--space-3xs)}.n-search-link-excerpt mark{color:var(--mark-color, currentColor);background-color:var(--mark-bg, var(--color-highlight))}.n-search-link-icon,.n-search-link-icon svg{display:flex;width:var(--n-search-icon-size);height:var(--n-search-icon-size);color:var(--n-search-color-icon)}.n-search-link-icon [data-icon=caretRight]{width:1em;opacity:0}.n-search-link-label{margin-inline-end:var(--space-3xs)}.n-search-link-badge{display:inline-block;width:max-content;font-size:.7em;padding:.1em .4em;position:relative;bottom:.3em;color:var(--n-search-link-badge-text-color, var(--color-disabled-text));background:var(--n-search-link-badge-color, var(--color-disabled-bg));border:1px solid var(--n-search-link-badge-border, var(--color-disabled-border));border-radius:3px}.n-search-link-badge[data-resource=blog]{--n-search-link-badge-color: var(--color-info-bg);--n-search-link-badge-text-color: var(--color-info-text);--n-search-link-badge-border: var(--color-info-border)}.n-search-link-badge[data-resource=changelog]{--n-search-link-badge-color: var(--color-warning-bg);--n-search-link-badge-text-color: var(--color-warning-text);--n-search-link-badge-border: var(--color-warning-border)}.n-search-link-badge[data-resource=guide]{--n-search-link-badge-color: var(--color-highlight-bg);--n-search-link-badge-text-color: var(--color-highlight-text);--n-search-link-badge-border: var(--color-highlight-border)}.n-search-link-badge[data-resource=knowledge-base]{--n-search-link-badge-color: var(--color-success-bg);--n-search-link-badge-text-color: var(--color-success-text);--n-search-link-badge-border: var(--color-success-border)}.n-loader-dots-spinner{width:var(--n-loader-dot-w, 50px);aspect-ratio:1;--_c: no-repeat radial-gradient(farthest-side, var(--n-loader-dot-color, var(--teal-600)) 92%, #0000);background:var(--_c) top,var(--_c) left,var(--_c) right,var(--_c) bottom;background-size:12px 12px;animation:l7 1s infinite}@keyframes l7{to{transform:rotate(.5turn)}}.n-search-modal{--n-search-padding-inline: var(--space-s);--n-search-color-text: var(--color-text-1, currentColor);--n-search-color-text-secondary: var(--color-text-weak, currentColor);--n-search-color-icon: var(--search-icon-color);--n-search-color-bg: var(--search-bg-color);--n-search-color-bg-2: var(--color-bg-3);--n-search-color-border: var(--color-bg-3);--n-search-border-radius: 1.3rem;--n-search-max-w: 600px;--n-search-text-highlight: var(--search-highlight-color);--n-search-input-height: 50px;--n-search-footer-height: 40px;--n-search-container-height: min(50dvh, 26.5rem)}.n-search-modal{padding:0;border:none;border-radius:var(--n-search-border-radius);width:min(var(--n-search-max-w),100%);margin:auto;background:var(--n-search-color-bg);transition-delay:.2s}.n-search-modal[data-state=ask]{--n-search-max-w: 800px}.n-search-container{--mark-bg: var(--n-search-text-highlight);display:grid;width:min(var(--n-search-max-w),100%);background-color:var(--n-search-color-bg);border-radius:var(--n-search-border-radius);overflow:hidden}.n-search-bar{display:flex;flex-wrap:wrap;align-items:center;overflow:hidden;background:var(--n-search-color-bg);border-bottom:1px solid var(--n-search-color-border)}.n-search-input-wrapper{position:relative;display:flex;width:100%;height:var(--n-search-input-height);align-items:center}.n-search-input{position:relative;display:inline-flex;box-sizing:border-box;background:transparent;inline-size:100%;padding-block:.75rem;padding-inline:var(--n-search-padding-inline);flex:1;border:none;outline:none;font-size:1rem;color:var(--color-text-1)}.n-search-input-clear{border:none;color:var(--n-search-color-text-secondary);font-size:var(--font-size-text-sm);margin-inline:var(--space-m);height:min-content;padding:0;outline-offset:.5rem;background:none;cursor:pointer}.n-search-input-wrapper:after,.n-search-footer:after{content:"";display:block;width:200%;height:1px;background:var(--n-search-color-border);position:absolute;bottom:0;left:0}.n-search-input::placeholder{color:var(--n-search-color-text-secondary)}.n-search-links{padding:var(--space-2xs);height:100%}.n-search-label{display:flex;padding-inline-start:var(--n-search-padding-inline);align-items:center}.n-results-list{padding-inline:0;padding-block-end:var(--space-2xs)}.n-results-info{font-family:var(--font-family-display);font-size:var(--step--1);padding-inline:var(--space-xs)}.n-search-label>*{display:inline-block;margin:0}.n-search-icon{display:flex;width:var(--n-search-icon-size, 1em);height:var(--n-search-icon-size, 1em);color:var(--n-search-color-text-secondary)}.n-search-term{font-weight:var(--font-bold);color:var(--n-search-color-text-secondary)}.n-search-window{height:var(--n-search-container-height);overflow-x:hidden;overflow-y:auto;overscroll-behavior:contain;scroll-padding-block:var(--space-s);margin-block:0;background:var(--n-search-color-bg)}.n-search-feedback{height:calc(100% - 70px);display:grid;place-content:center}.n-search-footer{position:relative;display:flex;gap:var(--space-m);padding:var(--space-2xs) var(--space-s);height:var(--n-search-footer-height)}.n-search-footer:after{top:0}.n-search-footer-tip{color:var(--n-search-color-text-secondary);display:flex;gap:var(--space-2xs);align-items:center;font-size:var(--font-size-text-sm)}.n-search-modal{transition:display .2s allow-discrete,overlay .2s allow-discrete,width .15s ease-in-out;animation:closeSearch .2s forwards}.n-search-modal[open]{animation:openSearch .2s forwards}.n-search-modal[data-state=search]>*{opacity:0;animation:appearContainer .12s ease-in-out forwards;animation-delay:.14s}@keyframes appearContainer{0%{opacity:0}to{opacity:1}}@keyframes openSearch{0%{opacity:0;transform:scale(.9)}to{opacity:1;transform:scale(1)}}@keyframes closeSearch{0%{opacity:1;transform:scale(1)}50%{opacity:.3}to{opacity:0;transform:scale(.9)}}.n-search-modal::backdrop{animation:closeSearchBackdrop .2s forwards}.n-search-modal[open]::backdrop{animation:openSearchBackdrop .2s forwards}@keyframes openSearchBackdrop{0%{opacity:0;-webkit-backdrop-filter:blur(0px);backdrop-filter:blur(0px)}to{opacity:1;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}}@keyframes closeSearchBackdrop{0%{opacity:1;-webkit-backdrop-filter:blur(1.5px);backdrop-filter:blur(1.5px)}50%{opacity:.3}to{opacity:0;-webkit-backdrop-filter:blur(0px);backdrop-filter:blur(0px)}}
1
+ .n-keyboard-key{--n-key-text-size: .8em;--n-key-border-radius: 6px;--n-key-text-color: currentColor;--n-key-bg-color: transparent;display:flex;gap:calc(var(--space-3xs) * .5);font-size:var(--n-key-text-size);color:var(--n-key-text-color);background:var(--n-key-bg-color);border:1px solid currentColor;border-radius:var(--n-key-border-radius);padding:var(--n-key-padding-block, .05em) var(--n-key-padding-inline, .3em)}.n-search-heading{--n-search-heading-weight: var(--font-weight-semibold, 400);--n-search-heading-size: var(--font-size-text-xs, 13px);--n-search-heading-color: var(--color-text-weak, #757575);font-size:var(--n-search-heading-size);font-weight:var(--n-search-heading-weight);font-family:var(--font-family-mono);color:var(--n-search-heading-color);padding-inline:var(--space-xs);margin-block:var(--space-xs);letter-spacing:.2px}.n-search-link{--n-search-icon-size: 1.25em;box-sizing:border-box;display:flex;justify-content:space-between;flex-wrap:wrap;gap:var(--space-s, 1rem);align-items:center;padding:var(--n-search-link-padding-block, 1em) var(--n-search-link-padding-inline, 1em);font-size:var(--font-size-text-sm);font-weight:var(--font-weight-regular);text-decoration:none;cursor:pointer;width:100%;border:none;text-align:left;outline:none;border-radius:var(--radius-l)}.n-search-link-body{flex:1;width:80%;color:var(--color-text-weak);text-wrap:pretty}.n-search-link:is(:hover,:focus-visible){background:var(--n-search-color-bg-2)}.n-search-link:is(:hover,:focus-visible) .n-search-link-icon [data-icon=caretRight]{opacity:1}.n-search-link:is(:hover,:focus-visible) .n-search-link-icon :where(#ask-netlify-eyelid-left,#ask-netlify-eyelid-right){--n-ask-netlify-eyelid-color: var(--n-search-color-bg-2);animation:askEyeBlink 4s infinite;animation-delay:.2s}.n-search-link-icon :where(#ask-netlify-eyelid-left,#ask-netlify-eyelid-right){--n-ask-netlify-eyelid-color: var(--search-bg-color)}.n-search-link-title{font-weight:var(--font-weight-medium);color:var(--ntl-color-text);line-height:1.5}.n-search-link-excerpt{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;color:var(--color-text-weak);line-height:1.3;font-size:.9em;margin-block-start:var(--space-3xs)}.n-search-link-excerpt mark{color:var(--mark-color, currentColor);background-color:var(--mark-bg, var(--ntl-color-highlight-bg))}.n-search-link-icon,.n-search-link-icon svg{display:flex;width:var(--n-search-icon-size);height:var(--n-search-icon-size);color:var(--n-search-color-icon)}.n-search-link-icon [data-icon=caretRight]{width:1em;opacity:0}.n-search-link-label{margin-inline-end:var(--space-3xs)}.n-search-link-badge{display:inline-block;width:max-content;font-size:.7em;padding:.1em .4em;position:relative;bottom:.3em;color:var(--n-search-link-badge-text-color, var(--color-disabled-text));background:var(--n-search-link-badge-color, var(--color-disabled-bg));border:1px solid var(--n-search-link-badge-border, var(--color-disabled-border));border-radius:3px}.n-search-link-badge[data-resource=blog]{--n-search-link-badge-color: var(--color-info-bg);--n-search-link-badge-text-color: var(--color-info-text);--n-search-link-badge-border: var(--color-info-border)}.n-search-link-badge[data-resource=changelog]{--n-search-link-badge-color: var(--color-warning-bg);--n-search-link-badge-text-color: var(--color-warning-text);--n-search-link-badge-border: var(--color-warning-border)}.n-search-link-badge[data-resource=guide]{--n-search-link-badge-color: var(--ntl-color-highlight-bg);--n-search-link-badge-text-color: var(--ntl-color-highlight-text);--n-search-link-badge-border: var(--ntl-color-highlight-border)}.n-search-link-badge[data-resource=knowledge-base]{--n-search-link-badge-color: var(--color-success-bg);--n-search-link-badge-text-color: var(--color-success-text);--n-search-link-badge-border: var(--color-success-border)}.n-loader-dots-spinner{width:var(--n-loader-dot-w, 50px);aspect-ratio:1;--_c: no-repeat radial-gradient(farthest-side, var(--n-loader-dot-color, var(--teal-600)) 92%, #0000);background:var(--_c) top,var(--_c) left,var(--_c) right,var(--_c) bottom;background-size:12px 12px;animation:l7 1s infinite}@keyframes l7{to{transform:rotate(.5turn)}}.n-search-modal{--n-search-padding-inline: var(--space-s);--n-search-color-text: var(--ntl-color-text, currentColor);--n-search-color-text-secondary: var(--color-text-weak, currentColor);--n-search-color-icon: var(--search-icon-color);--n-search-color-bg: var(--search-bg-color);--n-search-color-bg-2: var(--ntl-color-bg-muted);--n-search-color-border: var(--ntl-color-border);--n-search-border-radius: 1.3rem;--n-search-max-w: 600px;--n-search-text-highlight: var(--search-highlight-color);--n-search-input-height: 50px;--n-search-footer-height: 40px;--n-search-container-height: min(50dvh, 26.5rem)}.n-search-modal{padding:0;border:none;border-radius:var(--n-search-border-radius);width:min(var(--n-search-max-w),100%);margin:auto;background:var(--n-search-color-bg);transition-delay:.2s}.n-search-modal[data-state=ask]{--n-search-max-w: 800px}.n-search-container{--mark-bg: var(--n-search-text-highlight);display:grid;width:min(var(--n-search-max-w),100%);background-color:var(--n-search-color-bg);border-radius:var(--n-search-border-radius);overflow:hidden}.n-search-bar{display:flex;flex-wrap:wrap;align-items:center;overflow:hidden;background:var(--n-search-color-bg);border-bottom:1px solid var(--n-search-color-border)}.n-search-input-wrapper{position:relative;display:flex;width:100%;height:var(--n-search-input-height);align-items:center}.n-search-input{position:relative;display:inline-flex;box-sizing:border-box;background:transparent;inline-size:100%;padding-block:.75rem;padding-inline:var(--n-search-padding-inline);flex:1;border:none;outline:none;font-size:1rem;color:var(--ntl-color-text)}.n-search-input-clear{border:none;color:var(--n-search-color-text-secondary);font-size:var(--font-size-text-sm);margin-inline:var(--space-m);height:min-content;padding:0;outline-offset:.5rem;background:none;cursor:pointer}.n-search-input-wrapper:after,.n-search-footer:after{content:"";display:block;width:200%;height:1px;background:var(--n-search-color-border);position:absolute;bottom:0;left:0}.n-search-input::placeholder{color:var(--n-search-color-text-secondary)}.n-search-links{padding:var(--space-2xs);height:100%}.n-search-label{display:flex;padding-inline-start:var(--n-search-padding-inline);align-items:center}.n-results-list{padding-inline:0;padding-block-end:var(--space-2xs)}.n-results-info{font-family:var(--ntl-font-family-heading);font-size:var(--step--1);padding-inline:var(--space-xs)}.n-search-label>*{display:inline-block;margin:0}.n-search-icon{display:flex;width:var(--n-search-icon-size, 1em);height:var(--n-search-icon-size, 1em);color:var(--n-search-color-text-secondary)}.n-search-term{font-weight:var(--ntl-font-weight-bold);color:var(--n-search-color-text-secondary)}.n-search-window{height:var(--n-search-container-height);overflow-x:hidden;overflow-y:auto;overscroll-behavior:contain;scroll-padding-block:var(--space-s);margin-block:0;background:var(--n-search-color-bg)}.n-search-feedback{height:calc(100% - 70px);display:grid;place-content:center}.n-search-footer{position:relative;display:flex;gap:var(--space-m);padding:var(--space-2xs) var(--space-s);height:var(--n-search-footer-height)}.n-search-footer:after{top:0}.n-search-footer-tip{color:var(--n-search-color-text-secondary);display:flex;gap:var(--space-2xs);align-items:center;font-size:var(--font-size-text-sm)}.n-search-modal{transition:display .2s allow-discrete,overlay .2s allow-discrete,width .15s ease-in-out;animation:closeSearch .2s forwards}.n-search-modal[open]{animation:openSearch .2s forwards}.n-search-modal[data-state=search]>*{opacity:0;animation:appearContainer .12s ease-in-out forwards;animation-delay:.14s}@keyframes appearContainer{0%{opacity:0}to{opacity:1}}@keyframes openSearch{0%{opacity:0;transform:scale(.9)}to{opacity:1;transform:scale(1)}}@keyframes closeSearch{0%{opacity:1;transform:scale(1)}50%{opacity:.3}to{opacity:0;transform:scale(.9)}}.n-search-modal::backdrop{animation:closeSearchBackdrop .2s forwards}.n-search-modal[open]::backdrop{animation:openSearchBackdrop .2s forwards}@keyframes openSearchBackdrop{0%{opacity:0;-webkit-backdrop-filter:blur(0px);backdrop-filter:blur(0px)}to{opacity:1;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}}@keyframes closeSearchBackdrop{0%{opacity:1;-webkit-backdrop-filter:blur(1.5px);backdrop-filter:blur(1.5px)}50%{opacity:.3}to{opacity:0;-webkit-backdrop-filter:blur(0px);backdrop-filter:blur(0px)}}
@@ -0,0 +1,5 @@
1
+ import { FaviconAsset, FaviconName } from '../../utils/types';
2
+ export type { FaviconAsset, FaviconName } from '../../utils/types';
3
+ /** The 2026 favicon set, as `FAVICONS.<ico|svg|icon192|icon512|maskable192|maskable512|appleTouchIcon>`. */
4
+ export declare const FAVICONS: Record<FaviconName, FaviconAsset>;
5
+ export declare const FAVICON_NAMES: FaviconName[];
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,11 @@
1
+ import { LogoAsset, LogoColor, LogoFormat, LogoName, LogoVariant } from '../../utils/types';
2
+ export type { AssetFile, LogoAsset, LogoColor, LogoFormat, LogoName, LogoVariant, } from '../../utils/types';
3
+ /** Every logo in the 2026 kit, as `LOGOS.<full|monogram>.<lightmode|darkmode|black>.<svg|png>`. */
4
+ export declare const LOGOS: Record<LogoVariant, Record<LogoColor, LogoAsset>>;
5
+ export declare const LOGO_VARIANTS: LogoVariant[];
6
+ export declare const LOGO_COLORS: LogoColor[];
7
+ export declare const LOGO_FORMATS: LogoFormat[];
8
+ /** The published file name of a logo, e.g. `logo-netlify-full-lightmode.svg`. */
9
+ export declare function getLogoFileName(variant: LogoVariant, color: LogoColor, format?: LogoFormat): string;
10
+ /** Splits a `<variant>-<color>` name into its two keys, throwing on a name that isn't in `LOGOS`. */
11
+ export declare function resolveLogoKeys(name: LogoName): [LogoVariant, LogoColor];
@@ -0,0 +1 @@
1
+ export {};
@@ -26,3 +26,19 @@ export interface Testimonial {
26
26
  label?: string;
27
27
  };
28
28
  }
29
+ export type LogoVariant = 'full' | 'monogram';
30
+ export type LogoColor = 'lightmode' | 'darkmode' | 'black';
31
+ export type LogoName = `${LogoVariant}-${LogoColor}`;
32
+ export type LogoFormat = 'svg' | 'png';
33
+ export interface AssetFile {
34
+ src: string;
35
+ fileName: string;
36
+ width: number;
37
+ height: number;
38
+ }
39
+ export interface LogoAsset {
40
+ svg: AssetFile;
41
+ png: AssetFile;
42
+ }
43
+ export type FaviconName = 'ico' | 'svg' | 'icon192' | 'icon512' | 'maskable192' | 'maskable512' | 'appleTouchIcon';
44
+ export type FaviconAsset = AssetFile;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@netlify/spark-ui",
3
3
  "description": "Assets, design tokens, components, and utilities",
4
- "version": "2.2.0",
4
+ "version": "2.4.0",
5
5
  "type": "module",
6
6
  "main": "dist/components/preact/index.js",
7
7
  "types": "dist/components/preact/index.d.ts",
@@ -9,14 +9,15 @@
9
9
  "**/*.css"
10
10
  ],
11
11
  "scripts": {
12
- "build:tokens": "npx tz build && node scripts/generate-compat-tokens.mjs",
12
+ "build:tokens": "npx tz build && node scripts/generate-compat-tokens.mjs && node scripts/docs-token-values.mjs",
13
13
  "build:vite": "vite build",
14
14
  "lint": "eslint . --ext .js,.jsx,.ts,.tsx,.astro",
15
15
  "lint:fix": "eslint . --ext .js,.jsx,.ts,.tsx,.astro --fix",
16
16
  "format": "prettier --write \"**/*.{js,jsx,ts,tsx,astro,json,css,md,mdx}\" --ignore-path packages/styles/tokens.css",
17
17
  "format:check": "prettier --check \"**/*.{js,jsx,ts,tsx,astro,json,css,md,mdx}\" --ignore-path packages/styles/tokens.css",
18
18
  "test": "vitest run",
19
- "prepublishOnly": "npm run build:vite"
19
+ "prepublishOnly": "npm run build:vite",
20
+ "tokens:diff": "node scripts/diff-tokens.mjs"
20
21
  },
21
22
  "files": [
22
23
  "packages/",
@@ -29,7 +30,11 @@
29
30
  "./drop-core": "./dist/drop-core/index.js",
30
31
  "./assets/*.css": "./dist/assets/*.css",
31
32
  "./assets/icons/*.svg": "./packages/assets/icons/*.svg",
33
+ "./logos": "./packages/assets/logos/index.ts",
32
34
  "./logos/*.svg": "./packages/assets/logos/*.svg",
35
+ "./logos/*.png": "./packages/assets/logos/*.png",
36
+ "./favicons": "./packages/assets/favicons/index.ts",
37
+ "./favicons/*": "./packages/assets/favicons/*",
33
38
  "./styles/*.css": "./packages/styles/*.css",
34
39
  "./tokens/app": {
35
40
  "types": "./packages/tokens/app.d.ts",
@@ -1,30 +1,14 @@
1
- <svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
1
+ <svg width="32" height="32" viewBox="0 0 390 390" fill="none" xmlns="http://www.w3.org/2000/svg">
2
2
  <style>
3
- .favicon-center-dot {
4
- fill: #014847;
5
- }
6
-
7
- .favicon-lines {
8
- fill: #05BDBA;
9
- }
10
-
3
+ .mark { fill: #131619; }
11
4
  @media (prefers-color-scheme: dark) {
12
- .favicon-center-dot {
13
- fill: #fff;
14
- }
15
-
16
- .favicon-lines {
17
- fill: #05BDBA;
18
- }
5
+ .mark { fill: #ffffff; }
19
6
  }
20
7
  </style>
21
- <path class="favicon-center-dot" stroke="none" d="M17.9922 18.3225H14.005L13.6746 17.9921V14.005L14.005 13.6746H17.9922L18.3226 14.005V17.9921L17.9922 18.3225Z" />
22
- <g class="favicon-lines" stroke="none">
23
- <path d="M9.6958 24.3311H9.35705L7.6661 22.6401V22.3041L10.2511 19.7164L12.042 19.7191L12.2808 19.9552V21.7461L9.6958 24.3311Z" />
24
- <path d="M7.6661 9.69576V9.35701L9.35705 7.66606H9.6958L12.2808 10.2511V12.0392L12.042 12.2808H10.2511L7.6661 9.69576Z" />
25
- <path d="M10.0457 17.4369H0.205466L0 17.2314V14.7658L0.205466 14.5603H10.0457L10.2511 14.7658V17.2314L10.0457 17.4369Z" />
26
- <path d="M31.7945 17.4369H21.9544L21.7489 17.2314V14.7658L21.9544 14.5603H31.7945L32 14.7658V17.2314L31.7945 17.4369Z" />
27
- <path d="M14.5631 10.0456V2.66547L14.7686 2.46001H17.2343L17.4396 2.66547V10.0456L17.2343 10.2511H14.7686L14.5631 10.0456Z" />
28
- <path d="M14.5631 29.3316V21.9515L14.7686 21.746H17.2343L17.4396 21.9515V29.3316L17.2343 29.5371H14.7686L14.5631 29.3316Z" />
8
+ <g class="mark" transform="translate(12.5 14.5)">
9
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M122.608 207.222V298.975C122.608 301.415 123.574 303.775 125.317 305.518L177.467 357.668C181.06 361.261 186.932 361.261 190.525 357.668L232.675 315.519C236.268 311.926 236.268 306.053 232.675 302.434L133.119 202.878C129.231 198.99 122.608 201.726 122.608 207.222Z"/>
10
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M232.675 44.8449L190.525 2.69468C186.932 -0.898228 181.06 -0.898228 177.467 2.69468L125.317 54.846C123.574 56.5889 122.608 58.922 122.608 61.362V153.115C122.608 158.584 129.231 161.346 133.119 157.459L232.675 57.9031C236.268 54.3101 236.268 48.4385 232.675 44.8187V44.8449Z"/>
11
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M307.482 126.543L151.056 174.243C145.238 176.012 145.238 184.243 151.056 186.013L307.482 233.713C310.726 234.705 314.319 233.82 316.706 231.407L361.483 186.629C365.076 183.036 365.076 177.165 361.483 173.545L316.706 128.767C314.292 126.354 310.753 125.469 307.482 126.462V126.515V126.543Z"/>
12
+ <path d="M48.6878 131.481L6.52195 173.647C2.91992 177.249 2.91992 183.089 6.52195 186.691L48.6883 228.857C52.2903 232.459 58.1302 232.459 61.7322 228.857L103.898 186.691C107.5 183.089 107.5 177.249 103.898 173.647L61.7317 131.481C58.1297 127.879 52.2899 127.879 48.6878 131.481Z"/>
29
13
  </g>
30
14
  </svg>
@@ -0,0 +1,10 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { FAVICONS, FAVICON_NAMES } from './index';
3
+
4
+ const URL_PATTERN = /^(\/|data:image\/)/;
5
+
6
+ describe('FAVICONS', () => {
7
+ it.each(FAVICON_NAMES)('%s resolves to a URL', name => {
8
+ expect(FAVICONS[name].src).toMatch(URL_PATTERN);
9
+ });
10
+ });
@@ -0,0 +1,38 @@
1
+ import type { FaviconAsset, FaviconName } from '../../utils/types';
2
+ import faviconIco from './favicon.ico?url';
3
+ import iconSvg from './icon.svg?url';
4
+ import icon192 from './icon-192.png?url';
5
+ import icon512 from './icon-512.png?url';
6
+ import icon192Maskable from './icon-192-maskable.png?url';
7
+ import icon512Maskable from './icon-512-maskable.png?url';
8
+ import appleTouchIcon from './apple-touch-icon.png?url';
9
+
10
+ export type { FaviconAsset, FaviconName } from '../../utils/types';
11
+
12
+ /** The 2026 favicon set, as `FAVICONS.<ico|svg|icon192|icon512|maskable192|maskable512|appleTouchIcon>`. */
13
+ export const FAVICONS: Record<FaviconName, FaviconAsset> = {
14
+ ico: { src: faviconIco, fileName: 'favicon.ico', width: 48, height: 48 },
15
+ svg: { src: iconSvg, fileName: 'icon.svg', width: 32, height: 32 },
16
+ icon192: { src: icon192, fileName: 'icon-192.png', width: 192, height: 192 },
17
+ icon512: { src: icon512, fileName: 'icon-512.png', width: 512, height: 512 },
18
+ maskable192: {
19
+ src: icon192Maskable,
20
+ fileName: 'icon-192-maskable.png',
21
+ width: 192,
22
+ height: 192,
23
+ },
24
+ maskable512: {
25
+ src: icon512Maskable,
26
+ fileName: 'icon-512-maskable.png',
27
+ width: 512,
28
+ height: 512,
29
+ },
30
+ appleTouchIcon: {
31
+ src: appleTouchIcon,
32
+ fileName: 'apple-touch-icon.png',
33
+ width: 180,
34
+ height: 180,
35
+ },
36
+ };
37
+
38
+ export const FAVICON_NAMES = Object.keys(FAVICONS) as FaviconName[];
@@ -0,0 +1,93 @@
1
+ Copyright © 2017 IBM Corp. with Reserved Font Name "Plex"
2
+
3
+ This Font Software is licensed under the SIL Open Font License, Version 1.1.
4
+
5
+ This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
6
+
7
+
8
+ -----------------------------------------------------------
9
+ SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
10
+ -----------------------------------------------------------
11
+
12
+ PREAMBLE
13
+ The goals of the Open Font License (OFL) are to stimulate worldwide
14
+ development of collaborative font projects, to support the font creation
15
+ efforts of academic and linguistic communities, and to provide a free and
16
+ open framework in which fonts may be shared and improved in partnership
17
+ with others.
18
+
19
+ The OFL allows the licensed fonts to be used, studied, modified and
20
+ redistributed freely as long as they are not sold by themselves. The
21
+ fonts, including any derivative works, can be bundled, embedded,
22
+ redistributed and/or sold with any software provided that any reserved
23
+ names are not used by derivative works. The fonts and derivatives,
24
+ however, cannot be released under any other type of license. The
25
+ requirement for fonts to remain under this license does not apply
26
+ to any document created using the fonts or their derivatives.
27
+
28
+ DEFINITIONS
29
+ "Font Software" refers to the set of files released by the Copyright
30
+ Holder(s) under this license and clearly marked as such. This may
31
+ include source files, build scripts and documentation.
32
+
33
+ "Reserved Font Name" refers to any names specified as such after the
34
+ copyright statement(s).
35
+
36
+ "Original Version" refers to the collection of Font Software components as
37
+ distributed by the Copyright Holder(s).
38
+
39
+ "Modified Version" refers to any derivative made by adding to, deleting,
40
+ or substituting -- in part or in whole -- any of the components of the
41
+ Original Version, by changing formats or by porting the Font Software to a
42
+ new environment.
43
+
44
+ "Author" refers to any designer, engineer, programmer, technical
45
+ writer or other person who contributed to the Font Software.
46
+
47
+ PERMISSION & CONDITIONS
48
+ Permission is hereby granted, free of charge, to any person obtaining
49
+ a copy of the Font Software, to use, study, copy, merge, embed, modify,
50
+ redistribute, and sell modified and unmodified copies of the Font
51
+ Software, subject to the following conditions:
52
+
53
+ 1) Neither the Font Software nor any of its individual components,
54
+ in Original or Modified Versions, may be sold by itself.
55
+
56
+ 2) Original or Modified Versions of the Font Software may be bundled,
57
+ redistributed and/or sold with any software, provided that each copy
58
+ contains the above copyright notice and this license. These can be
59
+ included either as stand-alone text files, human-readable headers or
60
+ in the appropriate machine-readable metadata fields within text or
61
+ binary files as long as those fields can be easily viewed by the user.
62
+
63
+ 3) No Modified Version of the Font Software may use the Reserved Font
64
+ Name(s) unless explicit written permission is granted by the corresponding
65
+ Copyright Holder. This restriction only applies to the primary font name as
66
+ presented to the users.
67
+
68
+ 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
69
+ Software shall not be used to promote, endorse or advertise any
70
+ Modified Version, except to acknowledge the contribution(s) of the
71
+ Copyright Holder(s) and the Author(s) or with their explicit written
72
+ permission.
73
+
74
+ 5) The Font Software, modified or unmodified, in part or in whole,
75
+ must be distributed entirely under this license, and must not be
76
+ distributed under any other license. The requirement for fonts to
77
+ remain under this license does not apply to any document created
78
+ using the Font Software.
79
+
80
+ TERMINATION
81
+ This license becomes null and void if any of the above conditions are
82
+ not met.
83
+
84
+ DISCLAIMER
85
+ THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
86
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
87
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
88
+ OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
89
+ COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
90
+ INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
91
+ DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
92
+ FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
93
+ OTHER DEALINGS IN THE FONT SOFTWARE.
@@ -0,0 +1,16 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { LOGOS, LOGO_COLORS, LOGO_FORMATS, LOGO_VARIANTS } from './index';
3
+
4
+ const URL_PATTERN = /^(\/|data:image\/)/;
5
+
6
+ const FILES = LOGO_VARIANTS.flatMap(variant =>
7
+ LOGO_COLORS.flatMap(color =>
8
+ LOGO_FORMATS.map(format => [`${variant}.${color}.${format}`, LOGOS[variant][color][format].src])
9
+ )
10
+ );
11
+
12
+ describe('LOGOS', () => {
13
+ it.each(FILES)('%s resolves to a URL', (_key, src) => {
14
+ expect(src).toMatch(URL_PATTERN);
15
+ });
16
+ });
@@ -0,0 +1,79 @@
1
+ import type {
2
+ AssetFile,
3
+ LogoAsset,
4
+ LogoColor,
5
+ LogoFormat,
6
+ LogoName,
7
+ LogoVariant,
8
+ } from '../../utils/types';
9
+ import fullLightmodeSvg from './logo-netlify-full-lightmode.svg?url';
10
+ import fullLightmodePng from './logo-netlify-full-lightmode.png?url';
11
+ import fullDarkmodeSvg from './logo-netlify-full-darkmode.svg?url';
12
+ import fullDarkmodePng from './logo-netlify-full-darkmode.png?url';
13
+ import fullBlackSvg from './logo-netlify-full-black.svg?url';
14
+ import fullBlackPng from './logo-netlify-full-black.png?url';
15
+ import monogramLightmodeSvg from './logo-netlify-monogram-lightmode.svg?url';
16
+ import monogramLightmodePng from './logo-netlify-monogram-lightmode.png?url';
17
+ import monogramDarkmodeSvg from './logo-netlify-monogram-darkmode.svg?url';
18
+ import monogramDarkmodePng from './logo-netlify-monogram-darkmode.png?url';
19
+ import monogramBlackSvg from './logo-netlify-monogram-black.svg?url';
20
+ import monogramBlackPng from './logo-netlify-monogram-black.png?url';
21
+
22
+ export type {
23
+ AssetFile,
24
+ LogoAsset,
25
+ LogoColor,
26
+ LogoFormat,
27
+ LogoName,
28
+ LogoVariant,
29
+ } from '../../utils/types';
30
+
31
+ const LOGO_SIZES: Record<LogoVariant, Record<LogoFormat, Pick<AssetFile, 'width' | 'height'>>> = {
32
+ full: { svg: { width: 583, height: 152 }, png: { width: 2701, height: 701 } },
33
+ monogram: { svg: { width: 365, height: 361 }, png: { width: 719, height: 711 } },
34
+ };
35
+
36
+ /** Every logo in the 2026 kit, as `LOGOS.<full|monogram>.<lightmode|darkmode|black>.<svg|png>`. */
37
+ export const LOGOS: Record<LogoVariant, Record<LogoColor, LogoAsset>> = {
38
+ full: {
39
+ lightmode: toLogoAsset('full', 'lightmode', fullLightmodeSvg, fullLightmodePng),
40
+ darkmode: toLogoAsset('full', 'darkmode', fullDarkmodeSvg, fullDarkmodePng),
41
+ black: toLogoAsset('full', 'black', fullBlackSvg, fullBlackPng),
42
+ },
43
+ monogram: {
44
+ lightmode: toLogoAsset('monogram', 'lightmode', monogramLightmodeSvg, monogramLightmodePng),
45
+ darkmode: toLogoAsset('monogram', 'darkmode', monogramDarkmodeSvg, monogramDarkmodePng),
46
+ black: toLogoAsset('monogram', 'black', monogramBlackSvg, monogramBlackPng),
47
+ },
48
+ };
49
+
50
+ export const LOGO_VARIANTS = Object.keys(LOGOS) as LogoVariant[];
51
+ export const LOGO_COLORS = Object.keys(LOGOS.full) as LogoColor[];
52
+ export const LOGO_FORMATS = Object.keys(LOGOS.full.lightmode) as LogoFormat[];
53
+
54
+ /** The published file name of a logo, e.g. `logo-netlify-full-lightmode.svg`. */
55
+ export function getLogoFileName(
56
+ variant: LogoVariant,
57
+ color: LogoColor,
58
+ format: LogoFormat = 'svg'
59
+ ): string {
60
+ return `logo-netlify-${variant}-${color}.${format}`;
61
+ }
62
+
63
+ /** Splits a `<variant>-<color>` name into its two keys, throwing on a name that isn't in `LOGOS`. */
64
+ export function resolveLogoKeys(name: LogoName): [LogoVariant, LogoColor] {
65
+ const [variant, color] = name.split('-') as [LogoVariant, LogoColor];
66
+ if (!LOGO_VARIANTS.includes(variant) || !LOGO_COLORS.includes(color)) {
67
+ throw new Error(
68
+ `Unknown logo name "${name}". Expected <${LOGO_VARIANTS.join('|')}>-<${LOGO_COLORS.join('|')}>.`
69
+ );
70
+ }
71
+ return [variant, color];
72
+ }
73
+
74
+ function toLogoAsset(variant: LogoVariant, color: LogoColor, svg: string, png: string): LogoAsset {
75
+ return {
76
+ svg: { src: svg, fileName: getLogoFileName(variant, color, 'svg'), ...LOGO_SIZES[variant].svg },
77
+ png: { src: png, fileName: getLogoFileName(variant, color, 'png'), ...LOGO_SIZES[variant].png },
78
+ };
79
+ }
@@ -0,0 +1,4 @@
1
+ <svg width="583" height="152" viewBox="0 0 583 152" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M46.5567 81.2217C46.5567 79.0651 49.1543 77.9965 50.6739 79.5157L89.6924 118.534C91.1039 119.956 91.104 122.25 89.6924 123.661L73.1729 140.18C71.7612 141.591 69.4674 141.591 68.0557 140.18L47.6153 119.739C46.939 119.063 46.5567 118.141 46.5567 117.181V81.2217ZM119.015 49.5879C120.299 49.1958 121.681 49.5386 122.632 50.4893L140.181 68.0381C141.592 69.4597 141.592 71.7534 140.181 73.1651L122.632 90.7129C121.691 91.6541 120.289 92.0074 119.015 91.6153L57.7031 72.92C55.4194 72.2237 55.4195 68.9991 57.7031 68.3028L119.015 49.6075V49.5879ZM17.5781 51.5274C18.9899 50.116 21.2837 50.1158 22.6953 51.5274L39.2139 68.0469C40.6255 69.4586 40.6256 71.7524 39.2139 73.1641L22.6953 89.6827C21.2837 91.0943 18.9899 91.0942 17.5781 89.6827L1.05862 73.1641C-0.352982 71.7525 -0.352763 69.4587 1.05862 68.0469L17.5781 51.5274ZM68.0557 1.05863C69.4673 -0.352957 71.7612 -0.352799 73.1729 1.05863L89.6924 17.5782C91.1039 18.9997 91.104 21.2935 89.6924 22.7051L50.6739 61.7227C49.1544 63.2422 46.557 62.1643 46.5567 60.0176V24.0577C46.5567 23.097 46.9291 22.1852 47.6153 21.4991L68.0557 1.05863Z" fill="black"/>
3
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M537.698 151.135C539.131 151.135 540.051 150.517 540.594 149.19L582.651 46.3761C583.36 44.6269 582.591 43.4655 580.706 43.4655H562.64C561.177 43.4655 560.258 44.1144 559.805 45.5169L544.122 92.3089C543.368 94.5709 541.634 94.5709 540.895 92.3089L525.348 45.5316C524.881 44.1442 523.976 43.4809 522.513 43.4809H492.78C491.152 43.4809 490.277 42.6061 490.277 40.9775V40.3295C490.277 36.3334 491.166 33.2717 492.961 31.1757C494.861 28.9589 497.59 27.8586 501.164 27.8586C502.959 27.8586 504.587 28.1751 506.065 28.8084C506.563 28.9894 507.045 29.1852 507.498 29.4114C509.066 30.1654 510.182 29.894 510.77 28.2503L514.465 17.7099C514.962 16.2774 514.6 15.131 513.258 14.4223C508.719 12.0246 503.366 10.8335 497.229 10.8335C492.177 10.8335 487.547 11.8284 483.34 13.834C479.239 15.8396 475.921 18.8862 473.387 22.9878C470.869 27.0895 469.602 32.2014 469.602 38.2936V40.9929C469.602 42.6215 468.728 43.4957 467.099 43.4957H460.736C459.107 43.4957 458.232 44.3705 458.232 45.9991V57.7316C458.232 59.3602 459.107 60.2343 460.736 60.2343H467.099C468.728 60.2343 469.602 61.1092 469.602 62.7378V118.668C469.602 120.297 470.477 121.172 472.106 121.172H488.407C490.035 121.172 490.91 120.297 490.91 118.668V62.7378C490.91 61.1092 491.785 60.2343 493.413 60.2343H505.684C507.132 60.2343 508.037 60.853 508.565 62.1951L530.46 117.281C530.943 118.487 530.913 119.453 530.385 120.629L518.064 148.24C517.28 149.989 518.064 151.165 519.965 151.165H537.698V151.135ZM189.712 121.141C191.341 121.141 192.215 120.267 192.215 118.638V52.8307C192.215 50.3123 194.025 49.86 195.201 52.0767L231.045 119.347C231.694 120.584 232.614 121.126 234.016 121.126H256.183C257.812 121.126 258.687 120.252 258.687 118.623V22.2788C258.687 20.6502 257.812 19.7753 256.183 19.7753H240.199C238.57 19.7753 237.695 20.6502 237.695 22.2788V86.4427C237.695 88.961 235.871 89.3987 234.71 87.1819L200.268 21.5704C199.619 20.3339 198.699 19.7753 197.312 19.7753H173.742C172.114 19.7753 171.239 20.6502 171.239 22.2788V118.623C171.239 120.252 172.114 121.126 173.742 121.126H189.727L189.712 121.141ZM335.937 112.154C337.098 111.053 337.083 109.786 335.982 108.61L327.749 99.9246C326.618 98.7333 325.426 98.7785 324.205 99.8944C319.983 103.74 314.841 105.669 308.794 105.669C302.747 105.669 298.057 104.252 294.589 101.402C291.784 99.0198 289.718 95.9135 288.436 92.0681C287.863 90.3641 288.768 89.2326 290.562 89.2326H341.275C342.859 89.2326 343.779 88.4182 343.869 86.8499C343.96 85.1308 344.005 83.0802 344.005 80.7127C344.005 72.826 342.316 65.9195 338.953 60.0384C335.696 54.1423 331.172 49.6184 325.381 46.4667C319.591 43.2095 313.121 41.5658 305.958 41.5658C298.177 41.5658 291.165 43.4057 284.968 47.0852C278.86 50.6591 274.125 55.5596 270.763 61.7725C267.4 67.9853 265.711 74.8162 265.711 82.2958C265.711 89.7753 267.445 96.6069 270.913 102.82C274.381 109.033 279.282 113.918 285.601 117.507C291.919 121.081 299.173 122.876 307.391 122.876C318.912 122.876 328.427 119.302 335.967 112.154H335.937ZM293.322 62.5721C296.473 59.526 300.741 57.9878 306.109 57.9878C309.367 57.9878 312.322 58.7263 314.946 60.2041C317.57 61.5764 319.681 63.5218 321.265 66.0401C322.396 67.7743 323.119 69.7046 323.436 71.8158C323.692 73.4595 322.697 74.4091 321.023 74.4091H290.291C288.526 74.4091 287.607 73.3387 288.074 71.6347C289.099 67.9703 290.834 64.9396 293.292 62.5721H293.322ZM374.693 121.141C376.322 121.141 377.197 120.267 377.197 118.638V62.7076C377.197 61.079 378.071 60.2041 379.7 60.2041H390.633C392.261 60.2041 393.136 59.33 393.136 57.7014V45.9689C393.136 44.3403 392.261 43.4655 390.633 43.4655H379.7C378.071 43.4655 377.197 42.5914 377.197 40.9627V23.6358C377.197 21.9016 376.201 21.0575 374.497 21.3591L358.166 24.149C356.643 24.4054 355.889 25.3102 355.889 26.8483V40.9775C355.889 42.6061 355.014 43.4809 353.386 43.4809H347.022C345.393 43.4809 344.519 44.3558 344.519 45.9844V57.7161C344.519 59.3447 345.393 60.2196 347.022 60.2196H353.386C355.014 60.2196 355.889 61.0937 355.889 62.7223V118.653C355.889 120.282 356.764 121.156 358.392 121.156H374.693V121.141ZM417.577 121.141C419.206 121.141 420.08 120.267 420.08 118.638V15.191C420.08 13.5624 419.206 12.6883 417.577 12.6883H401.427C399.798 12.6883 398.924 13.5624 398.924 15.191V118.638C398.924 120.267 399.798 121.141 401.427 121.141H417.577ZM449.006 121.141C450.635 121.141 451.51 120.267 451.51 118.638V45.9689C451.51 44.3403 450.635 43.4655 449.006 43.4655H432.856C431.227 43.4655 430.353 44.3403 430.353 45.9689V118.638C430.353 120.267 431.227 121.141 432.856 121.141H449.006ZM430.956 14.8744V30.2258C430.956 31.5377 432.027 32.6085 433.338 32.6085H448.69C450.001 32.6085 451.072 31.5377 451.072 30.2258V14.8744C451.072 13.5625 450.001 12.4924 448.69 12.4924H433.338C432.027 12.4924 430.956 13.5625 430.956 14.8744Z" fill="black"/>
4
+ </svg>