saasaloy 0.1.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.
- package/dist/index.js +8455 -0
- package/dist/index.js.map +1 -0
- package/package.json +69 -0
- package/schemas/manifest.schema.json +107 -0
- package/schemas/registry-item.schema.json +336 -0
- package/schemas/saasaloy-lock.schema.json +86 -0
- package/schemas/saasaloy.schema.json +42 -0
- package/templates/base/AGENTS.md +450 -0
- package/templates/base/CLAUDE.md +1 -0
- package/templates/base/DESIGN.md +209 -0
- package/templates/base/README.md +71 -0
- package/templates/base/_agents/skills/saasaloy-design/SKILL.md +198 -0
- package/templates/base/_agents/skills/saasaloy-landing-copy/SKILL.md +395 -0
- package/templates/base/_agents/skills/saasaloy-setup/SKILL.md +273 -0
- package/templates/base/_gitignore +32 -0
- package/templates/base/_husky/commit-msg +1 -0
- package/templates/base/_husky/pre-commit +1 -0
- package/templates/base/_prettierignore +31 -0
- package/templates/base/_saasaloy-base.json +9 -0
- package/templates/base/apps/web/astro.config.mjs +61 -0
- package/templates/base/apps/web/package.json +30 -0
- package/templates/base/apps/web/public/favicon.svg +4 -0
- package/templates/base/apps/web/src/layouts/Layout.astro +52 -0
- package/templates/base/apps/web/src/pages/404.astro +24 -0
- package/templates/base/apps/web/src/pages/500.astro +33 -0
- package/templates/base/apps/web/src/pages/index.astro +61 -0
- package/templates/base/apps/web/src/pages/privacy.astro +15 -0
- package/templates/base/apps/web/src/pages/terms.astro +14 -0
- package/templates/base/apps/web/tsconfig.json +11 -0
- package/templates/base/apps/web/wrangler.jsonc +27 -0
- package/templates/base/commitlint.config.js +9 -0
- package/templates/base/lint-staged.config.js +17 -0
- package/templates/base/oxlint.config.mjs +155 -0
- package/templates/base/package.json +44 -0
- package/templates/base/packages/tsconfig/base.json +17 -0
- package/templates/base/packages/tsconfig/package.json +18 -0
- package/templates/base/packages/ui/components.json +19 -0
- package/templates/base/packages/ui/package.json +39 -0
- package/templates/base/packages/ui/src/blocks/cta.tsx +82 -0
- package/templates/base/packages/ui/src/blocks/error-state.tsx +144 -0
- package/templates/base/packages/ui/src/blocks/faq.tsx +64 -0
- package/templates/base/packages/ui/src/blocks/feature-grid.tsx +185 -0
- package/templates/base/packages/ui/src/blocks/footer.tsx +99 -0
- package/templates/base/packages/ui/src/blocks/hero.tsx +84 -0
- package/templates/base/packages/ui/src/blocks/navbar.tsx +159 -0
- package/templates/base/packages/ui/src/blocks/pricing-table.tsx +175 -0
- package/templates/base/packages/ui/src/blocks/theme-toggle.tsx +51 -0
- package/templates/base/packages/ui/src/components/accordion.tsx +78 -0
- package/templates/base/packages/ui/src/components/badge.tsx +53 -0
- package/templates/base/packages/ui/src/components/button.tsx +59 -0
- package/templates/base/packages/ui/src/components/card.tsx +103 -0
- package/templates/base/packages/ui/src/components/input.tsx +20 -0
- package/templates/base/packages/ui/src/components/label.tsx +18 -0
- package/templates/base/packages/ui/src/components/separator.tsx +23 -0
- package/templates/base/packages/ui/src/containers/README.md +11 -0
- package/templates/base/packages/ui/src/content/errors.ts +58 -0
- package/templates/base/packages/ui/src/content/landing.ts +304 -0
- package/templates/base/packages/ui/src/index.ts +8 -0
- package/templates/base/packages/ui/src/lib/interpolate.ts +31 -0
- package/templates/base/packages/ui/src/lib/sentinel.ts +11 -0
- package/templates/base/packages/ui/src/lib/theme.ts +167 -0
- package/templates/base/packages/ui/src/lib/utils.ts +11 -0
- package/templates/base/packages/ui/src/styles/globals.css +164 -0
- package/templates/base/packages/ui/tsconfig.json +7 -0
- package/templates/base/pnpm-workspace.yaml +23 -0
- package/templates/base/prettier.config.js +10 -0
- package/templates/base/saasaloy.json +8 -0
- package/templates/base/stylelint.config.js +46 -0
- package/templates/base/turbo.json +20 -0
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/* The one theme for the whole monorepo. `@repo/ui` owns Tailwind's entrypoint, the
|
|
2
|
+
source globs, and the token set; apps import it via the `@repo/ui/globals.css`
|
|
3
|
+
subpath export (see apps/web/src/layouts/Layout.astro) rather than redeclaring it.
|
|
4
|
+
Tokens follow shadcn's `neutral` base color with `cssVariables: true`, so anything
|
|
5
|
+
added later with `pnpm --filter @repo/ui exec shadcn add <x>` themes correctly. */
|
|
6
|
+
@import "tailwindcss";
|
|
7
|
+
@import "tw-animate-css";
|
|
8
|
+
@import "shadcn/tailwind.css";
|
|
9
|
+
|
|
10
|
+
/* Tailwind's automatic class detection is rooted at the CURRENT WORKING DIRECTORY, and
|
|
11
|
+
`astro dev`/`astro build` run with cwd = apps/web. Without these globs every utility
|
|
12
|
+
class written inside packages/ui is silently dropped — no error, no warning, just
|
|
13
|
+
missing CSS. A non-matching @source glob is equally silent, so both paths matter. */
|
|
14
|
+
@source "../**/*.{ts,tsx}";
|
|
15
|
+
|
|
16
|
+
/* FOUR levels up, not three. From packages/ui/src/styles/ the path walks
|
|
17
|
+
styles → src → ui → packages → <root>, so `../../../apps/**` would resolve to
|
|
18
|
+
packages/apps/** — a directory that does not exist. shadcn's own astro-monorepo
|
|
19
|
+
template ships that off-by-one and gets away with it only because cwd-rooted
|
|
20
|
+
auto-detection happens to cover the app; that cover vanishes when Turborepo builds
|
|
21
|
+
from the repo root. Do not "correct" this back to three. */
|
|
22
|
+
@source "../../../../apps/**/*.{ts,tsx,astro}";
|
|
23
|
+
|
|
24
|
+
/* Tailwind's own scanner skips node_modules only by way of .gitignore, and its ignore
|
|
25
|
+
walker needs a real .git directory to honour one. Before `git init` — a fresh
|
|
26
|
+
`saasaloy init`, or CI checking out a tarball — every .ts/.md under node_modules gets
|
|
27
|
+
scanned and the built stylesheet balloons ~5x (173 kB vs 33 kB, measured) with
|
|
28
|
+
utilities no page uses. This exclusion makes the result independent of git state. */
|
|
29
|
+
@source not "../../../../**/node_modules";
|
|
30
|
+
|
|
31
|
+
/* Dark mode is the `.dark` class shadcn assumes. It is set pre-paint by the inline
|
|
32
|
+
THEME_INIT_SCRIPT (packages/ui/src/lib/theme.ts) that every host document emits —
|
|
33
|
+
from the visitor's stored choice, falling back to the OS preference. The chosen
|
|
34
|
+
state also lands on <html> as `data-theme`, which is what blocks/theme-toggle.tsx
|
|
35
|
+
keys its icons off; nothing here needs to know about it. */
|
|
36
|
+
@custom-variant dark (&:is(.dark *));
|
|
37
|
+
|
|
38
|
+
:root {
|
|
39
|
+
/* Tell the browser which palette the document is using, so native UI it renders for
|
|
40
|
+
us — scrollbars, form controls, the default canvas — follows the theme too. The
|
|
41
|
+
tokens below only cover what we paint ourselves. Paired with `.dark` rather than
|
|
42
|
+
`light dark` on :root, because the theme is class-driven, not media-driven: the
|
|
43
|
+
pre-paint script resolves the visitor's choice (or the OS preference behind it)
|
|
44
|
+
into a class, and re-resolves on the fly when the OS flips while the choice is
|
|
45
|
+
`system`. `light dark` here would let the OS override an explicit choice. */
|
|
46
|
+
color-scheme: light;
|
|
47
|
+
|
|
48
|
+
--radius: 0.625rem;
|
|
49
|
+
--background: oklch(1 0 0);
|
|
50
|
+
--foreground: oklch(0.145 0 0);
|
|
51
|
+
--card: oklch(1 0 0);
|
|
52
|
+
--card-foreground: oklch(0.145 0 0);
|
|
53
|
+
--popover: oklch(1 0 0);
|
|
54
|
+
--popover-foreground: oklch(0.145 0 0);
|
|
55
|
+
--primary: oklch(0.205 0 0);
|
|
56
|
+
--primary-foreground: oklch(0.985 0 0);
|
|
57
|
+
--secondary: oklch(0.97 0 0);
|
|
58
|
+
--secondary-foreground: oklch(0.205 0 0);
|
|
59
|
+
--muted: oklch(0.97 0 0);
|
|
60
|
+
--muted-foreground: oklch(0.556 0 0);
|
|
61
|
+
--accent: oklch(0.97 0 0);
|
|
62
|
+
--accent-foreground: oklch(0.205 0 0);
|
|
63
|
+
--destructive: oklch(0.577 0.245 27.325);
|
|
64
|
+
--border: oklch(0.922 0 0);
|
|
65
|
+
--input: oklch(0.922 0 0);
|
|
66
|
+
--ring: oklch(0.708 0 0);
|
|
67
|
+
--chart-1: oklch(0.87 0 0);
|
|
68
|
+
--chart-2: oklch(0.556 0 0);
|
|
69
|
+
--chart-3: oklch(0.439 0 0);
|
|
70
|
+
--chart-4: oklch(0.371 0 0);
|
|
71
|
+
--chart-5: oklch(0.269 0 0);
|
|
72
|
+
--sidebar: oklch(0.985 0 0);
|
|
73
|
+
--sidebar-foreground: oklch(0.145 0 0);
|
|
74
|
+
--sidebar-primary: oklch(0.205 0 0);
|
|
75
|
+
--sidebar-primary-foreground: oklch(0.985 0 0);
|
|
76
|
+
--sidebar-accent: oklch(0.97 0 0);
|
|
77
|
+
--sidebar-accent-foreground: oklch(0.205 0 0);
|
|
78
|
+
--sidebar-border: oklch(0.922 0 0);
|
|
79
|
+
--sidebar-ring: oklch(0.708 0 0);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.dark {
|
|
83
|
+
color-scheme: dark;
|
|
84
|
+
|
|
85
|
+
--background: oklch(0.145 0 0);
|
|
86
|
+
--foreground: oklch(0.985 0 0);
|
|
87
|
+
--card: oklch(0.205 0 0);
|
|
88
|
+
--card-foreground: oklch(0.985 0 0);
|
|
89
|
+
--popover: oklch(0.205 0 0);
|
|
90
|
+
--popover-foreground: oklch(0.985 0 0);
|
|
91
|
+
--primary: oklch(0.922 0 0);
|
|
92
|
+
--primary-foreground: oklch(0.205 0 0);
|
|
93
|
+
--secondary: oklch(0.269 0 0);
|
|
94
|
+
--secondary-foreground: oklch(0.985 0 0);
|
|
95
|
+
--muted: oklch(0.269 0 0);
|
|
96
|
+
--muted-foreground: oklch(0.708 0 0);
|
|
97
|
+
--accent: oklch(0.269 0 0);
|
|
98
|
+
--accent-foreground: oklch(0.985 0 0);
|
|
99
|
+
--destructive: oklch(0.704 0.191 22.216);
|
|
100
|
+
--border: oklch(1 0 0 / 10%);
|
|
101
|
+
--input: oklch(1 0 0 / 15%);
|
|
102
|
+
--ring: oklch(0.556 0 0);
|
|
103
|
+
--chart-1: oklch(0.87 0 0);
|
|
104
|
+
--chart-2: oklch(0.556 0 0);
|
|
105
|
+
--chart-3: oklch(0.439 0 0);
|
|
106
|
+
--chart-4: oklch(0.371 0 0);
|
|
107
|
+
--chart-5: oklch(0.269 0 0);
|
|
108
|
+
--sidebar: oklch(0.205 0 0);
|
|
109
|
+
--sidebar-foreground: oklch(0.985 0 0);
|
|
110
|
+
--sidebar-primary: oklch(0.488 0.243 264.376);
|
|
111
|
+
--sidebar-primary-foreground: oklch(0.985 0 0);
|
|
112
|
+
--sidebar-accent: oklch(0.269 0 0);
|
|
113
|
+
--sidebar-accent-foreground: oklch(0.985 0 0);
|
|
114
|
+
--sidebar-border: oklch(1 0 0 / 10%);
|
|
115
|
+
--sidebar-ring: oklch(0.556 0 0);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
@theme inline {
|
|
119
|
+
--radius-sm: calc(var(--radius) - 4px);
|
|
120
|
+
--radius-md: calc(var(--radius) - 2px);
|
|
121
|
+
--radius-lg: var(--radius);
|
|
122
|
+
--radius-xl: calc(var(--radius) + 4px);
|
|
123
|
+
--color-background: var(--background);
|
|
124
|
+
--color-foreground: var(--foreground);
|
|
125
|
+
--color-card: var(--card);
|
|
126
|
+
--color-card-foreground: var(--card-foreground);
|
|
127
|
+
--color-popover: var(--popover);
|
|
128
|
+
--color-popover-foreground: var(--popover-foreground);
|
|
129
|
+
--color-primary: var(--primary);
|
|
130
|
+
--color-primary-foreground: var(--primary-foreground);
|
|
131
|
+
--color-secondary: var(--secondary);
|
|
132
|
+
--color-secondary-foreground: var(--secondary-foreground);
|
|
133
|
+
--color-muted: var(--muted);
|
|
134
|
+
--color-muted-foreground: var(--muted-foreground);
|
|
135
|
+
--color-accent: var(--accent);
|
|
136
|
+
--color-accent-foreground: var(--accent-foreground);
|
|
137
|
+
--color-destructive: var(--destructive);
|
|
138
|
+
--color-border: var(--border);
|
|
139
|
+
--color-input: var(--input);
|
|
140
|
+
--color-ring: var(--ring);
|
|
141
|
+
--color-chart-1: var(--chart-1);
|
|
142
|
+
--color-chart-2: var(--chart-2);
|
|
143
|
+
--color-chart-3: var(--chart-3);
|
|
144
|
+
--color-chart-4: var(--chart-4);
|
|
145
|
+
--color-chart-5: var(--chart-5);
|
|
146
|
+
--color-sidebar: var(--sidebar);
|
|
147
|
+
--color-sidebar-foreground: var(--sidebar-foreground);
|
|
148
|
+
--color-sidebar-primary: var(--sidebar-primary);
|
|
149
|
+
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
|
150
|
+
--color-sidebar-accent: var(--sidebar-accent);
|
|
151
|
+
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
|
152
|
+
--color-sidebar-border: var(--sidebar-border);
|
|
153
|
+
--color-sidebar-ring: var(--sidebar-ring);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
@layer base {
|
|
157
|
+
* {
|
|
158
|
+
@apply border-border outline-ring/50;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
body {
|
|
162
|
+
@apply bg-background text-foreground;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# pnpm 11 workspace + settings (camelCase; .npmrc is auth/registry-only).
|
|
2
|
+
packages:
|
|
3
|
+
- "apps/*"
|
|
4
|
+
- "packages/*"
|
|
5
|
+
# `infra` (the deploy capability, ADR 0021) scaffolds at the repo root, a sibling of
|
|
6
|
+
# apps/ and packages/, not inside either — it isn't an app and it isn't a shared
|
|
7
|
+
# package, so it needs its own literal entry rather than fitting one of the globs.
|
|
8
|
+
- "infra"
|
|
9
|
+
|
|
10
|
+
# Pin exact versions so manifest and lockfile agree.
|
|
11
|
+
saveExact: true
|
|
12
|
+
# Fail installs when Node/pnpm don't satisfy `engines`.
|
|
13
|
+
engineStrict: true
|
|
14
|
+
# Collapse duplicate peer installs across the monorepo.
|
|
15
|
+
dedupePeerDependents: true
|
|
16
|
+
|
|
17
|
+
# Dependencies allowed to run install/build scripts (pnpm 11 blocks by default).
|
|
18
|
+
allowBuilds:
|
|
19
|
+
esbuild: true
|
|
20
|
+
workerd: true
|
|
21
|
+
sharp: true
|
|
22
|
+
# @pulumi/pulumi's gRPC transport (infra capability, ADR 0021) needs this postinstall.
|
|
23
|
+
protobufjs: true
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import ultracite from "ultracite/prettier";
|
|
2
|
+
|
|
3
|
+
// Ultracite's Prettier config carries no `plugins` key, so this is a spread rather
|
|
4
|
+
// than a re-export: Astro parsing and Tailwind class sorting are added on top.
|
|
5
|
+
// `prettier-plugin-tailwindcss` must stay LAST — it wraps whichever printer runs
|
|
6
|
+
// before it, and loses its sorting if another plugin loads after it.
|
|
7
|
+
export default {
|
|
8
|
+
...ultracite,
|
|
9
|
+
plugins: ["prettier-plugin-astro", "prettier-plugin-tailwindcss"],
|
|
10
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import ultracite from "ultracite/stylelint";
|
|
2
|
+
|
|
3
|
+
// Ultracite's Stylelint config with the at-rule allow-list widened for Tailwind v4.
|
|
4
|
+
// Its list stops at tailwind/apply/layer/variants/responsive/screen/source/reference,
|
|
5
|
+
// and `packages/ui/src/styles/globals.css` also uses `@theme` and `@custom-variant`,
|
|
6
|
+
// so without these entries the config fails on the only CSS file you ship.
|
|
7
|
+
//
|
|
8
|
+
// The notation rules match shadcn's own output: its colour tokens are written
|
|
9
|
+
// `oklch(0.985 0 0)`, and rewriting them to `oklch(98.5% 0deg)` would have to be
|
|
10
|
+
// redone by hand after every `shadcn add` sync.
|
|
11
|
+
export default {
|
|
12
|
+
...ultracite,
|
|
13
|
+
|
|
14
|
+
// Stylelint has no .gitignore support and its default ignore list is
|
|
15
|
+
// `node_modules` only, so build output has to be named here. `pnpm lint:css`
|
|
16
|
+
// globs `**/*.css`, which after a `pnpm build` would otherwise walk into
|
|
17
|
+
// `apps/*/dist/_astro/*.css` — Tailwind's minified output, ~600 findings of
|
|
18
|
+
// "violations" in code nobody wrote.
|
|
19
|
+
ignoreFiles: [
|
|
20
|
+
"**/node_modules/**",
|
|
21
|
+
"**/dist/**",
|
|
22
|
+
"**/build/**",
|
|
23
|
+
"**/.astro/**",
|
|
24
|
+
"**/.turbo/**",
|
|
25
|
+
"**/.wrangler/**",
|
|
26
|
+
],
|
|
27
|
+
rules: {
|
|
28
|
+
...ultracite.rules,
|
|
29
|
+
"import-notation": "string",
|
|
30
|
+
"hue-degree-notation": "number",
|
|
31
|
+
"lightness-notation": "number",
|
|
32
|
+
"at-rule-no-unknown": [
|
|
33
|
+
true,
|
|
34
|
+
{
|
|
35
|
+
ignoreAtRules: [
|
|
36
|
+
...ultracite.rules["at-rule-no-unknown"][1].ignoreAtRules,
|
|
37
|
+
"custom-variant",
|
|
38
|
+
"plugin",
|
|
39
|
+
"theme",
|
|
40
|
+
"utility",
|
|
41
|
+
"variant",
|
|
42
|
+
],
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
},
|
|
46
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://turbo.build/schema.json",
|
|
3
|
+
"ui": "tui",
|
|
4
|
+
"tasks": {
|
|
5
|
+
"build": {
|
|
6
|
+
"dependsOn": ["^build"],
|
|
7
|
+
"outputs": ["dist/**", ".astro/**"]
|
|
8
|
+
},
|
|
9
|
+
"clean": {
|
|
10
|
+
"cache": false
|
|
11
|
+
},
|
|
12
|
+
"dev": {
|
|
13
|
+
"cache": false,
|
|
14
|
+
"persistent": true
|
|
15
|
+
},
|
|
16
|
+
"typecheck": {
|
|
17
|
+
"dependsOn": ["^build"]
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|