From 7edd7033fbd2a07f40dcd5907df6e29e328d8d4c Mon Sep 17 00:00:00 2001 From: "moxey.eth" Date: Mon, 16 Oct 2023 12:06:55 +1100 Subject: [PATCH] wip: tailwind -> vanilla css, markdown element progress --- .vscode/settings.json | 3 + bun.lockb | Bin 206439 -> 202495 bytes playground/dev/components/Example.tsx | 3 + playground/dev/pages/hello.md | 7 - playground/dev/pages/index.mdx | 213 ++++++++++++++ playground/dev/pages/index.tsx | 12 - playground/dev/pages/{foo.tsx => jsx.tsx} | 0 src/app/index.server.tsx | 6 + src/app/routes.tsx | 9 +- src/app/types.ts | 3 +- src/index.css | 3 - src/index.html | 2 +- src/package.json | 6 +- src/server.ts | 8 +- src/styles/elements.css | 217 ++++++++++++++ src/styles/global.css | 7 + src/styles/index.css | 4 + src/styles/reset.css | 344 ++++++++++++++++++++++ src/styles/vars.css | 33 +++ src/vite.config.ts | 15 +- 20 files changed, 859 insertions(+), 36 deletions(-) create mode 100644 playground/dev/components/Example.tsx delete mode 100644 playground/dev/pages/hello.md create mode 100644 playground/dev/pages/index.mdx delete mode 100644 playground/dev/pages/index.tsx rename playground/dev/pages/{foo.tsx => jsx.tsx} (100%) delete mode 100644 src/index.css create mode 100644 src/styles/elements.css create mode 100644 src/styles/global.css create mode 100644 src/styles/index.css create mode 100644 src/styles/reset.css create mode 100644 src/styles/vars.css diff --git a/.vscode/settings.json b/.vscode/settings.json index ecffd000..e71c73b2 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -20,5 +20,8 @@ }, "[typescriptreact]": { "editor.defaultFormatter": "biomejs.biome" + }, + "[css]": { + "editor.defaultFormatter": "vscode.css-language-features" } } diff --git a/bun.lockb b/bun.lockb index 75f00fe776f72725d8de663296871a1d7b89ad4a..bb072be74c57aa11e7b296dc1e9475b7b5a4748e 100755 GIT binary patch delta 46284 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 R_4ANcRpaX@@hy^F{tL#hY&HM@ diff --git a/playground/dev/components/Example.tsx b/playground/dev/components/Example.tsx new file mode 100644 index 00000000..77f1be1d --- /dev/null +++ b/playground/dev/components/Example.tsx @@ -0,0 +1,3 @@ +export function Example() { + return

+} diff --git a/playground/dev/pages/hello.md b/playground/dev/pages/hello.md deleted file mode 100644 index 36002268..00000000 --- a/playground/dev/pages/hello.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Hi, World! ---- - -# Welcome - -Hello world \ No newline at end of file diff --git a/playground/dev/pages/index.mdx b/playground/dev/pages/index.mdx new file mode 100644 index 00000000..c1c34616 --- /dev/null +++ b/playground/dev/pages/index.mdx @@ -0,0 +1,213 @@ +--- +title: Vocs +--- + +import { Example } from '../components/Example' + +# Heading 1 + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce vestibulum ante non neque convallis tempor. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nam a iaculis libero. Suspendisse bibendum placerat enim, vitae iaculis sapien tincidunt vel. Nunc nunc dui, varius eget diam vitae, sagittis rutrum ante. Vestibulum ut nulla in ante tincidunt lacinia. Suspendisse ex orci, elementum vitae enim sed, pellentesque fermentum tortor. In bibendum sapien at nisi pharetra tincidunt. Etiam eleifend lacus dictum lorem ornare euismod. Nunc ullamcorper nunc mi, ut volutpat libero gravida id. Pellentesque cursus mi id tortor convallis eleifend. + +## Heading 2 + +### Heading 3 + +#### Heading 4 + +##### Heading 5 + +###### Heading 6 + +## Heading 2 + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce vestibulum ante non neque convallis tempor. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nam a iaculis libero. Suspendisse bibendum placerat enim, vitae iaculis sapien tincidunt vel. Nunc nunc dui, varius eget diam vitae, sagittis rutrum ante. Vestibulum ut nulla in ante tincidunt lacinia. Suspendisse ex orci, elementum vitae enim sed, pellentesque fermentum tortor. In bibendum sapien at nisi pharetra tincidunt. Etiam eleifend lacus dictum lorem ornare euismod. Nunc ullamcorper nunc mi, ut volutpat libero gravida id. Pellentesque cursus mi id tortor convallis eleifend. + +### Heading 3 + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce vestibulum ante non neque convallis tempor. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nam a iaculis libero. Suspendisse bibendum placerat enim, vitae iaculis sapien tincidunt vel. Nunc nunc dui, varius eget diam vitae, sagittis rutrum ante. Vestibulum ut nulla in ante tincidunt lacinia. Suspendisse ex orci, elementum vitae enim sed, pellentesque fermentum tortor. In bibendum sapien at nisi pharetra tincidunt. Etiam eleifend lacus dictum lorem ornare euismod. Nunc ullamcorper nunc mi, ut volutpat libero gravida id. Pellentesque cursus mi id tortor convallis eleifend. + +#### Heading 4 + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce vestibulum ante non neque convallis tempor. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nam a iaculis libero. Suspendisse bibendum placerat enim, vitae iaculis sapien tincidunt vel. Nunc nunc dui, varius eget diam vitae, sagittis rutrum ante. Vestibulum ut nulla in ante tincidunt lacinia. Suspendisse ex orci, elementum vitae enim sed, pellentesque fermentum tortor. In bibendum sapien at nisi pharetra tincidunt. Etiam eleifend lacus dictum lorem ornare euismod. Nunc ullamcorper nunc mi, ut volutpat libero gravida id. Pellentesque cursus mi id tortor convallis eleifend. + +##### Heading 5 + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce vestibulum ante non neque convallis tempor. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nam a iaculis libero. Suspendisse bibendum placerat enim, vitae iaculis sapien tincidunt vel. Nunc nunc dui, varius eget diam vitae, sagittis rutrum ante. Vestibulum ut nulla in ante tincidunt lacinia. Suspendisse ex orci, elementum vitae enim sed, pellentesque fermentum tortor. In bibendum sapien at nisi pharetra tincidunt. Etiam eleifend lacus dictum lorem ornare euismod. Nunc ullamcorper nunc mi, ut volutpat libero gravida id. Pellentesque cursus mi id tortor convallis eleifend. + +###### Heading 6 + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce vestibulum ante non neque convallis tempor. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nam a iaculis libero. Suspendisse bibendum placerat enim, vitae iaculis sapien tincidunt vel. Nunc nunc dui, varius eget diam vitae, sagittis rutrum ante. Vestibulum ut nulla in ante tincidunt lacinia. Suspendisse ex orci, elementum vitae enim sed, pellentesque fermentum tortor. In bibendum sapien at nisi pharetra tincidunt. Etiam eleifend lacus dictum lorem ornare euismod. Nunc ullamcorper nunc mi, ut volutpat libero gravida id. Pellentesque cursus mi id tortor convallis eleifend. + +**Strong Title** + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce vestibulum ante non neque convallis tempor. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nam a iaculis libero. Suspendisse bibendum placerat enim, vitae iaculis sapien tincidunt vel. Nunc nunc dui, varius eget diam vitae, sagittis rutrum ante. Vestibulum ut nulla in ante tincidunt lacinia. Suspendisse ex orci, elementum vitae enim sed, pellentesque fermentum tortor. In bibendum sapien at nisi pharetra tincidunt. Etiam eleifend lacus dictum lorem ornare euismod. Nunc ullamcorper nunc mi, ut volutpat libero gravida id. Pellentesque cursus mi id tortor convallis eleifend. + +## Paragraphs + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce vestibulum ante non neque convallis tempor. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nam a iaculis libero. Suspendisse bibendum placerat enim, vitae iaculis sapien tincidunt vel. Nunc nunc dui, varius eget diam vitae, sagittis rutrum ante. Vestibulum ut nulla in ante tincidunt lacinia. Suspendisse ex orci, elementum vitae enim sed, pellentesque fermentum tortor. In bibendum sapien at nisi pharetra tincidunt. Etiam eleifend lacus dictum lorem ornare euismod. Nunc ullamcorper nunc mi, ut volutpat libero gravida id. Pellentesque cursus mi id tortor convallis eleifend. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce vestibulum ante non neque convallis tempor. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nam a iaculis libero. Suspendisse bibendum placerat enim, vitae iaculis sapien tincidunt vel. Nunc nunc dui, varius eget diam vitae, sagittis rutrum ante. Vestibulum ut nulla in ante tincidunt lacinia. Suspendisse ex orci, elementum vitae enim sed, pellentesque fermentum tortor. In bibendum sapien at nisi pharetra tincidunt. Etiam eleifend lacus dictum lorem ornare euismod. Nunc ullamcorper nunc mi, ut volutpat libero gravida id. Pellentesque cursus mi id tortor convallis eleifend. + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce vestibulum ante non neque convallis tempor. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nam a iaculis libero. Suspendisse bibendum placerat enim, vitae iaculis sapien tincidunt vel. Nunc nunc dui, varius eget diam vitae, sagittis rutrum ante. Vestibulum ut nulla in ante tincidunt lacinia. Suspendisse ex orci, elementum vitae enim sed, pellentesque fermentum tortor. In bibendum sapien at nisi pharetra tincidunt. Etiam eleifend lacus dictum lorem ornare euismod. Nunc ullamcorper nunc mi, ut volutpat libero gravida id. Pellentesque cursus mi id tortor convallis eleifend. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce vestibulum ante non neque convallis tempor. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nam a iaculis libero. Suspendisse bibendum placerat enim, vitae iaculis sapien tincidunt vel. Nunc nunc dui, varius eget diam vitae, sagittis rutrum ante. Vestibulum ut nulla in ante tincidunt lacinia. Suspendisse ex orci, elementum vitae enim sed, pellentesque fermentum tortor. In bibendum sapien at nisi pharetra tincidunt. Etiam eleifend lacus dictum lorem ornare euismod. Nunc ullamcorper nunc mi, ut volutpat libero gravida id. Pellentesque cursus mi id tortor convallis eleifend. + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce vestibulum ante non neque convallis tempor. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nam a iaculis libero. Suspendisse bibendum placerat enim, vitae iaculis sapien tincidunt vel. Nunc nunc dui, varius eget diam vitae, sagittis rutrum ante. Vestibulum ut nulla in ante tincidunt lacinia. Suspendisse ex orci, elementum vitae enim sed, pellentesque fermentum tortor. In bibendum sapien at nisi pharetra tincidunt. Etiam eleifend lacus dictum lorem ornare euismod. Nunc ullamcorper nunc mi, ut volutpat libero gravida id. Pellentesque cursus mi id tortor convallis eleifend. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce vestibulum ante non neque convallis tempor. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nam a iaculis libero. Suspendisse bibendum placerat enim, vitae iaculis sapien tincidunt vel. Nunc nunc dui, varius eget diam vitae, sagittis rutrum ante. Vestibulum ut nulla in ante tincidunt lacinia. Suspendisse ex orci, elementum vitae enim sed, pellentesque fermentum tortor. In bibendum sapien at nisi pharetra tincidunt. Etiam eleifend lacus dictum lorem ornare euismod. Nunc ullamcorper nunc mi, ut volutpat libero gravida id. Pellentesque cursus mi id tortor convallis eleifend. + +## Emphasis + +Emphasis, aka italics, with *asterisks* or _underscores_. + +Strong emphasis, aka bold, with **asterisks** or __underscores__. + +Combined emphasis with **asterisks and _underscores_**. + +Strikethrough uses two tildes. ~~Scratch this.~~ + +## Lists + +### Ordered list + +1. First ordered list item +2. Another item + - Unordered sub-list. + - Unordered sub-list. + - Unordered sub-list. +3. Actual numbers don't matter, just that it's a number + 1. Ordered sub-list + 2. Ordered sub-list + 3. Ordered sub-list +4. And another item. + +### Unordered list + +* First item +* Second item +* Third item + +## Links + +www.example.com, https://example.com, and contact@example.com. + +[I'm an inline-style link](https://www.google.com) + +[I'm an inline-style link with title](https://www.google.com "Google's Homepage") + +[I'm a reference-style link][Arbitrary case-insensitive reference text] + +[I'm a relative reference to a repository file](../blob/master/LICENSE) + +[You can use numbers for reference-style link definitions][1] + +Or leave it empty and use the [link text itself]. + +Some text to show that the reference links can follow later. + +[arbitrary case-insensitive reference text]: https://www.mozilla.org +[1]: http://slashdot.org +[link text itself]: http://www.reddit.com + +## Images + +Inline-style: +![alt text](https://github.com/adam-p/markdown-here/raw/master/src/common/images/icon48.png "Logo Title Text 1") + +Reference-style: +![alt text][logo] + +[logo]: https://github.com/adam-p/markdown-here/raw/master/src/common/images/icon48.png "Logo Title Text 2" + +## Code and Syntax Highlighting + +Inline `code` has `back-ticks around` it. + +```ts {1} +type Example = string +const example: Example = 'example' +``` + +```js +const s = "JavaScript syntax highlighting"; +console.log(s); +``` + +```python +s = "Python syntax highlighting" +print s +``` + +``` +No language indicated, so no syntax highlighting. +But let's throw in a tag. +``` + +## Blockquote + +> Blockquotes are very handy in email to emulate reply text. +> This line is part of the same quote. + +> This is a very long line that will still be quoted properly when it wraps. Oh boy let's keep writing to make sure this is long enough to actually wrap for everyone. Oh, you can *put* **Markdown** into a blockquote. + +## Tables + +Colons can be used to align columns. + +| Tables | Are | Cool | +| ------------- |:-------------:| -----:| +| col 3 is | right-aligned | $1600 | +| col 2 is | centered | $12 | +| zebra stripes | are neat | $1 | + +There must be at least 3 dashes separating each header cell. +The outer pipes (|) are optional, and you don't need to make the +raw Markdown line up prettily. You can also use inline Markdown. + +Markdown | Less | Pretty +--- | --- | --- +*Still* | `renders` | **nicely** +1 | 2 | 3 + +## Footnotes + +Here is a simple footnote[^1]. + +A footnote can also have multiple lines[^2]. + +You can also use words, to fit your writing style more closely[^note]. + +[^1]: My reference. +[^2]: Every new line should be prefixed with 2 spaces. + This allows you to have a footnote with multiple lines. +[^note]: + Named footnotes will still render with numbers instead of the text but allow easier identification and linking. + This footnote also has been made with a different syntax using 4 spaces for new lines. + +## Inline HTML + +
+
Definition list
+
Is something people use sometimes.
+
Markdown in HTML
+
Does *not* work **very** well. Use HTML tags.
+
+ +## Inline React + + + +## Horizontal Rule + +Three or more... + +--- + +Hyphens + +*** + +Asterisks + +___ + +Underscores + +## Tasklist + +* [ ] to do +* [x] done \ No newline at end of file diff --git a/playground/dev/pages/index.tsx b/playground/dev/pages/index.tsx deleted file mode 100644 index b3db98a8..00000000 --- a/playground/dev/pages/index.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import { Link } from 'react-router-dom' - -export const head = Index - -export default function Index() { - return ( -
-

