diff --git a/apps/main-app/package.json b/apps/main-app/package.json index b5609f4..e1e69ea 100644 --- a/apps/main-app/package.json +++ b/apps/main-app/package.json @@ -32,6 +32,7 @@ "@radix-ui/react-tabs": "^1.1.13", "@tanstack/react-query": "^5.90.2", "@wisp/atproto-utils": "workspace:*", + "@wisp/css": "workspace:*", "@wisp/constants": "workspace:*", "@wisp/database": "workspace:*", "@wisp/fs-utils": "workspace:*", diff --git a/apps/main-app/public/editor/acceptable-use.html b/apps/main-app/public/editor/acceptable-use.html index 51e4d35..11d2a65 100644 --- a/apps/main-app/public/editor/acceptable-use.html +++ b/apps/main-app/public/editor/acceptable-use.html @@ -8,94 +8,8 @@ +
diff --git a/apps/main-app/public/landingpage.html b/apps/main-app/public/landingpage.html index 558d628..f7b6e59 100644 --- a/apps/main-app/public/landingpage.html +++ b/apps/main-app/public/landingpage.html @@ -31,122 +31,9 @@ + diff --git a/apps/main-app/src/index.ts b/apps/main-app/src/index.ts index 1638426..588db95 100644 --- a/apps/main-app/src/index.ts +++ b/apps/main-app/src/index.ts @@ -25,6 +25,7 @@ import { csrfProtection } from './lib/csrf' import { DNSVerificationWorker } from './lib/dns-verification-worker' import { createLogger, logCollector, initializeGrafanaExporters } from '@wisp/observability' import { observabilityMiddleware } from '@wisp/observability/middleware/elysia' +import { css as wispCss } from '@wisp/css' import { promptAdminSetup } from './lib/admin-auth' import { adminRoutes } from './routes/admin' @@ -225,6 +226,11 @@ export const app = new Elysia({ }) : (app) => app ) + .get('/wisp.css', ({ set }) => { + set.headers['Content-Type'] = 'text/css; charset=utf-8' + set.headers['Cache-Control'] = 'public, max-age=86400' + return wispCss + }) .get('/acceptable-use', async ({ set }) => { set.headers['Content-Type'] = 'text/html; charset=utf-8' return await Bun.file('./apps/main-app/public/editor/acceptable-use.html').text() diff --git a/bun.lock b/bun.lock index 484e859..ace9223 100644 --- a/bun.lock +++ b/bun.lock @@ -71,6 +71,7 @@ "@tanstack/react-query": "^5.90.2", "@wisp/atproto-utils": "workspace:*", "@wisp/constants": "workspace:*", + "@wisp/css": "workspace:*", "@wisp/database": "workspace:*", "@wisp/fs-utils": "workspace:*", "@wisp/lexicons": "workspace:*", @@ -156,6 +157,10 @@ "name": "@wisp/constants", "version": "1.0.0", }, + "packages/@wisp/css": { + "name": "@wisp/css", + "version": "1.0.0", + }, "packages/@wisp/database": { "name": "@wisp/database", "version": "1.0.0", @@ -837,6 +842,8 @@ "@wisp/constants": ["@wisp/constants@workspace:packages/@wisp/constants"], + "@wisp/css": ["@wisp/css@workspace:packages/@wisp/css"], + "@wisp/database": ["@wisp/database@workspace:packages/@wisp/database"], "@wisp/fs-utils": ["@wisp/fs-utils@workspace:packages/@wisp/fs-utils"], @@ -889,7 +896,7 @@ "bun-plugin-tailwind": ["bun-plugin-tailwind@0.1.2", "", { "peerDependencies": { "bun": ">=1.0.0" } }, "sha512-41jNC1tZRSK3s1o7pTNrLuQG8kL/0vR/JgiTmZAJ1eHwe0w5j6HFPKeqEk0WAD13jfrUC7+ULuewFBBCoADPpg=="], - "bun-types": ["bun-types@1.3.7", "", { "dependencies": { "@types/node": "*" } }, "sha512-qyschsA03Qz+gou+apt6HNl6HnI+sJJLL4wLDke4iugsE6584CMupOtTY1n+2YC9nGVrEKUlTs99jjRLKgWnjQ=="], + "bun-types": ["bun-types@1.3.8", "", { "dependencies": { "@types/node": "*" } }, "sha512-fL99nxdOWvV4LqjmC+8Q9kW3M4QTtTR1eePs94v5ctGqU8OeceWrSUaRw3JYb7tU3FkMIAjkueehrHPPPGKi5Q=="], "bundle-name": ["bundle-name@4.1.0", "", { "dependencies": { "run-applescript": "^7.0.0" } }, "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q=="], diff --git a/packages/@wisp/css/README.md b/packages/@wisp/css/README.md new file mode 100644 index 0000000..b188ca7 --- /dev/null +++ b/packages/@wisp/css/README.md @@ -0,0 +1,143 @@ +# wisp.css + +A minimal, monospace-first CSS stylesheet with automatic light/dark mode. See it live on https://wisp.place or https://sites.wisp.place/wisp.place/wisp.css for a demo. + +## Quick Start + +### CDN +```html + +``` + +### Self-hosted + +Just copy `wisp.css` to your project and link to it: + +```html + +``` + +## Features + +- **Automatic dark mode** via `prefers-color-scheme` +- **CSS custom properties** for easy theming +- **JetBrains Mono** typography +- **Components**: cards, buttons, alerts, forms +- **Utility classes**: spacing, flexbox, text styling +- **Responsive** with mobile-first breakpoints + +## CSS Variables + +All variables use the `--wisp-` prefix. Unprefixed aliases are also available for convenience. + +### Colors + +```css +--wisp-bg /* Main background */ +--wisp-bg-alt /* Alternate background (cards, etc) */ +--wisp-text /* Primary text */ +--wisp-text-muted /* Secondary text */ +--wisp-text-subtle /* Tertiary text */ +--wisp-border /* Strong borders */ +--wisp-border-light /* Light borders */ +--wisp-accent /* Accent/link color */ +--wisp-cta-bg /* Button background */ +--wisp-cta-text /* Button text */ +--wisp-code-bg /* Code block background */ +--wisp-success /* Success state */ +--wisp-danger /* Error/danger state */ +--wisp-warning /* Warning state */ +--wisp-info /* Info state */ +``` + +### Customizing + +Override variables in your own CSS: + +```css +:root { + --wisp-accent: oklch(0.65 0.20 200); /* Blue accent */ +} +``` + +## Components + +### Cards + +```html +A minimal, monospace-first CSS stylesheet with automatic light/dark mode.
+This is a paragraph with bold text and a link. The stylesheet uses JetBrains Mono for that clean monospace aesthetic.
+This is small text for captions or metadata.
+Here's some inline code in a sentence.
// Code block
+const greeting = "Hello, wisp.css!";
+console.log(greeting);
+ This is a basic card component with some content inside.
+Use this for positive feedback or confirmations.
+Use this for errors or destructive actions.
+Use this for warnings or important notices.
+Use this for informational messages.
+Use card-flex and card-icon for icon layouts.
text-muted - Secondary text
+text-subtle - Tertiary text
+text-accent - Accent color
+text-success - Success state
+text-danger - Danger state
+text-warning - Warning state
+text-left
+text-center
+text-right
+Colors automatically adapt to light/dark mode via CSS custom properties.
+ +
+
+
+
+
+
+
+
+