diff --git a/.eleventy.js b/.eleventy.js index deed23e..3d84cdf 100644 --- a/.eleventy.js +++ b/.eleventy.js @@ -1,14 +1,35 @@ import eleventyLucideicons from "@grimlink/eleventy-plugin-lucide-icons"; +import prettier from "prettier"; export default async function(eleventyConfig) { eleventyConfig.setInputDirectory("./docs"); eleventyConfig.setServerPassthroughCopyBehavior("passthrough"); eleventyConfig.addPassthroughCopy({"./dist/basecoat.css": "./assets/styles.css"}); eleventyConfig.addPlugin(eleventyLucideicons); + eleventyConfig.addNunjucksAsyncFilter("prettyHtml", async (code, callback) => { + try { + const formattedCode = await prettier.format(code, { + parser: "html", + printWidth: 1000, + singleAttributePerLine: false, + bracketSameLine: true, + htmlWhitespaceSensitivity: "ignore" + }); + callback(null, formattedCode); + } catch (err) { + console.error("Error formatting HTML with Prettier:", err); + callback(err, code); + } + }); // Registry to ensure component assets (JS) load only once per page. - let componentRegistry = {} - eleventyConfig.on('beforeBuild', () => { componentRegistry = {}; }) + let componentRegistry; + eleventyConfig.on('beforeBuild', () => { componentRegistry = {}; }); eleventyConfig.addNunjucksGlobal("registerComponent", function(componentName) { + // Reset registry at the start of each page build + if (!this.page) { + componentRegistry = {}; + } + if (!componentRegistry[componentName]) { componentRegistry[componentName] = true; return true; diff --git a/dist/basecoat.css b/dist/basecoat.css index 5d64503..77707a1 100644 --- a/dist/basecoat.css +++ b/dist/basecoat.css @@ -21,12 +21,18 @@ --color-blue-700: oklch(48.8% 0.243 264.376); --color-blue-900: oklch(37.9% 0.146 265.522); --color-blue-950: oklch(28.2% 0.091 267.935); + --color-zinc-50: oklch(98.5% 0 0); + --color-zinc-700: oklch(37% 0.013 285.805); + --color-neutral-900: oklch(20.5% 0 0); --color-black: #000; --color-white: #fff; --spacing: 0.25rem; + --breakpoint-sm: 40rem; + --breakpoint-md: 48rem; --breakpoint-lg: 64rem; --container-xs: 20rem; --container-sm: 24rem; + --container-md: 28rem; --container-lg: 32rem; --container-xl: 36rem; --text-xs: 0.75rem; @@ -41,6 +47,8 @@ --text-xl--line-height: calc(1.75 / 1.25); --text-2xl: 1.5rem; --text-2xl--line-height: calc(2 / 1.5); + --text-3xl: 1.875rem; + --text-3xl--line-height: calc(2.25 / 1.875); --font-weight-normal: 400; --font-weight-medium: 500; --font-weight-semibold: 600; @@ -281,6 +289,15 @@ .top-1\/2 { top: calc(1/2 * 100%); } + .top-3 { + top: calc(var(--spacing) * 3); + } + .top-22 { + top: calc(var(--spacing) * 22); + } + .right-3 { + right: calc(var(--spacing) * 3); + } .left-0 { left: calc(var(--spacing) * 0); } @@ -299,21 +316,51 @@ .col-span-2 { grid-column: span 2 / span 2; } + .container { + width: 100%; + @media (width >= 40rem) { + max-width: 40rem; + } + @media (width >= 48rem) { + max-width: 48rem; + } + @media (width >= 64rem) { + max-width: 64rem; + } + @media (width >= 80rem) { + max-width: 80rem; + } + @media (width >= 96rem) { + max-width: 96rem; + } + } .mx-auto { margin-inline: auto; } + .my-4 { + margin-block: calc(var(--spacing) * 4); + } + .my-6 { + margin-block: calc(var(--spacing) * 6); + } .mt-4 { margin-top: calc(var(--spacing) * 4); } .mr-auto { margin-right: auto; } + .mb-6 { + margin-bottom: calc(var(--spacing) * 6); + } .ml-\(--sidebar-width\) { margin-left: var(--sidebar-width); } .ml-auto { margin-left: auto; } + .block { + display: block; + } .flex { display: flex; } @@ -346,10 +393,6 @@ width: calc(var(--spacing) * 4); height: calc(var(--spacing) * 4); } - .size-6 { - width: calc(var(--spacing) * 6); - height: calc(var(--spacing) * 6); - } .size-8 { width: calc(var(--spacing) * 8); height: calc(var(--spacing) * 8); @@ -390,6 +433,12 @@ .max-h-\[612px\] { max-height: 612px; } + .max-h-\[650px\] { + max-height: 650px; + } + .min-h-\[350px\] { + min-height: 350px; + } .scrollbar { scrollbar-width: thin; scrollbar-color: var(--scrollbar-thumb) var(--scrollbar-track); @@ -413,6 +462,9 @@ .w-4 { width: calc(var(--spacing) * 4); } + .w-6 { + width: calc(var(--spacing) * 6); + } .w-72 { width: calc(var(--spacing) * 72); } @@ -440,12 +492,24 @@ .max-w-lg { max-width: var(--container-lg); } + .max-w-md { + max-width: var(--container-md); + } + .max-w-screen-lg { + max-width: var(--breakpoint-lg); + } + .max-w-screen-md { + max-width: var(--breakpoint-md); + } .max-w-sm { max-width: var(--container-sm); } .max-w-xl { max-width: var(--container-xl); } + .min-w-0 { + min-width: calc(var(--spacing) * 0); + } .min-w-5 { min-width: calc(var(--spacing) * 5); } @@ -535,6 +599,13 @@ .gap-8 { gap: calc(var(--spacing) * 8); } + .space-y-2 { + :where(& > :not(:last-child)) { + --tw-space-y-reverse: 0; + margin-block-start: calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse)); + margin-block-end: calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse))); + } + } .space-y-4 { :where(& > :not(:last-child)) { --tw-space-y-reverse: 0; @@ -542,6 +613,13 @@ margin-block-end: calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse))); } } + .space-y-6 { + :where(& > :not(:last-child)) { + --tw-space-y-reverse: 0; + margin-block-start: calc(calc(var(--spacing) * 6) * var(--tw-space-y-reverse)); + margin-block-end: calc(calc(var(--spacing) * 6) * calc(1 - var(--tw-space-y-reverse))); + } + } .gap-x-2 { column-gap: calc(var(--spacing) * 2); } @@ -555,6 +633,13 @@ margin-inline-end: calc(calc(var(--spacing) * -2) * calc(1 - var(--tw-space-x-reverse))); } } + .space-x-2 { + :where(& > :not(:last-child)) { + --tw-space-x-reverse: 0; + margin-inline-start: calc(calc(var(--spacing) * 2) * var(--tw-space-x-reverse)); + margin-inline-end: calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-x-reverse))); + } + } .gap-y-4 { row-gap: calc(var(--spacing) * 4); } @@ -590,6 +675,9 @@ .rounded-sm { border-radius: var(--radius-sm); } + .rounded-xl { + border-radius: var(--radius-xl); + } .border { border-style: var(--tw-border-style); border-width: 1px; @@ -605,6 +693,9 @@ .border-amber-50 { border-color: var(--color-amber-50); } + .\!bg-neutral-900 { + background-color: var(--color-neutral-900) !important; + } .bg-accent { background-color: var(--color-accent); } @@ -626,6 +717,9 @@ .object-cover { object-fit: cover; } + .p-0 { + padding: calc(var(--spacing) * 0); + } .p-2 { padding: calc(var(--spacing) * 2); } @@ -635,6 +729,9 @@ .p-4 { padding: calc(var(--spacing) * 4); } + .p-10 { + padding: calc(var(--spacing) * 10); + } .px-0 { padding-inline: calc(var(--spacing) * 0); } @@ -659,9 +756,18 @@ .py-4 { padding-block: calc(var(--spacing) * 4); } + .py-6 { + padding-block: calc(var(--spacing) * 6); + } + .pt-8 { + padding-top: calc(var(--spacing) * 8); + } .pb-4 { padding-bottom: calc(var(--spacing) * 4); } + .pb-12 { + padding-bottom: calc(var(--spacing) * 12); + } .pl-6 { padding-left: calc(var(--spacing) * 6); } @@ -680,6 +786,10 @@ .font-mono { font-family: var(--font-mono); } + .text-3xl { + font-size: var(--text-3xl); + line-height: var(--tw-leading, var(--text-3xl--line-height)); + } .text-base { font-size: var(--text-base); line-height: var(--tw-leading, var(--text-base--line-height)); @@ -720,6 +830,14 @@ --tw-font-weight: var(--font-weight-normal); font-weight: var(--font-weight-normal); } + .font-semibold { + --tw-font-weight: var(--font-weight-semibold); + font-weight: var(--font-weight-semibold); + } + .tracking-tight { + --tw-tracking: var(--tracking-tight); + letter-spacing: var(--tracking-tight); + } .tracking-widest { --tw-tracking: var(--tracking-widest); letter-spacing: var(--tracking-widest); @@ -727,6 +845,12 @@ .break-words { overflow-wrap: break-word; } + .whitespace-nowrap { + white-space: nowrap; + } + .whitespace-pre-wrap { + white-space: pre-wrap; + } .text-amber-900 { color: var(--color-amber-900); } @@ -754,10 +878,16 @@ .text-transparent { color: transparent; } + .text-zinc-50 { + color: var(--color-zinc-50); + } .tabular-nums { --tw-numeric-spacing: tabular-nums; font-variant-numeric: var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,); } + .underline { + text-decoration-line: underline; + } .underline-offset-4 { text-underline-offset: 4px; } @@ -778,6 +908,9 @@ .ring-sidebar-ring { --tw-ring-color: var(--color-sidebar-ring); } + .ring-offset-background { + --tw-ring-offset-color: var(--color-background); + } .outline-hidden { --tw-outline-style: none; outline-style: none; @@ -786,6 +919,10 @@ outline-offset: 2px; } } + .outline { + outline-style: var(--tw-outline-style); + outline-width: 1px; + } .filter { filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,); } @@ -925,6 +1062,13 @@ } } } + .hover\:bg-zinc-700 { + &:hover { + @media (hover: hover) { + background-color: var(--color-zinc-700); + } + } + } .hover\:text-foreground { &:hover { @media (hover: hover) { @@ -939,6 +1083,13 @@ } } } + .hover\:text-zinc-50 { + &:hover { + @media (hover: hover) { + color: var(--color-zinc-50); + } + } + } .hover\:underline { &:hover { @media (hover: hover) { @@ -964,6 +1115,12 @@ border-color: var(--color-ring); } } + .focus-visible\:ring-1 { + &:focus-visible { + --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor); + box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); + } + } .focus-visible\:ring-2 { &:focus-visible { --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor); @@ -976,6 +1133,11 @@ box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); } } + .focus-visible\:ring-ring { + &:focus-visible { + --tw-ring-color: var(--color-ring); + } + } .focus-visible\:ring-ring\/50 { &:focus-visible { --tw-ring-color: color-mix(in srgb, var(--ring) 50%, transparent); @@ -984,6 +1146,28 @@ } } } + .focus-visible\:ring-offset-2 { + &:focus-visible { + --tw-ring-offset-width: 2px; + --tw-ring-offset-shadow: var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + } + } + .focus-visible\:outline-none { + &:focus-visible { + --tw-outline-style: none; + outline-style: none; + } + } + .disabled\:pointer-events-none { + &:disabled { + pointer-events: none; + } + } + .disabled\:opacity-50 { + &:disabled { + opacity: 50%; + } + } .has-\[input\[type\=\'checkbox\'\]\:checked\]\:border-blue-600 { &:has(*:is(input[type='checkbox']:checked)) { border-color: var(--color-blue-600); @@ -1030,6 +1214,21 @@ flex-direction: row; } } + .lg\:gap-10 { + @media (width >= 64rem) { + gap: calc(var(--spacing) * 10); + } + } + .lg\:py-8 { + @media (width >= 64rem) { + padding-block: calc(var(--spacing) * 8); + } + } + .xl\:block { + @media (width >= 80rem) { + display: block; + } + } .\@md\:w-auto { @container (width >= 28rem) { width: auto; @@ -1146,6 +1345,37 @@ } } } + .\[\&_a\]\:inline-block { + & a { + display: inline-block; + } + } + .\[\&_a\]\:text-muted-foreground { + & a { + color: var(--color-muted-foreground); + } + } + .\[\&_a\]\:no-underline { + & a { + text-decoration-line: none; + } + } + .\[\&_a\]\:transition-colors { + & a { + transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to; + transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); + transition-duration: var(--tw-duration, var(--default-transition-duration)); + } + } + .\[\&_a\]\:hover\:text-foreground { + & a { + &:hover { + @media (hover: hover) { + color: var(--color-foreground); + } + } + } + } .\[\&_img\]\:size-8 { & img { width: calc(var(--spacing) * 8); @@ -1184,6 +1414,11 @@ --tw-ring-color: var(--color-background); } } + .\[\&_img\]\:ring-card { + & img { + --tw-ring-color: var(--color-card); + } + } .\[\&_img\]\:grayscale { & img { --tw-grayscale: grayscale(100%); @@ -1209,11 +1444,62 @@ transition-timing-function: var(--ease-in-out); } } + .\[\&_li\]\:mt-0 { + & li { + margin-top: calc(var(--spacing) * 0); + } + } + .\[\&_li\]\:pt-2 { + & li { + padding-top: calc(var(--spacing) * 2); + } + } + .\[\&_svg\]\:pointer-events-none { + & svg { + pointer-events: none; + } + } + .\[\&_svg\]\:size-4 { + & svg { + width: calc(var(--spacing) * 4); + height: calc(var(--spacing) * 4); + } + } + .\[\&_svg\]\:h-3 { + & svg { + height: calc(var(--spacing) * 3); + } + } + .\[\&_svg\]\:w-3 { + & svg { + width: calc(var(--spacing) * 3); + } + } + .\[\&_svg\]\:shrink-0 { + & svg { + flex-shrink: 0; + } + } .\[\&_svg\]\:\!text-destructive { & svg { color: var(--color-destructive) !important; } } + .\[\&_ul\]\:m-0 { + & ul { + margin: calc(var(--spacing) * 0); + } + } + .\[\&_ul\]\:list-none { + & ul { + list-style-type: none; + } + } + .\[\&_ul_ul\]\:pl-4 { + & ul ul { + padding-left: calc(var(--spacing) * 4); + } + } .md\:\*\:\[\.card\]\:basis-1\/4 { @media (width >= 48rem) { :is(& > *) { @@ -1223,6 +1509,80 @@ } } } + .\[\&\>h2\]\:mt-16 { + &>h2 { + margin-top: calc(var(--spacing) * 16); + } + } + .\[\&\>h2\]\:scroll-m-22 { + &>h2 { + scroll-margin: calc(var(--spacing) * 22); + } + } + .\[\&\>h2\]\:border-b { + &>h2 { + border-bottom-style: var(--tw-border-style); + border-bottom-width: 1px; + } + } + .\[\&\>h2\]\:pb-4 { + &>h2 { + padding-bottom: calc(var(--spacing) * 4); + } + } + .\[\&\>h2\]\:text-xl { + &>h2 { + font-size: var(--text-xl); + line-height: var(--tw-leading, var(--text-xl--line-height)); + } + } + .\[\&\>h2\]\:font-semibold { + &>h2 { + --tw-font-weight: var(--font-weight-semibold); + font-weight: var(--font-weight-semibold); + } + } + .\[\&\>h2\]\:tracking-tight { + &>h2 { + --tw-tracking: var(--tracking-tight); + letter-spacing: var(--tracking-tight); + } + } + .\[\&\>h2\]\:first\:mt-0 { + &>h2 { + &:first-child { + margin-top: calc(var(--spacing) * 0); + } + } + } + .\[\&\>h3\]\:mt-8 { + &>h3 { + margin-top: calc(var(--spacing) * 8); + } + } + .\[\&\>h3\]\:scroll-m-22 { + &>h3 { + scroll-margin: calc(var(--spacing) * 22); + } + } + .\[\&\>h3\]\:text-lg { + &>h3 { + font-size: var(--text-lg); + line-height: var(--tw-leading, var(--text-lg--line-height)); + } + } + .\[\&\>h3\]\:font-semibold { + &>h3 { + --tw-font-weight: var(--font-weight-semibold); + font-weight: var(--font-weight-semibold); + } + } + .\[\&\>h3\]\:tracking-tight { + &>h3 { + --tw-tracking: var(--tracking-tight); + letter-spacing: var(--tracking-tight); + } + } .\[\&\>svg\]\:size-4 { &>svg { width: calc(var(--spacing) * 4); @@ -1434,7 +1794,7 @@ } } @layer components { - .btn, .btn-primary, .btn-secondary, .btn-outline, .btn-ghost, .btn-link, .btn-destructive, .btn-sm, .btn-sm-primary, .btn-sm-secondary, .btn-sm-outline, .btn-sm-ghost, .btn-sm-link, .btn-sm-destructive, .btn-lg, .btn-lg-primary, .btn-lg-secondary, .btn-lg-outline, .btn-lg-ghost, .btn-lg-link, .btn-lg-destructive, .btn-icon, .btn-icon-primary, .btn-icon-secondary, .btn-icon-outline, .btn-icon-ghost, .btn-icon-link, .btn-icon-destructive { + .btn, .btn-primary, .btn-secondary, .btn-outline, .btn-ghost, .btn-link, .btn-destructive, .btn-sm, .btn-sm-primary, .btn-sm-secondary, .btn-sm-outline, .btn-sm-ghost, .btn-sm-link, .btn-sm-destructive, .btn-lg, .btn-lg-primary, .btn-lg-secondary, .btn-lg-outline, .btn-lg-ghost, .btn-lg-link, .btn-lg-destructive, .btn-icon, .btn-icon-primary, .btn-icon-secondary, .btn-icon-outline, .btn-icon-ghost, .btn-icon-link, .btn-icon-destructive, .btn-sm-icon, .btn-sm-icon-primary, .btn-sm-icon-secondary, .btn-sm-icon-outline, .btn-sm-icon-ghost, .btn-sm-icon-link, .btn-sm-icon-destructive, .btn-lg-icon, .btn-lg-icon-primary, .btn-lg-icon-secondary, .btn-lg-icon-outline, .btn-lg-icon-ghost, .btn-lg-icon-link, .btn-lg-icon-destructive { display: inline-flex; flex-shrink: 0; cursor: pointer; @@ -1519,6 +1879,10 @@ padding-inline: calc(var(--spacing) * 2.5); } } + .btn-sm-icon, .btn-sm-icon-primary, .btn-sm-icon-secondary, .btn-sm-icon-outline, .btn-sm-icon-ghost, .btn-sm-icon-link, .btn-sm-icon-destructive { + width: calc(var(--spacing) * 8); + height: calc(var(--spacing) * 8); + } .btn-lg, .btn-lg-primary, .btn-lg-secondary, .btn-lg-outline, .btn-lg-ghost, .btn-lg-link, .btn-lg-destructive { height: calc(var(--spacing) * 10); gap: calc(var(--spacing) * 2); @@ -1527,7 +1891,11 @@ padding-inline: calc(var(--spacing) * 4); } } - .btn, .btn-primary, .btn-sm, .btn-sm-primary, .btn-lg, .btn-lg-primary, .btn-icon, .btn-icon-primary { + .btn-lg-icon, .btn-lg-icon-primary, .btn-lg-icon-secondary, .btn-lg-icon-outline, .btn-lg-icon-ghost, .btn-lg-icon-link, .btn-lg-icon-destructive { + width: calc(var(--spacing) * 10); + height: calc(var(--spacing) * 10); + } + .btn, .btn-primary, .btn-sm, .btn-sm-primary, .btn-lg, .btn-lg-primary, .btn-icon, .btn-icon-primary, .btn-sm-icon, .btn-sm-icon-primary, .btn-lg-icon, .btn-lg-icon-primary { background-color: var(--color-primary); color: var(--color-primary-foreground); --tw-shadow: 0 1px 2px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.05)); @@ -1547,7 +1915,7 @@ } } } - .btn-secondary, .btn-sm-secondary, .btn-lg-secondary, .btn-icon-secondary { + .btn-secondary, .btn-sm-secondary, .btn-lg-secondary, .btn-icon-secondary, .btn-sm-icon-secondary, .btn-lg-icon-secondary { background-color: var(--color-secondary); color: var(--color-secondary-foreground); --tw-shadow: 0 1px 2px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.05)); @@ -1559,7 +1927,7 @@ } } } - .btn-outline, .btn-sm-outline, .btn-lg-outline, .btn-icon-outline { + .btn-outline, .btn-sm-outline, .btn-lg-outline, .btn-icon-outline, .btn-sm-icon-outline, .btn-lg-icon-outline { border-style: var(--tw-border-style); border-width: 1px; background-color: var(--color-background); @@ -1585,7 +1953,7 @@ } } } - .btn-ghost, .btn-sm-ghost, .btn-lg-ghost, .btn-icon-ghost { + .btn-ghost, .btn-sm-ghost, .btn-lg-ghost, .btn-icon-ghost, .btn-sm-icon-ghost, .btn-lg-icon-ghost { &:hover, &[aria-pressed='true'] { background-color: var(--color-accent); color: var(--color-accent-foreground); @@ -1597,7 +1965,7 @@ } } } - .btn-link, .btn-sm-link, .btn-lg-link, .btn-icon-link { + .btn-link, .btn-sm-link, .btn-lg-link, .btn-icon-link, .btn-sm-icon-link, .btn-lg-icon-link { color: var(--color-primary); text-underline-offset: 4px; &:hover, &[aria-pressed='true'] { @@ -1608,7 +1976,7 @@ } } } - .btn-destructive, .btn-sm-destructive, .btn-lg-destructive, .btn-icon-destructive { + .btn-destructive, .btn-sm-destructive, .btn-lg-destructive, .btn-icon-destructive, .btn-sm-icon-destructive, .btn-lg-icon-destructive { background-color: var(--color-destructive); color: var(--color-white); --tw-shadow: 0 1px 2px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.05)); @@ -2401,6 +2769,12 @@ color: var(--color-accent-foreground); } } + &:focus-visible { + background-color: var(--color-accent); + } + &:focus-visible { + color: var(--color-accent-foreground); + } } [role='option'] { padding-right: calc(var(--spacing) * 7.5); @@ -2981,6 +3355,9 @@ } @layer components { .tabs { + display: flex; + flex-direction: column; + gap: calc(var(--spacing) * 2); [role='tablist'] { display: inline-flex; height: calc(var(--spacing) * 9); @@ -3408,6 +3785,116 @@ } } } +@layer components { + .prose h1, .prose h2, .prose h3, .prose h4, .prose h5, .prose h6, .h1, .h2, .h3, .h4, .h5, .h6 { + --tw-leading: var(--leading-tight); + line-height: var(--leading-tight); + --tw-font-weight: var(--font-weight-medium); + font-weight: var(--font-weight-medium); + } + .prose h1, .h1 { + font-size: var(--text-2xl); + line-height: var(--tw-leading, var(--text-2xl--line-height)); + } + .prose h2, .h2 { + font-size: var(--text-xl); + line-height: var(--tw-leading, var(--text-xl--line-height)); + } + .prose h3, .h3 { + font-size: var(--text-lg); + line-height: var(--tw-leading, var(--text-lg--line-height)); + } + .prose h4, .prose h5, .prose h6, .h4, .h5, .h6 { + font-size: var(--text-base); + line-height: var(--tw-leading, var(--text-base--line-height)); + } + .prose a, .link { + --tw-font-weight: var(--font-weight-medium); + font-weight: var(--font-weight-medium); + text-decoration-line: underline; + text-underline-offset: 4px; + } + .prose code, .code { + position: relative; + border-radius: 0.25rem; + background-color: var(--color-muted); + padding-inline: 0.3rem; + padding-block: 0.2rem; + font-family: var(--font-mono); + font-size: var(--text-sm); + line-height: var(--tw-leading, var(--text-sm--line-height)); + } + .prose pre:has(> code), .code-block { + border-radius: var(--radius-md); + border-color: var(--color-border); + background-color: var(--color-muted); + } + .prose pre code, .code-block code { + display: inline-block; + padding: calc(var(--spacing) * 4); + font-family: var(--font-mono); + font-size: var(--text-sm); + line-height: var(--tw-leading, var(--text-sm--line-height)); + } + .prose blockquote, .quote { + border-left-style: var(--tw-border-style); + border-left-width: 4px; + border-color: var(--color-border); + padding-left: calc(var(--spacing) * 4); + } + .prose ol, .ordered-list { + margin-block: calc(var(--spacing) * 6); + margin-left: calc(var(--spacing) * 6); + list-style-type: decimal; + li { + margin-bottom: calc(var(--spacing) * 2); + } + } + .prose ul, .unordered-list { + margin-block: calc(var(--spacing) * 6); + margin-left: calc(var(--spacing) * 6); + list-style-type: disc; + li { + margin-bottom: calc(var(--spacing) * 2); + } + } + .prose > *:first-child { + margin-top: calc(var(--spacing) * 0) !important; + } + .prose > *:last-child { + margin-bottom: calc(var(--spacing) * 0) !important; + } + .prose h1 { + margin-bottom: calc(var(--spacing) * 8); + } + .prose h2 { + margin-top: calc(var(--spacing) * 8); + margin-bottom: calc(var(--spacing) * 6); + } + .prose h3 { + margin-top: calc(var(--spacing) * 6); + margin-bottom: calc(var(--spacing) * 4); + } + .prose h4 { + margin-block: calc(var(--spacing) * 4); + } + .prose h5 { + margin-block: calc(var(--spacing) * 4); + } + .prose h6 { + margin-block: calc(var(--spacing) * 4); + } + .prose > p, .prose > blockquote, .prose > ul, .prose > ol, .prose > dl, .prose > table, .prose > pre, .prose > p { + margin-block: calc(var(--spacing) * 4); + } + .prose > *:last-child { + margin-bottom: calc(var(--spacing) * 0) !important; + } + .prose strong, .prose b { + --tw-font-weight: var(--font-weight-semibold); + font-weight: var(--font-weight-semibold); + } +} @property --tw-translate-x { syntax: "*"; inherits: false; @@ -3535,6 +4022,11 @@ inherits: false; initial-value: 0 0 #0000; } +@property --tw-outline-style { + syntax: "*"; + inherits: false; + initial-value: solid; +} @property --tw-blur { syntax: "*"; inherits: false; @@ -3616,11 +4108,6 @@ inherits: false; initial-value: 1; } -@property --tw-outline-style { - syntax: "*"; - inherits: false; - initial-value: solid; -} @keyframes spin { to { transform: rotate(360deg); @@ -3662,6 +4149,7 @@ --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 #0000; + --tw-outline-style: solid; --tw-blur: initial; --tw-brightness: initial; --tw-contrast: initial; @@ -3681,7 +4169,6 @@ --tw-scale-x: 1; --tw-scale-y: 1; --tw-scale-z: 1; - --tw-outline-style: solid; } } } diff --git a/dist/basecoat.tailwind.css b/dist/basecoat.tailwind.css index 06cb756..3d182a2 100644 --- a/dist/basecoat.tailwind.css +++ b/dist/basecoat.tailwind.css @@ -231,7 +231,21 @@ .btn-icon-outline, .btn-icon-ghost, .btn-icon-link, - .btn-icon-destructive { + .btn-icon-destructive, + .btn-sm-icon, + .btn-sm-icon-primary, + .btn-sm-icon-secondary, + .btn-sm-icon-outline, + .btn-sm-icon-ghost, + .btn-sm-icon-link, + .btn-sm-icon-destructive, + .btn-lg-icon, + .btn-lg-icon-primary, + .btn-lg-icon-secondary, + .btn-lg-icon-outline, + .btn-lg-icon-ghost, + .btn-lg-icon-link, + .btn-lg-icon-destructive { @apply inline-flex items-center justify-center whitespace-nowrap text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive cursor-pointer rounded-md; } .btn, @@ -261,6 +275,15 @@ .btn-sm-destructive { @apply gap-1.5 h-8 px-3 has-[>svg]:px-2.5; } + .btn-sm-icon, + .btn-sm-icon-primary, + .btn-sm-icon-secondary, + .btn-sm-icon-outline, + .btn-sm-icon-ghost, + .btn-sm-icon-link, + .btn-sm-icon-destructive { + @apply size-8; + } .btn-lg, .btn-lg-primary, .btn-lg-secondary, @@ -270,6 +293,15 @@ .btn-lg-destructive { @apply gap-2 h-10 px-6 has-[>svg]:px-4; } + .btn-lg-icon, + .btn-lg-icon-primary, + .btn-lg-icon-secondary, + .btn-lg-icon-outline, + .btn-lg-icon-ghost, + .btn-lg-icon-link, + .btn-lg-icon-destructive { + @apply size-10; + } .btn, .btn-primary, .btn-sm, @@ -277,7 +309,11 @@ .btn-lg, .btn-lg-primary, .btn-icon, - .btn-icon-primary { + .btn-icon-primary, + .btn-sm-icon, + .btn-sm-icon-primary, + .btn-lg-icon, + .btn-lg-icon-primary { @apply bg-primary text-primary-foreground shadow-xs hover:bg-primary/90; &[aria-pressed='true'] { @apply bg-primary/90; @@ -286,7 +322,9 @@ .btn-secondary, .btn-sm-secondary, .btn-lg-secondary, - .btn-icon-secondary { + .btn-icon-secondary, + .btn-sm-icon-secondary, + .btn-lg-icon-secondary { @apply bg-secondary text-secondary-foreground shadow-xs; &:hover, &[aria-pressed='true'] { @@ -296,7 +334,9 @@ .btn-outline, .btn-sm-outline, .btn-lg-outline, - .btn-icon-outline { + .btn-icon-outline, + .btn-sm-icon-outline, + .btn-lg-icon-outline { @apply border bg-background shadow-xs dark:bg-input/30 dark:border-input; &:hover, &[aria-pressed='true'] { @@ -306,7 +346,9 @@ .btn-ghost, .btn-sm-ghost, .btn-lg-ghost, - .btn-icon-ghost { + .btn-icon-ghost, + .btn-sm-icon-ghost, + .btn-lg-icon-ghost { &:hover, &[aria-pressed='true'] { @apply bg-accent text-accent-foreground dark:bg-accent/50; @@ -315,7 +357,9 @@ .btn-link, .btn-sm-link, .btn-lg-link, - .btn-icon-link { + .btn-icon-link, + .btn-sm-icon-link, + .btn-lg-icon-link { @apply text-primary underline-offset-4; &:hover, &[aria-pressed='true'] { @@ -325,7 +369,9 @@ .btn-destructive, .btn-sm-destructive, .btn-lg-destructive, - .btn-icon-destructive { + .btn-icon-destructive, + .btn-sm-icon-destructive, + .btn-lg-icon-destructive { @apply bg-destructive text-white shadow-xs focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60; &:hover, &[aria-pressed='true'] { @@ -585,13 +631,13 @@ @apply aria-hidden:hidden [&_svg]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none [&_svg]:shrink-0 [&_svg]:size-4 aria-disabled:opacity-50 aria-disabled:pointer-events-none w-full truncate; } [role='menuitem'] { - @apply hover:bg-accent hover:text-accent-foreground; + @apply focus-visible:bg-accent focus-visible:text-accent-foreground hover:bg-accent hover:text-accent-foreground; } [role='option'] { @apply data-[focus]:bg-accent data-[focus]:text-accent-foreground pr-7.5; &[aria-selected='true'] { - @apply bg-[image:var(--check-icon)] bg-no-repeat bg-position-[center_right_0.5rem] bg-size-[0.875rem]; + @apply bg-[image:var(--check-icon)] bg-no-repeat bg-position-[center_right_0.5rem] bg-size-[0.875rem]; } } [role='menu'] [role='heading'] { @@ -744,7 +790,9 @@ /* Tabs */ @layer components { - .tabs { + .tabs { + @apply flex flex-col gap-2; + [role='tablist'] { @apply bg-muted text-muted-foreground inline-flex h-9 w-fit items-center justify-center rounded-lg p-[3px]; @@ -821,7 +869,7 @@ } &:not([data-side]), &[data-side='top'] { - @apply before:bottom-full before:mb-1.5 before:translate-y-2 hover:before:translate-y-0 ; + @apply before:bottom-full before:mb-1.5 before:translate-y-2 hover:before:translate-y-0 ; } &[data-side='bottom'] { @apply before:top-full before:mt-1.5 before:-translate-y-2 hover:before:translate-y-0 ; @@ -860,4 +908,120 @@ } } } +} + +/* Prose */ +@layer components { + .prose h1, + .prose h2, + .prose h3, + .prose h4, + .prose h5, + .prose h6, + .h1, + .h2, + .h3, + .h4, + .h5, + .h6 { + @apply font-medium leading-tight; + } + .prose h1, + .h1 { + @apply text-2xl; + } + .prose h2, + .h2 { + @apply text-xl; + } + .prose h3, + .h3 { + @apply text-lg; + } + .prose h4, + .prose h5, + .prose h6, + .h4, + .h5, + .h6 { + @apply text-base; + } + .prose a, + .link { + @apply font-medium underline underline-offset-4; + } + .prose code, + .code { + @apply relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm; + } + .prose pre:has(> code), + .code-block { + @apply bg-muted border-border rounded-md; + } + .prose pre code, + .code-block code { + @apply inline-block p-4 text-sm font-mono; + } + .prose blockquote, + .quote { + @apply border-l-4 border-border pl-4; + } + .prose ol, + .ordered-list { + @apply my-6 ml-6 list-decimal; + + li { + @apply mb-2; + } + } + .prose ul, + .unordered-list { + @apply my-6 ml-6 list-disc; + + li { + @apply mb-2; + } + } + .prose > *:first-child { + @apply !mt-0; + } + .prose > *:last-child { + @apply !mb-0; + } + .prose h1 { + @apply mb-8; + } + .prose h2 { + @apply mt-8 mb-6; + } + .prose h3 { + @apply mt-6 mb-4; + } + .prose h4 { + @apply my-4; + } + .prose h5 { + @apply my-4; + } + .prose h6 { + @apply my-4; + } + .prose > p, + .prose > blockquote, + .prose > ul, + .prose > ol, + .prose > dl, + .prose > table, + .prose > pre, + .prose > p { + @apply my-4; + } + .prose > *:last-child { + @apply !mb-0; + } + + .prose strong, + .prose b { + @apply font-semibold; + } } \ No newline at end of file diff --git a/docs/_data/site.json b/docs/_data/site.json new file mode 100644 index 0000000..117809d --- /dev/null +++ b/docs/_data/site.json @@ -0,0 +1,4 @@ +{ + "title": "Basecoat", + "description": "Minimal CSS UI kit for vanilla HTML." +} \ No newline at end of file diff --git a/docs/_includes/components/dialog.njk b/docs/_includes/components/dialog.njk index 7cdb5d0..c7d6cab 100644 --- a/docs/_includes/components/dialog.njk +++ b/docs/_includes/components/dialog.njk @@ -27,21 +27,21 @@ this.open = initialOpen; this.closeOnOverlayClick = initialCloseOnOverlayClick; }, - show() { if (!this.open) { this.open = true; - this.$nextTick(() => this.$el.dispatchEvent(new CustomEvent('dialog:opened', { bubbles: true }))); + this.$nextTick(() => { + this.$el.dispatchEvent(new CustomEvent('dialog:opened', { bubbles: true })); + setTimeout(() => this.$refs.dialog.focus(), 50); + }); } }, - hide() { if (this.open) { this.open = false; this.$el.dispatchEvent(new CustomEvent('dialog:closed', { bubbles: true })); } }, - handleControl(event) { const detail = event.detail; if (detail && detail.targetId === this.id) { @@ -52,9 +52,7 @@ }, $main: { - '@dialog:control.window'(e) { - this.handleControl(e) - }, + '@dialog:control.window'(e) { this.handleControl(e) }, }, $trigger: { @@ -63,9 +61,9 @@ }, $content: { + '@keydown.escape'() { this.open && this.hide() }, ':inert'() { return !this.open }, '@click'(e) { e.target === this.$el && this.closeOnOverlayClick && this.hide() }, - '@keydown.escape.prevent'() { this.open && this.hide() }, 'x-cloak': '' } })); @@ -97,6 +95,8 @@ +{% endmacro %} \ No newline at end of file diff --git a/docs/_includes/layouts/base.njk b/docs/_includes/layouts/base.njk new file mode 100644 index 0000000..e75e7ee --- /dev/null +++ b/docs/_includes/layouts/base.njk @@ -0,0 +1,113 @@ + + + + + + + + + + + {{ site.title + ": " + title if page.url === "/" else title + " - " + site.title }} + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + +
+
+ +
+ {{ content | safe }} +
+
+{% from "components/toast.njk" import toaster %} +{{ toaster() }} + + \ No newline at end of file diff --git a/docs/_includes/layouts/component.njk b/docs/_includes/layouts/component.njk new file mode 100644 index 0000000..e63d0f8 --- /dev/null +++ b/docs/_includes/layouts/component.njk @@ -0,0 +1,47 @@ +--- +layout: layouts/base.njk +--- + +
+
+
+

{{ title }}

+

{{ description }}

+
+
+ {{ content | safe }} +
+
+ +
+ + + + + + + \ No newline at end of file diff --git a/docs/_includes/macros/code_block.njk b/docs/_includes/macros/code_block.njk new file mode 100644 index 0000000..58c993d --- /dev/null +++ b/docs/_includes/macros/code_block.njk @@ -0,0 +1,29 @@ +{% macro code_block(code, language="html") %} +
+
{{- code | escape -}}
+ + +
+{% endmacro %} + diff --git a/docs/_includes/macros/code_preview.njk b/docs/_includes/macros/code_preview.njk new file mode 100644 index 0000000..2447ee5 --- /dev/null +++ b/docs/_includes/macros/code_preview.njk @@ -0,0 +1,27 @@ +{% macro code_preview(id, code, class=None, default_code=false) %} +{% from "./code_block.njk" import code_block %} +{% set code_panel = code_block(code) %} +{% set preview_panel %} +
+
+
+ {{ code | safe }} +
+
+
+{% endset %} + +
+ {% from "components/tabs.njk" import tabs %} + {% set tabsets = [ + { tab: "Preview", panel: preview_panel }, + { tab: "Code", panel: code_panel } + ] %} + + {{ tabs( + id="code-block-{{ id }}", + tabsets=tabsets, + default_tab_index=(2 if default_code else 1) + ) }} +
+{% endmacro %} \ No newline at end of file diff --git a/docs/_includes/partials/dropdown-menu.njk b/docs/_includes/partials/dropdown-menu.njk deleted file mode 100644 index 8aedf36..0000000 --- a/docs/_includes/partials/dropdown-menu.njk +++ /dev/null @@ -1,150 +0,0 @@ - \ No newline at end of file diff --git a/docs/_includes/partials/accordion.njk b/docs/_includes/partials/kitchen-sink/accordion.njk similarity index 100% rename from docs/_includes/partials/accordion.njk rename to docs/_includes/partials/kitchen-sink/accordion.njk diff --git a/docs/_includes/partials/alert-dialog.njk b/docs/_includes/partials/kitchen-sink/alert-dialog.njk similarity index 94% rename from docs/_includes/partials/alert-dialog.njk rename to docs/_includes/partials/kitchen-sink/alert-dialog.njk index 5bf5139..2d3295d 100644 --- a/docs/_includes/partials/alert-dialog.njk +++ b/docs/_includes/partials/kitchen-sink/alert-dialog.njk @@ -1,3 +1,5 @@ +{% from "components/dialog.njk" import dialog %} +

Alert Dialog

diff --git a/docs/_includes/partials/alert.njk b/docs/_includes/partials/kitchen-sink/alert.njk similarity index 91% rename from docs/_includes/partials/alert.njk rename to docs/_includes/partials/kitchen-sink/alert.njk index 244ddcb..383891b 100644 --- a/docs/_includes/partials/alert.njk +++ b/docs/_includes/partials/kitchen-sink/alert.njk @@ -59,15 +59,6 @@
- {#
- {% lucide "circle-check" %} -

Something went wrong!

-
Your session has expired. Please log in again.
- -
#} -
{% lucide "circle-check" %}

Plot Twist: This Alert is Actually Amber!

diff --git a/docs/_includes/partials/avatar.njk b/docs/_includes/partials/kitchen-sink/avatar.njk similarity index 100% rename from docs/_includes/partials/avatar.njk rename to docs/_includes/partials/kitchen-sink/avatar.njk diff --git a/docs/_includes/partials/badge.njk b/docs/_includes/partials/kitchen-sink/badge.njk similarity index 100% rename from docs/_includes/partials/badge.njk rename to docs/_includes/partials/kitchen-sink/badge.njk diff --git a/docs/_includes/partials/breadcrumb.njk b/docs/_includes/partials/kitchen-sink/breadcrumb.njk similarity index 96% rename from docs/_includes/partials/breadcrumb.njk rename to docs/_includes/partials/kitchen-sink/breadcrumb.njk index 1feadcb..3b67035 100644 --- a/docs/_includes/partials/breadcrumb.njk +++ b/docs/_includes/partials/kitchen-sink/breadcrumb.njk @@ -1,3 +1,5 @@ +{% from "components/popover.njk" import popover %} +