Skip to content

Commit ca08bf3

Browse files
bloveclaude
andauthored
chore(website): lint guard against new static inline styles (#858)
Lands only now that all seven migration batches (#848-#857) are merged, so it never sees legacy code. Flags identifier-keyed members of a style object literal in apps/website/src; the style={{ '--x': value }} escape hatch uses string-literal keys and passes. Excluded: the two Satori OG-image files (inline-only by design - note the [slug] segment must be matched by wildcard, brackets are a glob character class), the dev-only primitives route, and specs. Verified with raw eslint: fires on an identifier-key probe, silent on a custom-property probe, zero hits on the OG file. Baseline is 18 warnings - exactly the documented dynamic-value sites from the batch reports - and 0 errors, so CI (which fails on errors only) stays green. Ships as 'warn'; the escalation to 'error' is a deliberate follow-up one release later. Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
1 parent bb95afc commit ca08bf3

1 file changed

Lines changed: 30 additions & 0 deletions

File tree

eslint.config.mjs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,34 @@ export default [
5454
// Override or add rules here
5555
rules: {},
5656
},
57+
// Inline-style guard — apps/website migrated off static inline styles
58+
// (docs/superpowers/specs/2026-08-29-inline-style-substrate-migration-design.md,
59+
// batches #848–#857). Flags identifier-keyed members of a style object
60+
// literal. The escape hatch for dynamic values — style={{ '--x': value }} —
61+
// uses string-literal keys and passes. Genuinely dynamic identifier-keyed
62+
// values (rare) get a targeted eslint-disable-next-line with a reason.
63+
// Ships as 'warn' for one release, then 'error'.
64+
{
65+
files: ['apps/website/src/**/*.tsx'],
66+
ignores: [
67+
// Satori-rendered OG images: inline styles are the only mechanism there.
68+
'apps/website/src/app/opengraph-image.tsx',
69+
// NOTE: [slug] would be a glob character class, so match by wildcard.
70+
'apps/website/src/app/blog/*/opengraph-image.tsx',
71+
// Dev-only route slated for deletion.
72+
'apps/website/src/app/dev/primitives/page.tsx',
73+
'apps/website/src/**/*.spec.tsx',
74+
],
75+
rules: {
76+
'no-restricted-syntax': [
77+
'warn',
78+
{
79+
selector:
80+
'JSXAttribute[name.name="style"] > JSXExpressionContainer > ObjectExpression > Property[key.type="Identifier"]',
81+
message:
82+
"Static presentation belongs in src/styles/*.css (see the substrate-migration spec). For dynamic values, set a CSS custom property: style={{ '--x': value }}.",
83+
},
84+
],
85+
},
86+
},
5787
];

0 commit comments

Comments
 (0)