diff --git a/packages/stacks-docs-next/.gitignore b/packages/stacks-docs-next/.gitignore index 785f956d1d..7df20a667c 100644 --- a/packages/stacks-docs-next/.gitignore +++ b/packages/stacks-docs-next/.gitignore @@ -22,5 +22,4 @@ Thumbs.db vite.config.js.timestamp-* vite.config.ts.timestamp-* -/static/docs -/static/legacy \ No newline at end of file +/static/docs \ No newline at end of file diff --git a/packages/stacks-docs-next/package.json b/packages/stacks-docs-next/package.json index 15cedb2235..4a95d63662 100644 --- a/packages/stacks-docs-next/package.json +++ b/packages/stacks-docs-next/package.json @@ -4,8 +4,7 @@ "type": "module", "scripts": { "dev": "vite dev", - "predev": "node scripts/copy-legacy.mjs", - "prebuild": "npm run build -w @stackoverflow/stacks && npm run build -w @stackoverflow/stacks-svelte && npm run build -w @stackoverflow/stacks-docs && node scripts/copy-legacy.mjs", + "prebuild": "npm run build -w @stackoverflow/stacks && npm run build -w @stackoverflow/stacks-svelte", "build": "bash netlify-setup.sh && npm run init-private-content && vite build", "preview": "vite preview", "prepare": "svelte-kit sync || echo ''", @@ -28,7 +27,9 @@ "@docsearch/js": "^4.3.2", "@hbsnow/rehype-sectionize": "^1.0.7", "@stackoverflow/stacks": "*", + "@stackoverflow/stacks-editor": "*", "@stackoverflow/stacks-icons": "*", + "@stackoverflow/stacks-icons-legacy": "*", "@stackoverflow/stacks-svelte": "*", "@stefanprobst/rehype-extract-toc": "^3.0.0", "better-auth": "^1.4.7", diff --git a/packages/stacks-docs-next/scripts/copy-legacy.mjs b/packages/stacks-docs-next/scripts/copy-legacy.mjs deleted file mode 100644 index 1e507c227b..0000000000 --- a/packages/stacks-docs-next/scripts/copy-legacy.mjs +++ /dev/null @@ -1,40 +0,0 @@ -// Handles legacy Eleventy site content - -import fs from "fs"; -import path from "path"; - -const site = "../stacks-docs/_site"; - -if (!fs.existsSync(site)) { - console.warn("stacks-docs/_site not found, skipping legacy copy"); - process.exit(0); -} - -fs.mkdirSync("static/legacy", { recursive: true }); - -// Copy compiled assets -fs.cpSync(`${site}/assets`, "static/legacy/assets", { recursive: true }); - -// Copy fragment HTML files only, preserving directory structure -fs.cpSync(site, "static/legacy/fragments", { - recursive: true, - filter: (src) => { - const stat = fs.statSync(src); - if (stat.isDirectory()) return true; - return path.basename(src) === "fragment.html"; - }, -}); - -// Copy legacy JS bundle -const docsJs = "../stacks-docs/assets/dist/docs.js"; -if (fs.existsSync(docsJs)) { - fs.copyFileSync(docsJs, "static/legacy/docs.js"); -} - -// Copy legacy llms.txt -const llms = "../stacks-docs/_site/llms.txt"; -if (fs.existsSync(llms)) { - fs.copyFileSync(llms, "static/legacy/llms.txt"); -} - -console.log("Legacy assets copied successfully"); diff --git a/packages/stacks-docs-next/src/app.css b/packages/stacks-docs-next/src/app.css index 136ed17898..2d78ca943c 100644 --- a/packages/stacks-docs-next/src/app.css +++ b/packages/stacks-docs-next/src/app.css @@ -1,5 +1,7 @@ @import "@stackoverflow/stacks/dist/css/stacks.css"; +/* Brand color tokens — used by brand docs components. + The utility classes (.bg-brand-*, .fc-brand-*) are already provided by Stacks CSS. */ :root { --brand-color-orange: #ff5e00; --brand-color-orange-medium: #6e1527; @@ -31,78 +33,55 @@ --brand-color-gray-200: #dee0e3; } -/* Add to Stacks classic eventually */ - -.bg-brand-orange { - background: var(--brand-color-orange); -} -.fc-brand-orange { - color: var(--brand-color-orange) !important; -} -.bg-brand-orange-medium { - background: var(--brand-color-orange-medium); -} -.bg-brand-orange-dark { - background: var(--brand-color-orange-dark); -} - -.bg-brand-white { - background: var(--brand-color-white); -} -.bg-brand-black { - background: var(--brand-color-black); -} -.bg-brand-off-white { - background: var(--brand-color-off-white); -} - -.bg-brand-beige { - background: var(--brand-color-beige); -} - -.bg-brand-blue { - background: var(--brand-color-blue); -} -.bg-brand-blue-light { - background: var(--brand-color-blue-light); -} -.bg-brand-blue-dark { - background: var(--brand-color-blue-dark); -} - -.bg-brand-purple { - background: var(--brand-color-purple); -} -.bg-brand-purple-dark { - background: var(--brand-color-purple-dark); -} - -.bg-brand-pink { - background: var(--brand-color-pink); -} -.bg-brand-pink-dark { - background: var(--brand-color-pink-dark); -} - -.bg-brand-green { - background: var(--brand-color-green); -} -.bg-brand-green-dark { - background: var(--brand-color-green-dark); -} - -.bg-brand-yellow { - background: var(--brand-color-yellow); -} -.bg-brand-yellow-dark { - background: var(--brand-color-yellow-dark); -} - -.bg-brand-gray { - background: var(--brand-color-gray); -} -.bg-brand-gray-200 { - background: var(--brand-color-gray-200); +/* Custom theme color palette — activates when body has theme-custom + themed classes. + Primary: teal (h:170 s:37% l:48%), Secondary: purple (h:260 s:29% l:55%). + Matches the custom theme defined in stacks-docs. */ +body.theme-custom.themed { + --theme-base-primary-color-h: 170; + --theme-base-primary-color-s: 37%; + --theme-base-primary-color-l: 48%; + --theme-primary-custom-100: hsl(var(--theme-base-primary-color-h), var(--theme-base-primary-color-s), calc(var(--theme-base-primary-color-l) + ((100% - var(--theme-base-primary-color-l)) * .9))); + --theme-primary-custom-200: hsl(var(--theme-base-primary-color-h), var(--theme-base-primary-color-s), calc(var(--theme-base-primary-color-l) + ((100% - var(--theme-base-primary-color-l)) * .75))); + --theme-primary-custom-300: hsl(var(--theme-base-primary-color-h), var(--theme-base-primary-color-s), calc(var(--theme-base-primary-color-l) + ((100% - var(--theme-base-primary-color-l)) * .5))); + --theme-primary-custom-400: hsl(var(--theme-base-primary-color-h), var(--theme-base-primary-color-s), var(--theme-base-primary-color-l)); + --theme-primary-custom-500: hsl(var(--theme-base-primary-color-h), var(--theme-base-primary-color-s), calc(var(--theme-base-primary-color-l) + (var(--theme-base-primary-color-l) * -.3))); + --theme-primary-custom-600: hsl(var(--theme-base-primary-color-h), var(--theme-base-primary-color-s), calc(var(--theme-base-primary-color-l) + (var(--theme-base-primary-color-l) * -.6))); + --theme-primary-custom: var(--theme-primary-custom-400); + --theme-base-secondary-color-h: 260; + --theme-base-secondary-color-s: 29%; + --theme-base-secondary-color-l: 55%; + --theme-secondary-custom-100: hsl(var(--theme-base-secondary-color-h), var(--theme-base-secondary-color-s), calc(var(--theme-base-secondary-color-l) + ((100% - var(--theme-base-secondary-color-l)) * .9))); + --theme-secondary-custom-200: hsl(var(--theme-base-secondary-color-h), var(--theme-base-secondary-color-s), calc(var(--theme-base-secondary-color-l) + ((100% - var(--theme-base-secondary-color-l)) * .75))); + --theme-secondary-custom-300: hsl(var(--theme-base-secondary-color-h), var(--theme-base-secondary-color-s), calc(var(--theme-base-secondary-color-l) + ((100% - var(--theme-base-secondary-color-l)) * .5))); + --theme-secondary-custom-400: hsl(var(--theme-base-secondary-color-h), var(--theme-base-secondary-color-s), var(--theme-base-secondary-color-l)); + --theme-secondary-custom-500: hsl(var(--theme-base-secondary-color-h), var(--theme-base-secondary-color-s), calc(var(--theme-base-secondary-color-l) + (var(--theme-base-secondary-color-l) * -.3))); + --theme-secondary-custom-600: hsl(var(--theme-base-secondary-color-h), var(--theme-base-secondary-color-s), calc(var(--theme-base-secondary-color-l) + (var(--theme-base-secondary-color-l) * -.6))); + --theme-secondary-custom: var(--theme-secondary-custom-400); + --theme-secondary-custom-focus-ring: hsla(var(--theme-base-secondary-color-h), var(--theme-base-secondary-color-s), var(--theme-base-secondary-color-l), 0.15); + --theme-secondary-custom-translucent: hsla(var(--theme-base-secondary-color-h), var(--theme-base-secondary-color-s), var(--theme-base-secondary-color-l), 0.15); + /* Dark mode variants */ + --theme-dark-primary-color-h: 170; + --theme-dark-primary-color-s: 50%; + --theme-dark-primary-color-l: 60%; + --theme-dark-primary-custom-100: hsl(var(--theme-dark-primary-color-h), calc(var(--theme-dark-primary-color-s) + (var(--theme-dark-primary-color-s) * -.6)), calc(var(--theme-dark-primary-color-l) + (var(--theme-dark-primary-color-l) * -.7))); + --theme-dark-primary-custom-200: hsl(var(--theme-dark-primary-color-h), calc(var(--theme-dark-primary-color-s) + (var(--theme-dark-primary-color-s) * -.4)), calc(var(--theme-dark-primary-color-l) + (var(--theme-dark-primary-color-l) * -.5))); + --theme-dark-primary-custom-300: hsl(var(--theme-dark-primary-color-h), calc(var(--theme-dark-primary-color-s) + (var(--theme-dark-primary-color-s) * -.3)), calc(var(--theme-dark-primary-color-l) + (var(--theme-dark-primary-color-l) * -.2))); + --theme-dark-primary-custom-400: hsl(var(--theme-dark-primary-color-h), var(--theme-dark-primary-color-s), var(--theme-dark-primary-color-l)); + --theme-dark-primary-custom-500: hsl(var(--theme-dark-primary-color-h), var(--theme-dark-primary-color-s), calc(var(--theme-dark-primary-color-l) + ((100% - var(--theme-dark-primary-color-l)) * .5))); + --theme-dark-primary-custom-600: hsl(var(--theme-dark-primary-color-h), var(--theme-dark-primary-color-s), calc(var(--theme-dark-primary-color-l) + ((100% - var(--theme-dark-primary-color-l)) * .8))); + --theme-dark-primary-custom: var(--theme-dark-primary-custom-400); + --theme-dark-secondary-color-h: 260; + --theme-dark-secondary-color-s: 70%; + --theme-dark-secondary-color-l: 70%; + --theme-dark-secondary-custom-100: hsl(var(--theme-dark-secondary-color-h), calc(var(--theme-dark-secondary-color-s) + (var(--theme-dark-secondary-color-s) * -.6)), calc(var(--theme-dark-secondary-color-l) + (var(--theme-dark-secondary-color-l) * -.7))); + --theme-dark-secondary-custom-200: hsl(var(--theme-dark-secondary-color-h), calc(var(--theme-dark-secondary-color-s) + (var(--theme-dark-secondary-color-s) * -.4)), calc(var(--theme-dark-secondary-color-l) + (var(--theme-dark-secondary-color-l) * -.5))); + --theme-dark-secondary-custom-300: hsl(var(--theme-dark-secondary-color-h), calc(var(--theme-dark-secondary-color-s) + (var(--theme-dark-secondary-color-s) * -.3)), calc(var(--theme-dark-secondary-color-l) + (var(--theme-dark-secondary-color-l) * -.2))); + --theme-dark-secondary-custom-400: hsl(var(--theme-dark-secondary-color-h), var(--theme-dark-secondary-color-s), var(--theme-dark-secondary-color-l)); + --theme-dark-secondary-custom-500: hsl(var(--theme-dark-secondary-color-h), var(--theme-dark-secondary-color-s), calc(var(--theme-dark-secondary-color-l) + ((100% - var(--theme-dark-secondary-color-l)) * .5))); + --theme-dark-secondary-custom-600: hsl(var(--theme-dark-secondary-color-h), var(--theme-dark-secondary-color-s), calc(var(--theme-dark-secondary-color-l) + ((100% - var(--theme-dark-secondary-color-l)) * .8))); + --theme-dark-secondary-custom: var(--theme-dark-secondary-custom-400); + --theme-dark-secondary-custom-focus-ring: hsla(var(--theme-dark-secondary-color-h), var(--theme-dark-secondary-color-s), var(--theme-dark-secondary-color-l), 0.25); + --theme-dark-secondary-custom-translucent: hsla(var(--theme-dark-secondary-color-h), var(--theme-dark-secondary-color-s), var(--theme-dark-secondary-color-l), 0.25); } /* Override Stacks defaults */ @@ -131,10 +110,6 @@ body { src: url("/fonts/IBMPlexMono-Regular.woff2") format("woff2"); } -.ff-stack-sans { - font-family: "Stack Sans Text"; - font-weight: 400; -} .ff-stack-sans-headline, .ff-stack-sans-headline-notch { font-family: "Stack Sans Headline"; @@ -202,79 +177,117 @@ footer { } } -/* Document styles */ - -.doc h1 a, -.doc h2 a, -.doc h3 a, -.doc h4 a, -.doc h5 a { +/* Prose paragraph styling — applied to all p elements by the addDocClasses rehype plugin */ +.docs-copy { + color: var(--black-500); + font-size: var(--fs-body2); + line-height: 1.5; + margin-bottom: var(--su16); + margin-top: 0; +} +.docs-copy a:not([class]), +.docs-copy .s-link { + text-decoration: underline; +} +.docs-copy .docs-link { color: inherit; +} +.docs-copy code { + font-size: 0.875em; +} +.docs-copy strong { + color: var(--black-600); +} + +/* Document styles — individual classes applied by the addDocClasses rehype plugin */ + +/* Links and SVGs inside headings */ +.docs-heading .docs-link, +.docs-heading .docs-heading-anchor { + color: inherit !important; text-decoration: none; } -.doc h1 svg, -.doc h2 svg, -.doc h3 svg, -.doc h4 svg, -.doc h5 svg { +.docs-heading svg { vertical-align: middle; margin-right: 4px; } -.doc img, -.doc iframe { + +/* Heading flex layout (heading text + anchor icon side-by-side) */ +.docs-heading { + display: flex; + align-items: flex-end; + justify-content: space-between; + gap: 8px; +} + +/* Heading anchor icon appended by rehype-autolink-headings */ +.docs-heading-anchor { + flex-shrink: 0; + color: var(--black-300); + line-height: 1; + margin-bottom: 2px; +} +.docs-heading-anchor:hover { + color: var(--black-600); +} + +/* Heading-specific overrides */ +.docs-h2 { + font-size: var(--_pr-h1-fs); +} +.docs-h4 { + color: var(--black-400); +} + +/* Images and iframes */ +.docs-img, +.docs-iframe { width: 100%; height: auto; display: block; } -.doc iframe { +.docs-iframe { aspect-ratio: 16 / 9.675; } -.doc .doc__grid { + +/* Grid layout helper */ +.docs-grid { margin: 12px 0; } -.doc .doc__grid:not(.doc__grid + .doc__grid):not(:has(+ .doc__grid)) { +.docs-grid:not(.docs-grid + .docs-grid):not(:has(+ .docs-grid)) { margin: 32px 0; } -.doc section { + +/* Sections generated by rehype-sectionize */ +.docs-section { border-top: 1px solid var(--black-150); position: relative; padding: 20px 0; margin: 20px 0; } -.doc h1 a, -.doc h2 a, -.doc h3 a, -.doc h4 a { - color: inherit !important; -} -.doc section[data-heading-rank] { +.docs-section[data-heading-rank] { margin-top: 32px; } -.doc section[data-heading-rank="2"] > p { +.docs-section[data-heading-rank="2"] > .docs-p { color: var(--fc-medium); } -.doc section > section { +.docs-section > .docs-section { border-top: 0; padding: 0; margin: 0; } -.doc p:not(:has(img)), -.doc li { + +/* Prose elements */ +.docs-li { max-width: 800px; } -.doc ul li { +.docs-ul > .docs-li { list-style-type: square; } -.doc nav ul li { +.docs-nav .docs-li { list-style: none; } -.doc h2 { - font-size: var(--_pr-h1-fs); -} -.doc h4 { - color: var(--black-400); -} -.doc a { +.docs-link { font-weight: 500; } @@ -340,6 +353,13 @@ footer { border-color: var(--black-300); } +/* Docs card — used in example containers to simulate a card-like context */ +.docs-card { + border: var(--su1) solid var(--black-225); + border-radius: var(--su4); + padding: var(--su16); +} + /* Agolia Docsearch */ .DocSearch-Container { diff --git a/packages/stacks-docs-next/src/components/BannerDemo.svelte b/packages/stacks-docs-next/src/components/BannerDemo.svelte new file mode 100644 index 0000000000..d68c45a1b4 --- /dev/null +++ b/packages/stacks-docs-next/src/components/BannerDemo.svelte @@ -0,0 +1,56 @@ + + +{#if visible} + +{/if} + +
+ + +
diff --git a/packages/stacks-docs-next/src/components/BannerExample.svelte b/packages/stacks-docs-next/src/components/BannerExample.svelte new file mode 100644 index 0000000000..568c03573f --- /dev/null +++ b/packages/stacks-docs-next/src/components/BannerExample.svelte @@ -0,0 +1,29 @@ + + + diff --git a/packages/stacks-docs-next/src/components/ClassTable.svelte b/packages/stacks-docs-next/src/components/ClassTable.svelte new file mode 100644 index 0000000000..99dc7c5ad3 --- /dev/null +++ b/packages/stacks-docs-next/src/components/ClassTable.svelte @@ -0,0 +1,130 @@ + + + +
+ + {#if showHeadings} + + + + {#each activeCols as col} + + {/each} + + + {/if} + + {#each classes as row} + + + {#each activeCols as col} + + {/each} + + {/each} + +
{label('class')}{label(col)}
{row.class} + {#if col === 'responsive'} + {row.responsive ? '✓' : ''} + {:else} + {@const val = String((row as Record)[col] ?? '')} + {#if val === 'N/A'} + N/A + {:else if val.startsWith('.')} + {val} + {:else} + {val} + {/if} + {/if} +
+
+ +{#if expandable && !expanded} + +{:else} +
+{/if} diff --git a/packages/stacks-docs-next/src/components/Contents.svelte b/packages/stacks-docs-next/src/components/Contents.svelte index 3097fed471..0c2c53a0bf 100644 --- a/packages/stacks-docs-next/src/components/Contents.svelte +++ b/packages/stacks-docs-next/src/components/Contents.svelte @@ -1,7 +1,5 @@ -