Hello World!

- Foo -
- ) -} diff --git a/playground/dev/pages/foo.tsx b/playground/dev/pages/jsx.tsx similarity index 100% rename from playground/dev/pages/foo.tsx rename to playground/dev/pages/jsx.tsx diff --git a/src/app/index.server.tsx b/src/app/index.server.tsx index 444525ab..9a6e140a 100644 --- a/src/app/index.server.tsx +++ b/src/app/index.server.tsx @@ -23,13 +23,19 @@ export async function render(req: Request) { const body = ReactDOMServer.renderToString( , ) + const helmet = Helmet.renderStatic() + + const themeKey = 'vocs.theme' + const themeScript = `` + const head = ` ${helmet.title.toString()} ${helmet.meta.toString()} ${helmet.link.toString()} ${helmet.style.toString()} ${helmet.script.toString()} + ${themeScript} ` return { head, body } diff --git a/src/app/routes.tsx b/src/app/routes.tsx index cf5f3bda..a6e7ef88 100644 --- a/src/app/routes.tsx +++ b/src/app/routes.tsx @@ -1,9 +1,12 @@ -import type { RouteObject } from 'react-router-dom' +import type { MDXComponents } from 'mdx/types.js' import { Helmet } from 'react-helmet' +import type { RouteObject } from 'react-router-dom' import { pages } from 'virtual:pages' import { FrontmatterHead } from './components/FrontmatterHead.js' +const components: MDXComponents = {} + export const routes = pages.map((page) => ({ path: page.path, lazy: async () => { @@ -14,7 +17,9 @@ export const routes = pages.map((page) => ({ <> {head && {head}} {frontmatter && } - +
+ +
), } satisfies RouteObject diff --git a/src/app/types.ts b/src/app/types.ts index c2b6daa1..b05ef37e 100644 --- a/src/app/types.ts +++ b/src/app/types.ts @@ -1,3 +1,4 @@ +import type { MDXComponents } from 'mdx/types.js' import * as React from 'react' export type Frontmatter = { @@ -6,7 +7,7 @@ export type Frontmatter = { } export type Module = { - default: React.ComponentType + default: React.ComponentType<{ components: MDXComponents }> frontmatter?: Frontmatter head?: React.ReactNode } diff --git a/src/index.css b/src/index.css deleted file mode 100644 index bd6213e1..00000000 --- a/src/index.css +++ /dev/null @@ -1,3 +0,0 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; \ No newline at end of file diff --git a/src/index.html b/src/index.html index a4eb5d99..cb335b4e 100644 --- a/src/index.html +++ b/src/index.html @@ -3,7 +3,7 @@ - + diff --git a/src/package.json b/src/package.json index 2af400c6..620d0bfc 100644 --- a/src/package.json +++ b/src/package.json @@ -15,7 +15,9 @@ "react-dom": "^18.2.0" }, "dependencies": { + "@mdx-js/react": "^2.3.0", "@mdx-js/rollup": "^2.3.0", + "@radix-ui/colors": "^3.0.0", "@tinyhttp/app": "^2.2.0", "@vitejs/plugin-react": "4.1.0", "autoprefixer": "^10.4.16", @@ -26,10 +28,12 @@ "postcss": "^8.4.31", "react-helmet": "^6.1.0", "react-router-dom": "^6.16.0", + "rehype-pretty-code": "^0.10.1", "remark-frontmatter": "^5.0.0", + "remark-gfm": "^3.0.1", "remark-mdx-frontmatter": "^3.0.0", "serve-static": "^1.15.0", - "tailwindcss": "^3.3.3", + "shiki": "^0.14.5", "vite": "^4.4.11", "vite-plugin-pages": "^0.31.0" } diff --git a/src/server.ts b/src/server.ts index 0694b800..d3577b1c 100644 --- a/src/server.ts +++ b/src/server.ts @@ -47,7 +47,13 @@ export async function createServer(args: CreateServerParameters = {}) { }), ) - // HTML + // Static files + // @ts-expect-error + server.use(serveStatic.default(resolve(__dirname, 'public'))) + // @ts-expect-error + server.use(serveStatic.default(resolve(root, 'public'))) + + // React → HTML server.use('*', async (req, res) => { try { const url = req.originalUrl diff --git a/src/styles/elements.css b/src/styles/elements.css new file mode 100644 index 00000000..27fa1257 --- /dev/null +++ b/src/styles/elements.css @@ -0,0 +1,217 @@ +.vocs *:last-child { + margin-bottom: 0px; +} + +/************************************/ +/* Headings & Text */ +/************************************/ + +/** Markdown: "# (Text)" */ +.vocs h1 { + font-size: 32px; + font-weight: 500; + letter-spacing: -0.025em; + line-height: 28px; + margin-bottom: 24px; +} + +/** Markdown: "## (Text)" */ +.vocs h2 { + border-top: 1px solid var(--vocs-c-border); + font-size: 24px; + font-weight: 500; + letter-spacing: -0.02em; + line-height: 32px; + margin-top: 32px; + margin-bottom: 20px; + padding-top: 32px; +} + +/** Markdown: "### (Text)" */ +.vocs h3 { + letter-spacing: -0.01em; + line-height: 28px; + font-size: 20px; + font-weight: 500; + padding-top: 18px; + margin-bottom: 18px; + margin-top: 18px; +} + +.vocs h2+h3 { + padding-top: 12px; +} + +/** Markdown: "#### (Text)" */ +.vocs h4 { + line-height: 24px; + font-size: 18px; + font-weight: 500; + padding-top: 16px; + margin-bottom: 16px; + margin-top: 16px; +} + +/** Markdown: "##### (Text)" */ +.vocs h5 { + font-weight: 500; + line-height: 24px; + padding-top: 16px; + margin-bottom: 16px; + margin-top: 16px; +} + +/** Markdown: "####### (Text)" */ +.vocs h6 { + font-weight: 500; + padding-top: 16px; + margin-bottom: 16px; + margin-top: 16px; +} + +/** Markdown: "(Text)" */ +.vocs p { + line-height: 28px; + margin-bottom: 16px; +} + +/** Markdown: "**(Text)**" | "__(Text)__" */ +.vocs strong { + font-weight: 500; +} + +/** Sibling overrides **/ +.vocs h2+h3, +.vocs h3+h4, +.vocs h4+h5, +.vocs h5+h6 { + padding-top: 0px; +} + +/************************************/ +/* Link */ +/************************************/ + +.vocs a { + color: var(--vocs-c-accent); + font-weight: 400; + transition: color 0.25s; + + &:hover { + text-underline-offset: 2px; + text-decoration: underline; + } +} + +/************************************/ +/* Code */ +/************************************/ + +/* TODO */ + +.vocs [data-rehype-pretty-code-fragment] { + margin-bottom: 16px; +} + +.vocs pre { + margin-bottom: 16px; +} + +/************************************/ +/* Lists */ +/************************************/ + +/** Markdown: "* Text" */ +.vocs ul { + list-style: disc; + padding-left: 1.25rem; + margin-bottom: 16px; +} + +/** Markdown: "1. Text" */ +.vocs ol { + list-style: decimal; + padding-left: 1.25rem; + margin-bottom: 16px; +} + +/** Sibling overrides **/ +.vocs li+li { + padding-top: 12px; +} + +/** Direct descendant overrides **/ +.vocs li>ol, +.vocs li>ul { + padding-top: 12px; +} + +/** Descendant overrides **/ +.vocs ol ul, +.vocs ul ul, +.vocs ul ol, +.vocs ol ol { + padding-bottom: 0px; +} + +/************************************/ +/* Blockquote */ +/************************************/ + +/** Markdown: "> (Text)" */ +.vocs blockquote { + border-left: 2px solid var(--vocs-c-border); + padding-left: 16px; + margin-bottom: 16px; +} + +.vocs blockquote>p { + color: var(--vocs-c-text-tertiary); +} + +/************************************/ +/* Table */ +/************************************/ + +/** Markdown: "| (Text) | (Text) |" */ +.vocs table { + display: block; + border-collapse: collapse; + overflow-x: auto; + margin-bottom: 24px; +} + +.vocs tr { + border-top: 1px solid var(--vocs-c-border); +} + +.vocs tr:nth-child(2n) { + background-color: var(--vocs-c-background-surface); +} + +.vocs td { + border: 1px solid var(--vocs-c-border); + padding: 12px 16px; +} + +.vocs th { + border: 1px solid var(--vocs-c-border); + background-color: var(--vocs-c-background-surface); + color: var(--vocs-c-text-tertiary); + font-size: 14px; + font-weight: 400; + padding: 12px 16px; + text-align: left; +} + +.vocs th[align="center"] { + text-align: center; +} + +.vocs th[align="right"] { + text-align: right; +} + +.vocs td { + font-size: 14px; +} \ No newline at end of file diff --git a/src/styles/global.css b/src/styles/global.css new file mode 100644 index 00000000..75d3d472 --- /dev/null +++ b/src/styles/global.css @@ -0,0 +1,7 @@ +@import url('https://fonts.googleapis.com/css2?family=Inter:wght@100;200;300;400;500;600;700;800;900&display=swap'); + +:root { + background-color: var(--vocs-c-background); + color: var(--vocs-c-text); + font-weight: 300; +} \ No newline at end of file diff --git a/src/styles/index.css b/src/styles/index.css new file mode 100644 index 00000000..175ce52e --- /dev/null +++ b/src/styles/index.css @@ -0,0 +1,4 @@ +@import "./vars.css"; +@import "./reset.css"; +@import "./global.css"; +@import "./elements.css"; \ No newline at end of file diff --git a/src/styles/reset.css b/src/styles/reset.css new file mode 100644 index 00000000..cba8e1e9 --- /dev/null +++ b/src/styles/reset.css @@ -0,0 +1,344 @@ +*, +::before, +::after { + box-sizing: border-box; + border-width: 0; + border-style: solid; +} + +html, body { + line-height: 1.5; + -webkit-text-size-adjust: 100%; + tab-size: 4; + font-family: var(--vocs-fontFamily); + font-feature-settings: "rlig" 1, "calt" 1; + font-size: 16px; + line-height: inherit; + margin: 0; + padding: 0; + border: 0; +} + +hr { + height: 0; + color: inherit; + border-top-width: 1px; +} + +/* +Add the correct text decoration in Chrome, Edge, and Safari. +*/ + +abbr:where([title]) { + text-decoration: underline dotted; +} + +/* +Remove the default font size and weight for headings. +*/ + +h1, +h2, +h3, +h4, +h5, +h6 { + font-size: inherit; + font-weight: inherit; +} + +/* +Reset links to optimize for opt-in styling instead of opt-out. +*/ + +a { + color: inherit; + text-decoration: inherit; +} + +/* +Add the correct font weight in Edge and Safari. +*/ + +b, +strong { + font-weight: bolder; +} + +/* +1. Use the user's configured `mono` font family by default. +2. Correct the odd `em` font sizing in all browsers. +*/ + +code, +kbd, +samp, +pre { + font-family: var(--vocs-fontFamily-mono); /* 1 */ + font-size: 1em; /* 2 */ +} + +/* +Add the correct font size in all browsers. +*/ + +small { + font-size: 80%; +} + +/* +Prevent `sub` and `sup` elements from affecting the line height in all browsers. +*/ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sub { + bottom: -0.25em; +} + +sup { + top: -0.5em; +} + +/* +1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297) +2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016) +3. Remove gaps between table borders by default. +*/ + +table { + text-indent: 0; /* 1 */ + border-color: inherit; /* 2 */ + border-collapse: collapse; /* 3 */ +} + +/* +1. Change the font styles in all browsers. +2. Remove the margin in Firefox and Safari. +3. Remove default padding in all browsers. +*/ + +button, +input, +optgroup, +select, +textarea { + font-family: inherit; /* 1 */ + font-feature-settings: inherit; /* 1 */ + font-variation-settings: inherit; /* 1 */ + font-size: 100%; /* 1 */ + font-weight: inherit; /* 1 */ + line-height: inherit; /* 1 */ + color: inherit; /* 1 */ + margin: 0; /* 2 */ + padding: 0; /* 3 */ +} + +/* +Remove the inheritance of text transform in Edge and Firefox. +*/ + +button, +select { + text-transform: none; +} + +/* +1. Correct the inability to style clickable types in iOS and Safari. +2. Remove default button styles. +*/ + +button, +[type='button'], +[type='reset'], +[type='submit'] { + -webkit-appearance: button; /* 1 */ + background-color: transparent; /* 2 */ + background-image: none; /* 2 */ +} + +/* +Use the modern Firefox focus style for all focusable elements. +*/ + +:-moz-focusring { + outline: auto; +} + +/* +Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737) +*/ + +:-moz-ui-invalid { + box-shadow: none; +} + +/* +Add the correct vertical alignment in Chrome and Firefox. +*/ + +progress { + vertical-align: baseline; +} + +/* +Correct the cursor style of increment and decrement buttons in Safari. +*/ + +::-webkit-inner-spin-button, +::-webkit-outer-spin-button { + height: auto; +} + +/* +1. Correct the odd appearance in Chrome and Safari. +2. Correct the outline style in Safari. +*/ + +[type='search'] { + -webkit-appearance: textfield; /* 1 */ + outline-offset: -2px; /* 2 */ +} + +/* +Remove the inner padding in Chrome and Safari on macOS. +*/ + +::-webkit-search-decoration { + -webkit-appearance: none; +} + +/* +1. Correct the inability to style clickable types in iOS and Safari. +2. Change font properties to `inherit` in Safari. +*/ + +::-webkit-file-upload-button { + -webkit-appearance: button; /* 1 */ + font: inherit; /* 2 */ +} + +/* +Add the correct display in Chrome and Safari. +*/ + +summary { + display: list-item; +} + +/* +Removes the default spacing for appropriate elements. +*/ + +blockquote, +dl, +dd, +h1, +h2, +h3, +h4, +h5, +h6, +hr, +figure, +p, +pre { + margin: 0; +} + +fieldset { + margin: 0; + padding: 0; +} + +legend { + padding: 0; +} + +ol, +ul, +menu { + list-style: none; + margin: 0; + padding: 0; +} + +dialog { + padding: 0; +} + +/* +Prevent resizing textareas horizontally by default. +*/ + +textarea { + resize: vertical; +} + +/* +1. Reset the default placeholder opacity in Firefox. +*/ + +input::placeholder, +textarea::placeholder { + opacity: 1; /* 1 */ +} + +/* +Set the default cursor for buttons. +*/ + +button, +[role="button"] { + cursor: pointer; +} + +/* +Make sure disabled buttons don't get the pointer cursor. +*/ + +:disabled { + cursor: default; +} + +/* +1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14) +2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210) + This can trigger a poorly considered lint error in some tools but is included by design. +*/ + +img, +svg, +video, +canvas, +audio, +iframe, +embed, +object { + display: block; /* 1 */ + vertical-align: middle; /* 2 */ +} + +/* +Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14) +*/ + +img, +video { + max-width: 100%; + height: auto; +} + +/* +Make elements with the HTML hidden attribute stay hidden by default. +*/ + +[hidden] { + display: none; +} \ No newline at end of file diff --git a/src/styles/vars.css b/src/styles/vars.css new file mode 100644 index 00000000..fc326525 --- /dev/null +++ b/src/styles/vars.css @@ -0,0 +1,33 @@ +@import "@radix-ui/colors/iris.css"; +@import "@radix-ui/colors/iris-dark.css"; +@import "@radix-ui/colors/mauve.css"; +@import "@radix-ui/colors/mauve-dark.css"; +@import "@radix-ui/colors/gray.css"; +@import "@radix-ui/colors/gray-dark.css"; +@import "@radix-ui/colors/black-alpha.css"; + +/* Color */ +:root { + --vocs-c-accent: var(--iris-11); + --vocs-c-background: white; + --vocs-c-background-surface: var(--gray-2); + --vocs-c-border: var(--black-a2); + --vocs-c-text: var(--gray-12); + --vocs-c-text-secondary: var(--gray-11); + --vocs-c-text-tertiary: var(--gray-10); + + &.dark { + --vocs-c-background: var(--mauve-3); + --vocs-c-background-surface: var(--mauve-4); + --vocs-c-border: var(--mauve-6); + --vocs-c-text: rgba(255, 255, 255, 0.9); + --vocs-c-text-secondary: rgba(255, 255, 255, 0.75); + --vocs-c-text-tertiary: rgba(255, 255, 255, 0.6); + } +} + +/* Fonts */ +:root { + --vocs-fontFamily: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; + --vocs-fontFamily-mono: monospace; +} \ No newline at end of file diff --git a/src/vite.config.ts b/src/vite.config.ts index 5a961648..6aae2095 100644 --- a/src/vite.config.ts +++ b/src/vite.config.ts @@ -3,25 +3,24 @@ import mdx from '@mdx-js/rollup' import react from '@vitejs/plugin-react' import * as autoprefixer from 'autoprefixer' import { globby } from 'globby' +import rehypePrettyCode from 'rehype-pretty-code' import remarkFrontmatter from 'remark-frontmatter' +import remarkGfm from 'remark-gfm' import remarkMdxFrontmatter from 'remark-mdx-frontmatter' -import * as tailwindcss from 'tailwindcss' import { type PluginOption, defineConfig } from 'vite' export default defineConfig({ css: { postcss: { - plugins: [ - (autoprefixer as any).default(), - tailwindcss.default({ - content: [resolve(process.cwd(), './**/*.{html,tsx,ts,js,jsx}')], - }), - ], + plugins: [(autoprefixer as any).default()], }, }, plugins: [ react(), - mdx({ remarkPlugins: [remarkFrontmatter, remarkMdxFrontmatter] }), + mdx({ + remarkPlugins: [remarkFrontmatter, remarkMdxFrontmatter, remarkGfm], + rehypePlugins: [rehypePrettyCode as any], + }), pages({ paths: resolve(process.cwd(), './pages/**/*.{md,mdx,ts,tsx,js,jsx}') }), ], })