Skip to content

Commit 052ce74

Browse files
mblodeclaude
andcommitted
Marx 5: modern rewrite with auto dark mode, cascade layers, and design tokens
Ground-up modernization borrowing patterns from Tailwind Preflight v4.3 and shadcn/ui typeset: - Automatic light/dark mode via color-scheme + light-dark() oklch tokens - Zero-specificity :where() rules inside @layer marx.base/content/forms - New --marx-* token API (rem type scale, logical properties, RTL-ready) - Self-authored preflight base replaces vendored sanitize.css - Typeset-style one-directional margin-block-start rhythm - :focus-visible outlines, :user-invalid, accent-color, field-sizing, text-wrap balance/pretty, styled dialog/popover/kbd, print styles - Build swapped from PostCSS to Lightning CSS; exports/style/sideEffects added to package.json; publint in CI; browser floor Baseline 2024 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 53b9609 commit 052ce74

26 files changed

Lines changed: 4322 additions & 5093 deletions

.changeset/modern-marx-five.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
---
2+
"marx-css": major
3+
---
4+
5+
Marx 5: a ground-up modernization for the 2026 web, borrowing patterns from Tailwind CSS Preflight v4.3 and shadcn/ui typeset.
6+
7+
**Highlights**
8+
9+
- Automatic light/dark mode via `color-scheme` + `light-dark()` — force a scheme with `:root { color-scheme: light }` (or `dark`).
10+
- Zero specificity: every rule is wrapped in `:where()` inside cascade layers (`marx.base`, `marx.content`, `marx.forms`), so any consumer CSS overrides Marx.
11+
- New `--marx-*` design-token API (oklch colors, `rem` type scale) replaces the old unprefixed variables — see the migration table in the README.
12+
- Modern preflight-style base replaces the vendored sanitize.css snapshot.
13+
- Typeset-style rhythm: one-directional `margin-block-start` flow, logical properties throughout (RTL-ready), `text-wrap: balance`/`pretty`, styled `dialog`/`[popover]`/`kbd`, accent-colored native controls, `field-sizing` textareas.
14+
- Accessibility: `:focus-visible` outlines everywhere (no more removed outlines), `:user-invalid` instead of `:invalid`, transitions gated behind `prefers-reduced-motion`, print styles, WCAG AA-checked palette in both schemes.
15+
- Build swapped from PostCSS to Lightning CSS; package gains `exports`/`style`/`sideEffects` fields.
16+
17+
**Breaking changes**
18+
19+
- Theming variables renamed (`--md-pad``--marx-space-md`, `--link-color``--marx-link`, …) — full table in the README.
20+
- Pages now follow the OS dark-mode preference by default; add `:root { color-scheme: light }` to keep v4's always-light look.
21+
- Links are subtly underlined; type scale is `rem`-based; browser floor is Baseline 2024 (Chrome/Edge 123+, Firefox 120+, Safari 17.5+), with older browsers degrading to a readable light theme.

.claude/CLAUDE.md

Lines changed: 2 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -1,123 +1,3 @@
1-
# Ultracite Code Standards
1+
# Marx
22

3-
This project uses **Ultracite**, a zero-config preset that enforces strict code quality standards through automated formatting and linting.
4-
5-
## Quick Reference
6-
7-
- **Format code**: `npm exec -- ultracite fix`
8-
- **Check for issues**: `npm exec -- ultracite check`
9-
- **Diagnose setup**: `npm exec -- ultracite doctor`
10-
11-
Biome (the underlying engine) provides robust linting and formatting. Most issues are automatically fixable.
12-
13-
---
14-
15-
## Core Principles
16-
17-
Write code that is **accessible, performant, type-safe, and maintainable**. Focus on clarity and explicit intent over brevity.
18-
19-
### Type Safety & Explicitness
20-
21-
- Use explicit types for function parameters and return values when they enhance clarity
22-
- Prefer `unknown` over `any` when the type is genuinely unknown
23-
- Use const assertions (`as const`) for immutable values and literal types
24-
- Leverage TypeScript's type narrowing instead of type assertions
25-
- Use meaningful variable names instead of magic numbers - extract constants with descriptive names
26-
27-
### Modern JavaScript/TypeScript
28-
29-
- Use arrow functions for callbacks and short functions
30-
- Prefer `for...of` loops over `.forEach()` and indexed `for` loops
31-
- Use optional chaining (`?.`) and nullish coalescing (`??`) for safer property access
32-
- Prefer template literals over string concatenation
33-
- Use destructuring for object and array assignments
34-
- Use `const` by default, `let` only when reassignment is needed, never `var`
35-
36-
### Async & Promises
37-
38-
- Always `await` promises in async functions - don't forget to use the return value
39-
- Use `async/await` syntax instead of promise chains for better readability
40-
- Handle errors appropriately in async code with try-catch blocks
41-
- Don't use async functions as Promise executors
42-
43-
### React & JSX
44-
45-
- Use function components over class components
46-
- Call hooks at the top level only, never conditionally
47-
- Specify all dependencies in hook dependency arrays correctly
48-
- Use the `key` prop for elements in iterables (prefer unique IDs over array indices)
49-
- Nest children between opening and closing tags instead of passing as props
50-
- Don't define components inside other components
51-
- Use semantic HTML and ARIA attributes for accessibility:
52-
- Provide meaningful alt text for images
53-
- Use proper heading hierarchy
54-
- Add labels for form inputs
55-
- Include keyboard event handlers alongside mouse events
56-
- Use semantic elements (`<button>`, `<nav>`, etc.) instead of divs with roles
57-
58-
### Error Handling & Debugging
59-
60-
- Remove `console.log`, `debugger`, and `alert` statements from production code
61-
- Throw `Error` objects with descriptive messages, not strings or other values
62-
- Use `try-catch` blocks meaningfully - don't catch errors just to rethrow them
63-
- Prefer early returns over nested conditionals for error cases
64-
65-
### Code Organization
66-
67-
- Keep functions focused and under reasonable cognitive complexity limits
68-
- Extract complex conditions into well-named boolean variables
69-
- Use early returns to reduce nesting
70-
- Prefer simple conditionals over nested ternary operators
71-
- Group related code together and separate concerns
72-
73-
### Security
74-
75-
- Add `rel="noopener"` when using `target="_blank"` on links
76-
- Avoid `dangerouslySetInnerHTML` unless absolutely necessary
77-
- Don't use `eval()` or assign directly to `document.cookie`
78-
- Validate and sanitize user input
79-
80-
### Performance
81-
82-
- Avoid spread syntax in accumulators within loops
83-
- Use top-level regex literals instead of creating them in loops
84-
- Prefer specific imports over namespace imports
85-
- Avoid barrel files (index files that re-export everything)
86-
- Use proper image components (e.g., Next.js `<Image>`) over `<img>` tags
87-
88-
### Framework-Specific Guidance
89-
90-
**Next.js:**
91-
- Use Next.js `<Image>` component for images
92-
- Use `next/head` or App Router metadata API for head elements
93-
- Use Server Components for async data fetching instead of async Client Components
94-
95-
**React 19+:**
96-
- Use ref as a prop instead of `React.forwardRef`
97-
98-
**Solid/Svelte/Vue/Qwik:**
99-
- Use `class` and `for` attributes (not `className` or `htmlFor`)
100-
101-
---
102-
103-
## Testing
104-
105-
- Write assertions inside `it()` or `test()` blocks
106-
- Avoid done callbacks in async tests - use async/await instead
107-
- Don't use `.only` or `.skip` in committed code
108-
- Keep test suites reasonably flat - avoid excessive `describe` nesting
109-
110-
## When Biome Can't Help
111-
112-
Biome's linter will catch most issues automatically. Focus your attention on:
113-
114-
1. **Business logic correctness** - Biome can't validate your algorithms
115-
2. **Meaningful naming** - Use descriptive names for functions, variables, and types
116-
3. **Architecture decisions** - Component structure, data flow, and API design
117-
4. **Edge cases** - Handle boundary conditions and error states
118-
5. **User experience** - Accessibility, performance, and usability considerations
119-
6. **Documentation** - Add comments for complex logic, but prefer self-documenting code
120-
121-
---
122-
123-
Most formatting and common issues are automatically fixed by Biome. Run `npm exec -- ultracite fix` before committing to ensure compliance.
3+
See [AGENTS.md](../AGENTS.md) for everything: what Marx is, commands, CSS architecture conventions, and the release flow.

.github/workflows/ci.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ on:
55
branches: ["**"]
66
pull_request:
77

8+
concurrency:
9+
group: ci-${{ github.ref }}
10+
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
11+
812
jobs:
913
build:
1014
runs-on: ubuntu-latest
@@ -14,7 +18,7 @@ jobs:
1418
- name: Setup Node
1519
uses: actions/setup-node@v4
1620
with:
17-
node-version: 'lts/*'
21+
node-version: "lts/*"
1822
cache: npm
1923
- name: Install
2024
run: npm ci
@@ -24,3 +28,5 @@ jobs:
2428
run: npm run format:check
2529
- name: Build
2630
run: npm run build
31+
- name: Publint
32+
run: npx publint

.npmignore

Lines changed: 0 additions & 12 deletions
This file was deleted.

.zed/settings.json

Lines changed: 1 addition & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,3 @@
11
{
2-
"formatter": "language_server",
3-
"format_on_save": "on",
4-
"lsp": {
5-
"typescript-language-server": {
6-
"settings": {
7-
"typescript": {
8-
"preferences": {
9-
"includePackageJsonAutoImports": "on"
10-
}
11-
}
12-
}
13-
}
14-
},
15-
"languages": {
16-
"JavaScript": {
17-
"formatter": {
18-
"language_server": {
19-
"name": "biome"
20-
}
21-
},
22-
"code_actions_on_format": {
23-
"source.fixAll.biome": true,
24-
"source.organizeImports.biome": true
25-
}
26-
},
27-
"TypeScript": {
28-
"formatter": {
29-
"language_server": {
30-
"name": "biome"
31-
}
32-
},
33-
"code_actions_on_format": {
34-
"source.fixAll.biome": true,
35-
"source.organizeImports.biome": true
36-
}
37-
},
38-
"TSX": {
39-
"formatter": {
40-
"language_server": {
41-
"name": "biome"
42-
}
43-
},
44-
"code_actions_on_format": {
45-
"source.fixAll.biome": true,
46-
"source.organizeImports.biome": true
47-
}
48-
}
49-
}
2+
"format_on_save": "on"
503
}

0 commit comments

Comments
 (0)