[{"type":"docs","description":"Discover the styled API and how to compose atoms with it.","priority":1,"keywords":["styled","styled components","atomic components","atomic design","extending components"],"tags":["Styled Components","Atoms"],"frameworks":["react","next","astro"],"href":"/react/docs/basics/styled-components"},{"title":"Breakpoints & responsive layouts","type":"docs","description":"Name a condition once, then reference it by @name in any style object.","priority":1,"keywords":["breakpoints","media queries","responsive","container queries","dark mode","print"],"tags":["Breakpoints","Responsive"],"frameworks":["react","next","astro"],"href":"/react/docs/basics/breakpoints"},{"title":"Animations","type":"docs","description":"Transitions, keyframes and attribute-driven motion — lightest tool first.","priority":1,"keywords":["animations","keyframes","transitions","motion","stagger","scroll animation"],"tags":["Animations","Motion"],"frameworks":["react","next","astro"],"href":"/react/docs/basics/animations"},{"title":"Modifiers","type":"docs","description":"Invent a value shape, register what it becomes, and let it fire by recognition.","priority":1,"keywords":["modifiers","custom syntax","pattern","transform","config","value rewriting"],"tags":["Modifiers","Configuration"],"frameworks":["react","next","astro"],"href":"/react/docs/basics/modifiers"},{"title":"Viewport Clamp","type":"docs","description":"A size that scales smoothly with the screen instead of jumping at fixed breakpoints.","priority":1,"keywords":["viewport clamp","fluid sizing","clamp","responsive type","defineViewportClamp","scaling"],"tags":["Viewport Clamp","Responsive"],"frameworks":["react","next","astro"],"href":"/react/docs/basics/helpers/viewport-clamp"},{"title":"Color Function","type":"docs","description":"Chainable color transforms that resolve at build time into plain static strings.","priority":1,"keywords":["color","color function","lighten","darken","alpha","palette","shades"],"tags":["Color","Helpers"],"frameworks":["react","next","astro"],"href":"/react/docs/basics/color-function"},{"title":"Helpers","type":"docs","description":"Plain functions that compute a style value, resolved once at build time.","priority":1,"keywords":["helpers","helper functions","computed values","viewport clamp","color","rem"],"tags":["Helpers","Build Time"],"frameworks":["react","next","astro"],"href":"/react/docs/basics/helpers"},{"title":"Scoping and composition","type":"docs","description":"How styles stay put, and how to change them deliberately when you want to.","priority":1,"keywords":["scoping","composition","overrides","cascade layers","priority","extending components"],"tags":["Scoping","Cascade Layers"],"frameworks":["react","next","astro"],"href":"/react/docs/basics/scoping-and-composition"},{"title":"Runtime styles","type":"docs","description":"For style objects that do not exist until the request runs — and the security posture that comes with them.","priority":1,"keywords":["runtime styles","defineRuntime","request time","profile customization","cms overrides","dynamic css"],"tags":["Runtime Styles","Advanced"],"frameworks":["react","next","astro"],"href":"/react/docs/basics/runtime-styles"},{"title":"Accessibility","type":"docs","description":"Salty can't make your site accessible — it can make the accessible version cheaper to write.","priority":1,"keywords":["accessibility","a11y","aria","focus","contrast","reduced motion","zoom"],"tags":["Guides","Accessibility"],"frameworks":["react","next","astro"],"href":"/react/docs/basics/accessibility"},{"title":"Tooling","type":"docs","description":"TypeScript, one CLI, one ESLint plugin — and a type layer your own definitions generate.","priority":1,"keywords":["tooling","cli","eslint","types","autocomplete","devtools"],"tags":["Tooling","CLI"],"frameworks":["react","next","astro"],"href":"/react/docs/basics/tooling"},{"title":"Testing","type":"docs","description":"Three jobs, three tools — and a clear line between what is safe to assert on and what is not.","priority":1,"keywords":["testing","unit tests","visual regression","assertions","devtools","build output"],"tags":["Testing","Tooling"],"frameworks":["react","next","astro"],"href":"/react/docs/basics/testing"},{"title":"Security","type":"docs","description":"The CSS on your site is CSS you wrote — except in four places worth knowing about.","priority":1,"keywords":["security","untrusted input","sanitization","csp","nonce","validation"],"tags":["Security","Runtime Styles"],"frameworks":["react","next","astro"],"href":"/react/docs/basics/security"},{"title":"Class Names","type":"docs","description":"Get the same styling surface back as a class string, for the markup you do not own.","priority":1,"keywords":["className","class names","class string","third-party components","framework agnostic","variant chain"],"tags":["Class Names","Styling"],"frameworks":["react","next","astro"],"href":"/react/docs/basics/class-names"},{"title":"Dynamic Values","type":"docs","description":"Values decided in code — a variable, an import, a function, or a prop the consumer sets.","priority":1,"keywords":["dynamic values","build time","async","css variables","prop tokens","computed styles"],"tags":["Dynamic Values","Build Time"],"frameworks":["react","next","astro"],"href":"/react/docs/basics/dynamic-values"},{"title":"Interactive State","type":"docs","description":"Most interactive state is not a JavaScript problem — start with what the browser already tracks.","priority":1,"keywords":["interactive state","hover","focus","pseudo-classes","state variants","prop tokens","disabled"],"tags":["Interactive State","Styling"],"frameworks":["react","next","astro"],"href":"/react/docs/basics/interactive-state"},{"title":"Variants","type":"docs","description":"Named branches of a style, picked at the call site and compiled before your app runs.","priority":1,"keywords":["variants","compound variants","default variants","boolean variants","variant axes","styling branches"],"tags":["Variants","Styling"],"frameworks":["react","next","astro"],"href":"/react/docs/basics/variants"},{"title":"Variables & Tokens","type":"docs","description":"Name a value once, reference it by path everywhere, and let the compiler check it.","priority":1,"keywords":["variables","tokens","design tokens","custom properties","defineVariables","responsive tokens"],"tags":["Variables","Tokens"],"frameworks":["react","next","astro"],"href":"/react/docs/basics/variables"},{"title":"Theming","type":"docs","description":"The switchable layer on top of your variables — one attribute repaints an entire tree.","priority":1,"keywords":["theming","themes","dark mode","light and dark","data-theme","color scheme"],"tags":["Theming","Tokens"],"frameworks":["react","next","astro"],"href":"/react/docs/basics/theming"},{"title":"Templates","type":"docs","description":"Bundle the handful of properties you always set as a group under a single name.","priority":1,"keywords":["templates","defineTemplates","text styles","style bundles","shorthand","function templates"],"tags":["Templates","Styling"],"frameworks":["react","next","astro"],"href":"/react/docs/basics/templates"},{"title":"Global Styles","type":"docs","description":"Document-level rules — the deliberate exception to Salty scoping everything by default.","priority":1,"keywords":["global styles","defineGlobalStyles","document styles","base styles","reset","bare selectors"],"tags":["Global Styles","Cascade Layers"],"frameworks":["react","next","astro"],"href":"/react/docs/basics/global-styles"},{"title":"Fonts & Imports","type":"docs","description":"Register a font once and reference it everywhere, or pull in any external stylesheet.","priority":1,"keywords":["fonts","defineFont","defineImport","font-face","web fonts","stylesheet imports"],"tags":["Fonts","Imports"],"frameworks":["react","next","astro"],"href":"/react/docs/basics/fonts"},{"title":"Basic setup","type":"docs","description":"Install it, write one file, import it into a page — most of it is one command.","priority":1,"keywords":["setup","install","getting started","init","first component","plugin"],"tags":["Get Started","Setup"],"frameworks":["react","next","astro"],"href":"/react/docs/getting-started/basic-setup"},{"title":"API overview","type":"docs","description":"The map: every export grouped by the job it does, so you know what to reach for.","priority":1,"keywords":["api","overview","map","which api","exports","imports"],"tags":["Get Started","API"],"frameworks":["react","next","astro"],"href":"/react/docs/getting-started/api-overview"},{"title":"Configuration","type":"docs","description":"What's inside salty.config.ts, what can live elsewhere, and the file next to it people forget.","priority":1,"keywords":["configuration","salty.config.ts","defineConfig","saltyrc","setup","factories"],"tags":["Get Started","Configuration"],"frameworks":["react","next","astro"],"href":"/react/docs/getting-started/configuration"},{"title":"Editor setup","type":"docs","description":"No extension to install — everything your editor knows about Salty comes through TypeScript.","priority":1,"keywords":["editor","eslint","typescript","autocomplete","vscode","prepare"],"tags":["Get Started","Tooling"],"frameworks":["react","next","astro"],"href":"/react/docs/getting-started/editor-setup"},{"title":"File structure","type":"docs","description":"The files you write, the files Salty writes, and how to read saltygen/ when something's wrong.","priority":1,"keywords":["file structure","saltygen","suffix","generated output","debugging","hashes"],"tags":["Get Started","Compiler Output"],"frameworks":["react","next","astro"],"href":"/react/docs/getting-started/file-structure"},{"title":"Advanced setup","type":"docs","description":"The shared files that turn one component into part of a system.","priority":1,"keywords":["advanced setup","shared styles","styles folder","tokens","theming","system"],"tags":["Get Started","Setup"],"frameworks":["react","next","astro"],"href":"/react/docs/getting-started/advanced-setup"},{"title":"Troubleshooting","type":"docs","description":"Work out which stage failed, not which line — ordered by likelihood.","priority":1,"keywords":["troubleshooting","unstyled","not working","no styles","debugging","strict"],"tags":["Get Started","Troubleshooting"],"frameworks":["react","next","astro"],"href":"/react/docs/getting-started/troubleshooting"},{"title":"Updates","type":"docs","description":"Keeping a project current is one command, because every Salty package ships together.","priority":1,"keywords":["update","upgrade","version","release notes","pre-1.0","pinning"],"tags":["Updates","CLI"],"frameworks":["react","next","astro"],"href":"/react/docs/guides/updates"},{"title":"Migration","type":"docs","description":"Six changes for everyone, then a mapping table per source — with the hard part named each time.","priority":1,"keywords":["migration","porting","styled-components","stitches","panda","tailwind","sass"],"tags":["Guides","Migration"],"frameworks":["react","next","astro"],"href":"/react/docs/guides/migration"},{"title":"Framework agnostic APIs","type":"docs","description":"For the stacks Salty doesn't ship wiring for — which is most of them, and mostly fine.","priority":1,"keywords":["framework agnostic","vue","svelte","angular","className","bundler","core"],"tags":["Guides","Framework Agnostic"],"frameworks":["react","next","astro"],"href":"/react/docs/guides/framework-agnostic"},{"title":"styled reference","priority":1,"type":"docs","description":"The full options table for styled(), and what the returned component accepts.","keywords":["styled","styled reference","styled api","options","passProps","priority"],"tags":["Reference","Styled Components"],"frameworks":["react","next","astro"],"href":"/react/docs/reference/styled"},{"title":"className reference","priority":1,"type":"docs","description":"The full options table for className(), and what the returned class string carries.","keywords":["className","className reference","class name api","variant","priority","options"],"tags":["Reference","Class Names"],"frameworks":["react","next","astro"],"href":"/react/docs/reference/class-name"},{"title":"CSS reset","priority":1,"type":"docs","description":"The small reset Salty applies by default, and how to replace or disable it.","keywords":["css reset","reset","browser defaults","border-box","normalize","reset option"],"tags":["Reference","Reset"],"frameworks":["react","next","astro"],"href":"/react/docs/reference/css-reset"},{"title":"CLI reference","priority":1,"type":"docs","description":"Every salty-css command, argument and flag — and what each one writes.","keywords":["cli","salty-css","init","generate","build","update","command line"],"tags":["Reference","CLI"],"frameworks":["react","next","astro"],"href":"/react/docs/reference/cli"},{"type":"docs","priority":0.49999999999999994,"title":"What the styled() API is shaped around","description":"The four ideas behind the styled() API: build-time execution, components over class names, variants as layers, and primitives over UI kits.","teaches":"The design ideas that explain why the styled() API looks and behaves the way it does","subsection":true,"frameworks":["react","next","astro"],"keywords":["design philosophy","build time","runtime css-in-js","variants as layers","primitives","why styled","stitches"],"tags":["Styled Components","Philosophy"],"href":"/react/docs/basics/styled-components#what-the-api-is-shaped-around"},{"type":"docs","priority":0.49999999999999994,"title":"Deconstructing styled component parameters","description":"The anatomy of a styled() call: the tag, base styles, variants, defaultVariants and element — and why the file has to end in .css.ts.","teaches":"What each option in the styled() options object does and how variants become typed props","subsection":true,"frameworks":["react","next","astro"],"keywords":["styled options","base","variants","defaultVariants","element","css.ts","typed props"],"tags":["Styled Components","API"],"href":"/react/docs/basics/styled-components#deconstructing-styled-component-parameters"},{"type":"docs","priority":0.49999999999999994,"title":"Composing atoms into a card","description":"Building Card, CardTitle and CardBody as independent atoms and composing them freely — no shared context, no prop-drilling, no wrapper elements.","teaches":"How to compose independent styled() atoms into larger pieces of UI","subsection":true,"frameworks":["react","next","astro"],"keywords":["composing components","atoms","atomic design","card component","independent components"],"tags":["Styled Components","Atoms"],"href":"/react/docs/basics/styled-components#example-1-composing-atoms"},{"type":"docs","priority":0.49999999999999994,"title":"Extending a styled component","description":"Wrapping an existing styled() component: the new component inherits every variant and lands in a higher cascade layer, so its styles win without specificity fights.","teaches":"How extending a styled component inherits its variants and wins the cascade via layers","subsection":true,"frameworks":["react","next","astro"],"keywords":["extending components","wrapping components","inherit variants","cascade layers","defaultProps","override styles"],"tags":["Styled Components","Cascade Layers"],"href":"/react/docs/basics/styled-components#example-2-extending-components"},{"type":"docs","priority":0.49999999999999994,"title":"The three responsive tools","description":"Inline at-rules for a one-off, named queries for everything else, and value-level tools when it is one value changing rather than a block of styles.","teaches":"Which of the three tools fits, and the wiring step that fails silently","subsection":true,"frameworks":["react","next","astro"],"keywords":["inline at-rule","named query","responsive tokens","build graph","silent failure"],"tags":["Breakpoints","Concepts"],"href":"/react/docs/basics/breakpoints#how-it-works-briefly"},{"type":"docs","priority":0.49999999999999994,"title":"Naming a breakpoint set","description":"Define named queries in one central file, choose a direction and stay consistent, then reference them by @name across components.","teaches":"How to name breakpoints well, why direction consistency matters, and the three-step check when one is not firing","subsection":true,"frameworks":["react","next","astro"],"keywords":["defineMediaQuery","minWidth","maxWidth","mobile-first","desktop-first","naming"],"tags":["Breakpoints","Setup"],"href":"/react/docs/basics/breakpoints#example-1-name-your-breakpoints-once"},{"type":"docs","priority":0.49999999999999994,"title":"Conditions past width","description":"A media query is really any condition — dark, print, reduced motion, orientation — and they combine with and() and or().","teaches":"The full builder vocabulary beyond width, and when dark mode should be theming instead","subsection":true,"frameworks":["react","next","astro"],"keywords":["dark","print","reducedMotion","orientation","and or","custom","fluent form"],"tags":["Breakpoints","Media Queries"],"href":"/react/docs/basics/breakpoints#example-2-past-width"},{"type":"docs","priority":0.49999999999999994,"title":"Container queries","description":"A media query only ever asks about the viewport; a container query lets one component lay out two ways depending on the slot it lands in.","teaches":"How to set up a containment context, name a container query, and when to prefer it over a media query","subsection":true,"frameworks":["react","next","astro"],"keywords":["container queries","containerType","inline-size","placement-independent","cqi","container units"],"tags":["Breakpoints","Container Queries"],"href":"/react/docs/basics/breakpoints#example-3-container-queries"},{"type":"docs","priority":0.49999999999999994,"title":"When a breakpoint is the wrong tool","description":"Breakpoints move in hard steps. When the change is really one value moving smoothly, responsive tokens or a viewport clamp are the lighter answer.","teaches":"How to tell a genuine breakpoint from a fluid value pretending to be a stepped one","subsection":true,"frameworks":["react","next","astro"],"keywords":["over-reach","hard steps","responsive tokens","viewport clamp","composing","fluid"],"tags":["Breakpoints","Decisions"],"href":"/react/docs/basics/breakpoints#example-4-when-a-breakpoint-is-wrong"},{"type":"docs","priority":0.49999999999999994,"title":"The three animation tools","description":"Transitions are plain CSS with no special API; keyframes are the one primitive Salty adds; the ordering is the same lightest-first ladder used for state generally.","teaches":"Which of the three tools a given motion needs","subsection":true,"frameworks":["react","next","astro"],"keywords":["transitions","keyframes primitive","ladder","lightest first","two-state change"],"tags":["Animations","Concepts"],"href":"/react/docs/basics/animations#how-animations-work-briefly"},{"type":"docs","priority":0.49999999999999994,"title":"Transitions: the lightest tool","description":"Put the transition on the resting style and change the property inside the state selector — the browser tweens the difference, with nothing to wire up.","teaches":"When a transition is all you need, and which triggers can drive one","subsection":true,"frameworks":["react","next","astro"],"keywords":["transition","hover","resting state","no keyframe","browser tracked triggers"],"tags":["Animations","Transitions"],"href":"/react/docs/basics/animations#example-1-transitions"},{"type":"docs","priority":0.49999999999999994,"title":"Defining and tuning keyframes","description":"keyframes() defines the rule and returns a callable value — plus the export rule, the timing params table, and what appendInitialStyles fixes.","teaches":"How to define a keyframe, reuse one definition at different timings, and gate motion behind a reduced-motion preference","subsection":true,"frameworks":["react","next","astro"],"keywords":["keyframes","animationName","appendInitialStyles","params","callable","top-level export"],"tags":["Animations","Keyframes"],"href":"/react/docs/basics/animations#example-2-keyframes"},{"type":"docs","priority":0.49999999999999994,"title":"Keyframes as variants, staggering, and pausing","description":"Choosing an animation per instance with a variant, staggering a list of any length with a prop token, and pausing from a selector with animationPlayState.","teaches":"Why a stagger belongs in a prop token rather than a per-index variant, and how to pause without restating the shorthand","subsection":true,"frameworks":["react","next","astro"],"keywords":["entrance variant","stagger","props.index","css-index","animationPlayState","marquee"],"tags":["Animations","Patterns"],"href":"/react/docs/basics/animations#example-3-keyframes-in-real-components"},{"type":"docs","priority":0.49999999999999994,"title":"On-scroll entrances with no keyframe and no dependency","description":"An attribute, a global style built on a :not() selector, and an IntersectionObserver — plus the honest catch about content hidden by default.","teaches":"How to build an on-scroll entrance from the platform, and the no-JS decision it forces","subsection":true,"frameworks":["react","next","astro"],"keywords":["on scroll","IntersectionObserver","data-entry","defineGlobalStyles","not selector","no-js fallback"],"tags":["Animations","Progressive Enhancement"],"href":"/react/docs/basics/animations#example-4-state-driven-entry"},{"type":"docs","priority":0.49999999999999994,"title":"Sharing keyframe definitions","description":"A private helper called at the top level lets you stamp out a family of related animations without breaking the top-level-export rule.","teaches":"How to generate related keyframes, and when overriding params at the call site is better","subsection":true,"frameworks":["react","next","astro"],"keywords":["private helper","top-level export","family of animations","params override","less css"],"tags":["Animations","Patterns"],"href":"/react/docs/basics/animations#sharing-keyframe-definitions"},{"type":"docs","priority":0.49999999999999994,"title":"How a modifier works","description":"A pattern and a transform — plus the three facts that decide whether your pattern actually fires, the first of which surprises everyone.","teaches":"What the regex is really tested against, when tokens are resolved, and what transform receives","subsection":true,"frameworks":["react","next","astro"],"keywords":["pattern","transform","finished declaration","token resolution","declaration order","css return"],"tags":["Modifiers","Mechanism"],"href":"/react/docs/basics/modifiers#how-a-modifier-works"},{"type":"docs","priority":0.49999999999999994,"title":"Modifier, token, template, or helper?","description":"Four features overlap around reuse, and the difference is what you are reusing — a value, a bundle, a computation, or a value shape.","teaches":"The tie-breaker between a modifier and its three neighbours","subsection":true,"frameworks":["react","next","astro"],"keywords":["comparison","tokens","templates","helpers","value shape","tie-breaker"],"tags":["Modifiers","Decisions"],"href":"/react/docs/basics/modifiers#which-tool-for-which-job"},{"type":"docs","priority":0.49999999999999994,"title":"Modifier gotchas","description":"Greedy patterns, keeping the css return flat, declaration order, and the discoverability cost every modifier adds.","teaches":"The four things that go wrong with modifiers and when to prefer a token instead","subsection":true,"frameworks":["react","next","astro"],"keywords":["greedy patterns","flat css","run order","discoverability","no autocomplete","team cost"],"tags":["Modifiers","Pitfalls"],"href":"/react/docs/basics/modifiers#gotchas"},{"type":"docs","priority":0.49999999999999994,"title":"What a viewport clamp is for","description":"It replaces a stack of media queries with one continuously scaling value, so a size stays proportioned to the layout it was designed in.","teaches":"Why fluid scaling beats breakpoint-stepped sizes, and the two shapes of use that cover almost everything","subsection":true,"frameworks":["react","next","astro"],"keywords":["fluid sizing","breakpoints","proportioned","responsive tokens","one-off value"],"tags":["Viewport Clamp","Responsive"],"href":"/react/docs/basics/helpers/viewport-clamp#what-its-for"},{"type":"docs","priority":0.49999999999999994,"title":"Defining a clamp","description":"Create one clamp per device target with a reference screen size, multipliers that bound how far the value may move, and an optional axis.","teaches":"How to set up the small set of clamps a project needs","subsection":true,"frameworks":["react","next","astro"],"keywords":["defineViewportClamp","screenSize","minMultiplier","maxMultiplier","axis","device target"],"tags":["Viewport Clamp","Setup"],"href":"/react/docs/basics/helpers/viewport-clamp#defining-a-clamp"},{"type":"docs","priority":0.49999999999999994,"title":"Using a clamp","description":"Call it with the value you want at the reference size — it returns a clamp() string, so it works on any size property, not just font-size.","teaches":"How to call a clamp and when pairing it with a media query is worth it","subsection":true,"frameworks":["react","next","astro"],"keywords":["call site","any size property","padding","border radius","media query pairing"],"tags":["Viewport Clamp","Usage"],"href":"/react/docs/basics/helpers/viewport-clamp#using-a-clamp"},{"type":"docs","priority":0.49999999999999994,"title":"How a viewport clamp resolves","description":"The three parts of the generated clamp, how screenSize anchors the fluid middle, and the per-call min and max overrides.","teaches":"What the emitted clamp() actually contains and how to read a resolution table","subsection":true,"frameworks":["react","next","astro"],"keywords":["clamp parts","vw","vh","anchor","overrides","worked example"],"tags":["Viewport Clamp","Mechanism"],"href":"/react/docs/basics/helpers/viewport-clamp#how-it-works"},{"type":"docs","priority":0.49999999999999994,"title":"Building responsive tokens with a clamp","description":"Call the clamp once inside your variables so the whole spacing and type system scales fluidly and components just read plain token paths.","teaches":"The pattern that makes viewport clamps worth adopting rather than sprinkling","subsection":true,"frameworks":["react","next","astro"],"keywords":["responsive tokens","defineVariables","type scale","spacing scale","one place to change"],"tags":["Viewport Clamp","Tokens"],"href":"/react/docs/basics/helpers/viewport-clamp#building-responsive-tokens"},{"type":"docs","priority":0.49999999999999994,"title":"Viewport clamp reference","description":"The options defineViewportClamp accepts, the call arguments, the edge cases, and the best practices for keeping a system in proportion.","teaches":"Every option and argument, plus the four edge cases worth knowing before they bite","subsection":true,"frameworks":["react","next","astro"],"keywords":["options","arguments","edge cases","inverted min max","negative multipliers","best practices"],"tags":["Viewport Clamp","Reference"],"href":"/react/docs/basics/helpers/viewport-clamp#reference"},{"type":"docs","priority":0.49999999999999994,"title":"What color() is for, and its one boundary","description":"Deriving variations from one brand color — and the build-time boundary that means shades come from static atoms, never from themed molecules.","teaches":"The everyday use of color() and the single boundary that trips people","subsection":true,"frameworks":["react","next","astro"],"keywords":["derived shades","static atoms","themed molecules","build-time boundary","conditional scope"],"tags":["Color","Concepts"],"href":"/react/docs/basics/color-function#what-its-for"},{"type":"docs","priority":0.49999999999999994,"title":"Basic color() usage","description":"Chain transforms onto a source color and hand the result to any color property — each call resolves to a finished string at build time.","teaches":"How to chain color transforms and what lands in the compiled stylesheet","subsection":true,"frameworks":["react","next","astro"],"keywords":["chaining","alpha","lighten","darken","compiled output","no runtime"],"tags":["Color","Usage"],"href":"/react/docs/basics/color-function#basic-usage"},{"type":"docs","priority":0.49999999999999994,"title":"Deriving a palette from one source color","description":"Define one source color, derive the family from it, expose the shades as tokens — change the source and the whole family moves with it.","teaches":"The palette-from-one-color pattern and why it keeps a set of shades coherent","subsection":true,"frameworks":["react","next","astro"],"keywords":["palette","derived tokens","source of truth","brand color","defineVariables","reshade"],"tags":["Color","Tokens"],"href":"/react/docs/basics/color-function#deriving-a-palette"},{"type":"docs","priority":0.49999999999999994,"title":"Keeping interactive states in tune","description":"Deriving hover, press and disabled shades right where they are used — and the reminder that this only works on a static atom.","teaches":"How to keep state colours in tune with a base colour, and when the derive silently will not apply","subsection":true,"frameworks":["react","next","astro"],"keywords":["hover","active","disabled","static atom","themed molecule","interactive states"],"tags":["Color","Interactive State"],"href":"/react/docs/basics/color-function#theming-interactive-states"},{"type":"docs","priority":0.49999999999999994,"title":"color() reference","description":"Accepted sources, every chainable method grouped by what it changes, the output format methods, and the parsing and failure behaviour.","teaches":"The full method surface of color() and how it handles colour spaces and invalid input","subsection":true,"frameworks":["react","next","astro"],"keywords":["methods","alpha","saturate","rotate","mix","output formats","srgb","strict"],"tags":["Color","Reference"],"href":"/react/docs/basics/color-function#reference"},{"type":"docs","priority":0.49999999999999994,"title":"How helpers work","description":"No registration step and no compiler hook — a helper is a function that returns a value, called once while styles compile.","teaches":"How to write your own helper and where it should live in a project","subsection":true,"frameworks":["react","next","astro"],"keywords":["no registration","rem helper","build time","plain ts module","reuse"],"tags":["Helpers","Authoring"],"href":"/react/docs/basics/helpers#how-helpers-work"},{"type":"docs","priority":0.49999999999999994,"title":"The viewport clamp helper","description":"Trading a stack of media queries for a single native clamp() tuned to a reference screen, so type stays proportioned between breakpoints.","teaches":"What defineViewportClamp replaces and why continuous scaling beats snapping at breakpoints","subsection":true,"frameworks":["react","next","astro"],"keywords":["defineViewportClamp","fluid type","clamp","reference screen","fewer breakpoints"],"tags":["Helpers","Responsive"],"href":"/react/docs/basics/helpers#viewport-clamp"},{"type":"docs","priority":0.49999999999999994,"title":"The color helper","description":"A chainable build-time helper for lightening, darkening, mixing, fading and rotating colors, most often used to derive a family of shades from one.","teaches":"What color() does and the palette-from-one-color pattern it is best at","subsection":true,"frameworks":["react","next","astro"],"keywords":["color helper","darken","lighten","build time","derived shades","palette"],"tags":["Helpers","Color"],"href":"/react/docs/basics/helpers#color"},{"type":"docs","priority":0.49999999999999994,"title":"Nesting is already scoped","description":"SCSS-style nesting with & for pseudo-classes, combinators and attribute selectors — every one of which compiles anchored to the component hash.","teaches":"How nested selectors are written in Salty and why they cannot leak outside the component","subsection":true,"frameworks":["react","next","astro"],"keywords":["nesting","ampersand","combinators","hashed class","isolation","scss"],"tags":["Scoping","Selectors"],"href":"/react/docs/basics/scoping-and-composition#nesting-already-scoped"},{"type":"docs","priority":0.49999999999999994,"title":"Targeting another component by identity","description":"Interpolating a component hash into a selector, so contextual styling survives a tag change or an extra wrapper.","teaches":"How to style one Salty component from inside another without depending on markup structure","subsection":true,"frameworks":["react","next","astro"],"keywords":["hash interpolation","component identity","contextual styling","styling by contract","icon in button"],"tags":["Scoping","Composition"],"href":"/react/docs/basics/scoping-and-composition#targeting-another-component-by-identity"},{"type":"docs","priority":0.49999999999999994,"title":"A shared class for a family of components","description":"The className option adds a stable opt-in hook alongside the hash, so a parent can style a whole family at once — and it survives extension.","teaches":"When to use a shared class rather than hash interpolation, and the global-stylesheet boundary that comes with it","subsection":true,"frameworks":["react","next","astro"],"keywords":["className option","shared class","chapter heading","stable selector","test hooks","global stylesheet"],"tags":["Scoping","Class Names"],"href":"/react/docs/basics/scoping-and-composition#a-shared-class-for-a-family"},{"type":"docs","priority":0.49999999999999994,"title":"The override ladder","description":"Three rungs for changing a component deliberately: a variant for a named mode, the style prop for a one-off, and a CSS custom property for a reusable knob.","teaches":"Which override tool to reach for, in the order that stays predictable as an app grows","subsection":true,"frameworks":["react","next","astro"],"keywords":["override ladder","variant","style prop","custom property","inline declaration","consumer className"],"tags":["Scoping","Overrides"],"href":"/react/docs/basics/scoping-and-composition#changing-a-component-on-purpose"},{"type":"docs","priority":0.49999999999999994,"title":"Extending a component and the automatic layer bump","description":"Wrapping a styled component inherits its variants and lands the new one in the next cascade layer, so it wins without a specificity trick.","teaches":"How composition works in Salty and when a wrapped component needs passProps to keep a real HTML attribute","subsection":true,"frameworks":["react","next","astro"],"keywords":["extending","wrapping","layer bump","inherit variants","passProps","next link"],"tags":["Scoping","Composition"],"href":"/react/docs/basics/scoping-and-composition#composition-extend-a-component"},{"type":"docs","priority":0.49999999999999994,"title":"Cascade layers and precedence","description":"Salty emits every rule into a fixed layer hierarchy, so layer order outranks specificity and priority works like z-index for the cascade.","teaches":"How the layer hierarchy decides ties, and how priority resolves a stubborn one deterministically","subsection":true,"frameworks":["react","next","astro"],"keywords":["cascade layers","layer order","priority","source order","hash collision","specificity"],"tags":["Scoping","Cascade Layers"],"href":"/react/docs/basics/scoping-and-composition#how-precedence-is-decided"},{"type":"docs","priority":0.49999999999999994,"title":"When to reach for runtime styles","description":"A four-rung ladder from build-time styles to per-frame inline styles, and the two cases that actually drove the feature.","teaches":"Which rung a styling problem belongs on, and why an inline style is not a substitute","subsection":true,"frameworks":["react","next","astro"],"keywords":["ladder","prop tokens","profile customization","one-off override","inline style","same parser"],"tags":["Runtime Styles","Decisions"],"href":"/react/docs/basics/runtime-styles#when-you-reach-for-it"},{"type":"docs","priority":0.49999999999999994,"title":"The runtime loop","description":"Setting up a runtime in a plain .ts file, resolving a style object per request, and rendering the class and CSS together.","teaches":"How to wire defineRuntime, why the config argument matters, and what resolve returns","subsection":true,"frameworks":["react","next","astro"],"keywords":["defineRuntime","resolve","plain ts file","config","deterministic hash","scope"],"tags":["Runtime Styles","API"],"href":"/react/docs/basics/runtime-styles#example-1-the-loop"},{"type":"docs","priority":0.49999999999999994,"title":"Profile customization with runtime styles","description":"Building the style object yourself from validated fields, mixing your own tokens with a person's choices, and deduping when a page renders many modules.","teaches":"The habit that keeps runtime styles safe and maintainable, and when theming is the better tool instead","subsection":true,"frameworks":["react","next","astro"],"keywords":["profile styles","validated fields","dedupe","hash key","named looks","conditional group"],"tags":["Runtime Styles","Patterns"],"href":"/react/docs/basics/runtime-styles#example-2-profile-customization"},{"type":"docs","priority":0.49999999999999994,"title":"One-off overrides in a systematic layout","description":"Resolving a deviation for a single block instance, and the crucial detail that runtime CSS is emitted without a cascade layer.","teaches":"How to make a deliberate one-off deviation as data, and why runtime rules outrank every layered rule","subsection":true,"frameworks":["react","next","astro"],"keywords":["block overrides","styleOverride","unlayered","trump card","named breakpoints","cms"],"tags":["Runtime Styles","Cascade Layers"],"href":"/react/docs/basics/runtime-styles#example-3-a-one-off-override"},{"type":"docs","priority":0.49999999999999994,"title":"Runtime feature support","description":"Most of the authoring surface works unchanged; the exceptions are the things that need a component wrapper or a place in the static stylesheet.","teaches":"Which Salty features survive the runtime path and which do not, including the variants trap","subsection":true,"frameworks":["react","next","astro"],"keywords":["feature support","tokens","media queries","templates","variants trap","keyframes"],"tags":["Runtime Styles","Reference"],"href":"/react/docs/basics/runtime-styles#what-comes-along-and-what-doesnt"},{"type":"docs","priority":0.49999999999999994,"title":"Runtime styles and untrusted input","description":"Salty deliberately does not sanitize runtime style input, which makes the validation boundary yours — and a style object is more powerful than it looks.","teaches":"Why sanitization is left to you and the four habits that keep runtime styles safe","subsection":true,"frameworks":["react","next","astro"],"keywords":["security","sanitization","untrusted input","allowlist","set:html","threat model"],"tags":["Runtime Styles","Security"],"href":"/react/docs/basics/runtime-styles#security-a-note-before-you-ship-it"},{"type":"docs","priority":0.49999999999999994,"title":"Render the element the job calls for","description":"Heading level is document structure and font size is a visual decision — styled keeps them as two separate knobs, and a link is not a button.","teaches":"How to decouple tag from appearance with as, element and component wrapping","subsection":true,"frameworks":["react","next","astro"],"keywords":["as prop","element option","heading level","link versus button","passProps","document outline"],"tags":["Accessibility","Semantics"],"href":"/react/docs/basics/accessibility#render-the-right-element"},{"type":"docs","priority":0.49999999999999994,"title":"Semantic wrappers with no layout cost","description":"display: contents removes an element box while leaving its children in the flow — the layout stops seeing the wrapper, the accessibility tree keeps it.","teaches":"How to keep a list a list inside a grid, and the three sharp edges of display: contents","subsection":true,"frameworks":["react","next","astro"],"keywords":["display contents","role=list","card grid","safari list bug","fieldset","accessibility tree"],"tags":["Accessibility","Semantics"],"href":"/react/docs/basics/accessibility#semantic-wrappers"},{"type":"docs","priority":0.49999999999999994,"title":"Bind attributes to the component","description":"defaultProps sets HTML attributes that pass straight through — an attribute in the atom definition is an attribute nobody can forget.","teaches":"Which attributes are worth binding, and the defaultProps versus defaultVariants distinction","subsection":true,"frameworks":["react","next","astro"],"keywords":["defaultProps","type button","aria-hidden","role list","accessible name","icon button"],"tags":["Accessibility","Components"],"href":"/react/docs/basics/accessibility#bind-the-attribute"},{"type":"docs","priority":0.49999999999999994,"title":"Style off the ARIA attribute so it can't drift","description":"Make the attribute assistive tech reads the same attribute your CSS keys off, and the visual state and the announced state physically cannot disagree.","teaches":"The pattern that makes a missing ARIA attribute visible in thirty seconds, and why no ARIA beats bad ARIA","subsection":true,"frameworks":["react","next","astro"],"keywords":["aria-expanded","aria-current","aria-pressed","disclosure","variant trap","native state"],"tags":["Accessibility","ARIA"],"href":"/react/docs/basics/accessibility#style-off-the-aria-attribute"},{"type":"docs","priority":0.49999999999999994,"title":"Hover and focus in the same rule","description":"Reveal-on-hover is the most common way a keyboard user gets locked out — :focus-within is the keyboard equivalent, and opacity rather than display is what makes it work.","teaches":"How to reveal actions to both audiences in one rule, and why the focus ring itself needs :focus-visible","subsection":true,"frameworks":["react","next","astro"],"keywords":["focus-within","where selector","forgiving selector list","opacity","tab order","focus-visible"],"tags":["Accessibility","Focus"],"href":"/react/docs/basics/accessibility#hover-and-focus"},{"type":"docs","priority":0.49999999999999994,"title":"Respecting a reduced-motion preference","description":"A named query per component plus a global backstop that deliberately uses !important — because in the global layer, layer inversion is the mechanism.","teaches":"Why 0.01ms rather than none, why the !important is intentional here, and what the preference actually means","subsection":true,"frameworks":["react","next","astro"],"keywords":["prefers-reduced-motion","global backstop","animationend","important inversion","vestibular","cross-fade"],"tags":["Accessibility","Motion"],"href":"/react/docs/basics/accessibility#turn-motion-off"},{"type":"docs","priority":0.49999999999999994,"title":"Deriving a legible colour variant","description":"One grey doing four jobs is the everyday bug — derive the legible variant from the same source, and be clear that color() does not compute contrast ratios.","teaches":"How to keep a derived colour tied to its source, and the contrast thresholds worth knowing","subsection":true,"frameworks":["react","next","astro"],"keywords":["color helper","darken","contrast ratio","4.5:1","muted text","build-time boundary"],"tags":["Accessibility","Colour"],"href":"/react/docs/basics/accessibility#nudging-a-color"},{"type":"docs","priority":0.49999999999999994,"title":"prefers-contrast versus forced-colors","description":"One asks for more contrast in your palette; the other replaces your colours with the OS palette entirely. They behave nothing alike.","teaches":"Which scope each belongs in, and how to survive forced colours with a transparent border","subsection":true,"frameworks":["react","next","astro"],"keywords":["prefers-contrast","forced-colors","system colors","ButtonBorder","forced-color-adjust","responsive scope"],"tags":["Accessibility","Contrast"],"href":"/react/docs/basics/accessibility#high-contrast"},{"type":"docs","priority":0.49999999999999994,"title":"Zoom, rem sizing, and the clamp floor","description":"vw units do not respond to page zoom, which makes a clamp minMultiplier the thing standing between a fluid type scale and an unzoomable one.","teaches":"Why rem sizing follows the user setting, and the non-obvious zoom behaviour of viewport units","subsection":true,"frameworks":["react","next","astro"],"keywords":["rem","page zoom","vw units","clamp floor","minMultiplier","200% zoom","320px"],"tags":["Accessibility","Zoom"],"href":"/react/docs/basics/accessibility#zoom-and-the-floor"},{"type":"docs","priority":0.49999999999999994,"title":"The generated type layer","description":"Tokens, breakpoints and templates declared the normal way show up in the editor, because the compiler writes a declaration file describing them on every build.","teaches":"Where Salty autocomplete comes from and the two consequences of it following the build","subsection":true,"frameworks":["react","next","astro"],"keywords":["generated types","declaration file","autocomplete","typed variants","stale types","prepare script"],"tags":["Tooling","TypeScript"],"href":"/react/docs/basics/tooling#typescript-types-you-didnt-write"},{"type":"docs","priority":0.49999999999999994,"title":"The CLI in daily use","description":"Four commands, what init touches in full, the .saltyrc.json that shortens every other command, and when build earns its place.","teaches":"What each command is for day to day and the two honest caveats about init","subsection":true,"frameworks":["react","next","astro"],"keywords":["init","generate","build","update","saltyrc","npm only","monorepo"],"tags":["Tooling","CLI"],"href":"/react/docs/basics/tooling#the-cli"},{"type":"docs","priority":0.49999999999999994,"title":"The two ESLint rules","description":"must-be-exported and no-variants-in-base — two failures that are perfectly valid TypeScript and produce the wrong thing, or nothing.","teaches":"What each rule catches, why the failure modes are so confusing, and what the plugin deliberately does not do","subsection":true,"frameworks":["react","next","astro"],"keywords":["must-be-exported","no-variants-in-base","autofix","flat config","eslint-config-core","small surface"],"tags":["Tooling","Linting"],"href":"/react/docs/basics/tooling#eslint-the-two-rules"},{"type":"docs","priority":0.49999999999999994,"title":"What to assert on in an automated test","description":"A test runner sees class names and attributes, not resolved styles — so unit tests are for behaviour and structure, and browsers are for appearance.","teaches":"Why the hash is not a test target and which three consequences of content-addressing break tests","subsection":true,"frameworks":["react","next","astro"],"keywords":["test runner","jsdom","cascade layers","content-addressed hash","snapshots","deduplication"],"tags":["Testing","Assertions"],"href":"/react/docs/basics/testing#automated-tests"},{"type":"docs","priority":0.49999999999999994,"title":"Reading Salty output in the browser","description":"Component names in the tree, two classes rather than forty, the layer view that answers most override questions, live custom properties, and forcing states DevTools can emulate.","teaches":"How to debug a Salty style with nothing but the browser you already have open","subsection":true,"frameworks":["react","next","astro"],"keywords":["data-component-name","displayName","variant classes","layer view","root tokens","force state"],"tags":["Testing","DevTools"],"href":"/react/docs/basics/testing#reading-your-output-in-the-browser"},{"type":"docs","priority":0.49999999999999994,"title":"Checking the build without running the app","description":"Build, then read the file — a named text artifact in seconds beats starting a dev server and reasoning about what probably rendered.","teaches":"How to verify compiled output directly, and why the per-component file is the useful one","subsection":true,"frameworks":["react","next","astro"],"keywords":["salty-css build","saltygen","per-component file","mode production","ai assistant","implementation detail"],"tags":["Testing","Build Output"],"href":"/react/docs/basics/testing#checking-the-build"},{"type":"docs","priority":0.49999999999999994,"title":"What a style payload can actually do","description":"The old remote-code tricks are dead, but CSS still makes network requests, owns the interface, and can stop being CSS if a payload escapes its style element.","teaches":"How to calibrate the real risk of an untrusted style payload","subsection":true,"frameworks":["react","next","astro"],"keywords":["url()","beacon","attribute selectors","fixed position","content property","style escape"],"tags":["Security","Threat Model"],"href":"/react/docs/basics/security#what-a-style-object-can-do"},{"type":"docs","priority":0.49999999999999994,"title":"Securing runtime styles","description":"defineRuntime does not sanitize, deliberately — so build the style object yourself from validated fields, and watch the scope argument, the raw-HTML sinks and the payload size.","teaches":"The validation pattern that makes user-supplied styles safe, and the four edges around the API","subsection":true,"frameworks":["react","next","astro"],"keywords":["defineRuntime","allowlist","validation","scope selector","set:html","payload size","threat model"],"tags":["Security","Runtime Styles"],"href":"/react/docs/basics/security#runtime-styles"},{"type":"docs","priority":0.49999999999999994,"title":"Prop tokens and user-supplied values","description":"A prop token is narrower by construction — a user can fill a slot but not add a property — yet a valid CSS value can still make every visitor fetch from a host somebody else picked.","teaches":"Why narrower is not closed, and when theming removes the problem entirely","subsection":true,"frameworks":["react","next","astro"],"keywords":["prop tokens","css-bg","url value","validate the shape","conditional group","style prop"],"tags":["Security","Prop Tokens"],"href":"/react/docs/basics/security#prop-tokens"},{"type":"docs","priority":0.49999999999999994,"title":"Remote stylesheets and fonts","description":"Imported CSS has the same powers as yours, the host can change it at any time, and @import cannot carry an integrity hash.","teaches":"Why self-hosting is the default recommendation and where Subresource Integrity does and does not apply","subsection":true,"frameworks":["react","next","astro"],"keywords":["defineImport","remote stylesheet","google fonts","subresource integrity","self-host","privacy"],"tags":["Security","Imports"],"href":"/react/docs/basics/security#css-from-somebody-elses-server"},{"type":"docs","priority":0.49999999999999994,"title":"The build is code, and its output is public","description":"Style files execute during the build with whatever environment that process has — and everything the compiler emits is served to every visitor.","teaches":"How to treat .css.ts files as programs and what not to interpolate into a value at build time","subsection":true,"frameworks":["react","next","astro"],"keywords":["build time execution","lockfile","pull request ci","public output","api key","data-component-name"],"tags":["Security","Build"],"href":"/react/docs/basics/security#your-build-is-code"},{"type":"docs","priority":0.49999999999999994,"title":"Content Security Policy","description":"One static stylesheet on your own origin means style-src self covers ordinary Salty — two features need accommodation, and CSP is also the best mitigation for untrusted styles.","teaches":"Which Salty features a strict CSP affects and how to use CSP as a mitigation rather than only an obstacle","subsection":true,"frameworks":["react","next","astro"],"keywords":["csp","style-src","style-src-attr","nonce","unsafe-inline","dev server caveat"],"tags":["Security","CSP"],"href":"/react/docs/basics/security#content-security-policy"},{"type":"docs","priority":0.49999999999999994,"title":"Deconstructing className parameters","description":"The anatomy of a className() call: the optional stable class name, base styles and variant axes, and the chainable value it returns.","teaches":"What each option in the className() options object does and how the returned value carries .variant() with it","subsection":true,"frameworks":["react","next","astro"],"keywords":["className options","base","variants","variant chain","String object","defaultVariants","css.ts"],"tags":["Class Names","API"],"href":"/react/docs/basics/class-names#deconstructing-classname-parameters"},{"type":"docs","priority":0.49999999999999994,"title":"Handing a class to markup you don't own","description":"Styling a third-party component with several class-name slots, where a styled wrapper only ever reaches the outer one.","teaches":"How to style a third-party component that exposes multiple class-name slots driven by its own state","subsection":true,"frameworks":["react","next","astro"],"keywords":["third-party components","react-select","class slots","unstyled","clsx","library state"],"tags":["Class Names","Third-Party"],"href":"/react/docs/basics/class-names#example-1-handing-a-class-to-markup-you-dont-own"},{"type":"docs","priority":0.49999999999999994,"title":"Applying a class to DOM you didn't render","description":"Attaching a Salty class to markup injected by a script or a widget, and the split between state your code owns and state the browser already tracks.","teaches":"How to apply and swap Salty classes on plain DOM, and which states never need a variant","subsection":true,"frameworks":["react","next","astro"],"keywords":["plain DOM","querySelector","classList","widget","browser state","tree shaking"],"tags":["Class Names","Plain DOM"],"href":"/react/docs/basics/class-names#example-2-no-components-in-sight"},{"type":"docs","priority":0.49999999999999994,"title":"Frameworks without a styled","description":"Why styled is the only framework-specific API, and how className becomes the authoring API everywhere else.","teaches":"How to use Salty CSS on a framework that has no styled package, and what stays unchanged when you do","subsection":true,"frameworks":["react","next","astro"],"keywords":["framework agnostic","vue","svelte","angular","core package","class binding"],"tags":["Class Names","Framework Agnostic"],"href":"/react/docs/basics/class-names#frameworks-without-a-styled"},{"type":"docs","priority":0.49999999999999994,"title":"What className doesn't do","description":"The four component ergonomics className deliberately lacks — extending, element and prop forwarding, automatic defaults, and css-* prop tokens.","teaches":"Which capabilities require a component, and the workarounds when a class string is what you have","subsection":true,"frameworks":["react","next","astro"],"keywords":["limitations","extending","defaultProps","passProps","css props","custom properties"],"tags":["Class Names","Limitations"],"href":"/react/docs/basics/class-names#what-classname-doesnt-do"},{"type":"docs","priority":0.49999999999999994,"title":"A value held in a variable","description":"Naming a value in a local const and composing with it — read while the file compiles, so the variable has vanished by the time anything ships.","teaches":"How a local const behaves in a style file and where the line between a const and a real token sits","subsection":true,"frameworks":["react","next","astro"],"keywords":["const","template strings","authoring convenience","build time","design token boundary"],"tags":["Dynamic Values","Build Time"],"href":"/react/docs/basics/dynamic-values#example-1-a-value-held-in-a-variable"},{"type":"docs","priority":0.49999999999999994,"title":"A value that stays a CSS variable","description":"Authoring a real custom property with a build-time fallback, so a parent can set the variable and repaint children through the cascade.","teaches":"How to leave a per-instance knob open without adding a variant or changing the component","subsection":true,"frameworks":["react","next","astro"],"keywords":["custom property","var fallback","cascade","parent sets variable","per-instance knob"],"tags":["Dynamic Values","Custom Properties"],"href":"/react/docs/basics/dynamic-values#example-2-a-value-that-stays-a-css-variable"},{"type":"docs","priority":0.49999999999999994,"title":"A computed value, even an async one","description":"A style value can be a function Salty awaits at build time — so a CMS or design-system endpoint can drive your CSS, once, frozen into the stylesheet.","teaches":"What async actually means here, and why the fetched value is identical for every visitor","subsection":true,"frameworks":["react","next","astro"],"keywords":["async","fetch","build time","headless cms","design tokens","frozen value"],"tags":["Dynamic Values","Build Time"],"href":"/react/docs/basics/dynamic-values#example-3-a-computed-value"},{"type":"docs","priority":0.49999999999999994,"title":"Sharing values across files","description":"Importing a plain module into a style file works exactly as if the value were local — with one warning about what else comes along for the ride.","teaches":"How to share values between style files and when an import genuinely threatens the build","subsection":true,"frameworks":["react","next","astro"],"keywords":["imports","shared palette","build evaluation","heavy dependencies","window","lightweight helper"],"tags":["Dynamic Values","Build Time"],"href":"/react/docs/basics/dynamic-values#example-4-sharing-values-across-files"},{"type":"docs","priority":0.49999999999999994,"title":"Values the consumer sets","description":"Typed {props.X} tokens expose a css-* prop and wire the value through a CSS variable — the one mechanism here that stays live in the browser.","teaches":"How prop tokens work end to end, and when to prefer them over a hand-rolled custom property","subsection":true,"frameworks":["react","next","astro"],"keywords":["prop tokens","css-bg","props.X","typed contract","dash-case","stripped props"],"tags":["Dynamic Values","Prop Tokens"],"href":"/react/docs/basics/dynamic-values#example-5-values-the-consumer-sets"},{"type":"docs","priority":0.49999999999999994,"title":"State the browser already tracks","description":"The first rung: pseudo-classes, native attributes and relational selectors, all nested with & and scoped to the component hash.","teaches":"Which interactive states need no JavaScript at all, and how to nest their selectors in a Salty component","subsection":true,"frameworks":["react","next","astro"],"keywords":["pseudo-classes","hover","focus-within","user-invalid","has","details","aria-current","no javascript"],"tags":["Interactive State","Platform"],"href":"/react/docs/basics/interactive-state#example-1-state-the-browser-already-tracks"},{"type":"docs","priority":0.49999999999999994,"title":"Lifting app state to a variant","description":"Modelling a closed set of app modes as a variant axis driven by React state, with the browser-tracked states left where they belong.","teaches":"How to model app state the browser cannot see as a variant axis, and where the boundary with state management sits","subsection":true,"frameworks":["react","next","astro"],"keywords":["status variant","submitting","react state","boolean variant","defaultVariants","form state"],"tags":["Interactive State","Variants"],"href":"/react/docs/basics/interactive-state#example-2-app-state-lift-it-to-a-variant"},{"type":"docs","priority":0.49999999999999994,"title":"Open-ended state values with prop tokens","description":"When the state is a continuous value rather than a closed set, {props.X} exposes a typed css-* prop wired through a live CSS variable.","teaches":"How to style a continuously changing value with a prop token, and how the token maps to a JSX prop","subsection":true,"frameworks":["react","next","astro"],"keywords":["prop tokens","props.X","css-value","progress","live css variable","camelCase to dash-case"],"tags":["Interactive State","Prop Tokens"],"href":"/react/docs/basics/interactive-state#example-3-open-ended-state-values"},{"type":"docs","priority":0.49999999999999994,"title":"Theming as perceived state","description":"When a whole region changes state, a conditional group pointed at a state axis repaints everything beneath one attribute — no prop drilling, no re-render.","teaches":"How to use the theming mechanism for region-level state, and why a separate group keeps the axes orthogonal","subsection":true,"frameworks":["react","next","astro"],"keywords":["conditional group","data-mode","region state","edit mode","orthogonal axes","query handle"],"tags":["Interactive State","Theming"],"href":"/react/docs/basics/interactive-state#example-4-theming-as-perceived-state"},{"type":"docs","priority":0.49999999999999994,"title":"Why a variant, and not something else","description":"Variants compared against a second component, a style object computed at render, and a loose class name — plus the cost of compiling every declared value.","teaches":"Why variants are the right tool for a closed set of style branches, and what they cost in stylesheet size","subsection":true,"frameworks":["react","next","astro"],"keywords":["why variants","component explosion","inline styles","typed props","dead css","axes"],"tags":["Variants","Philosophy"],"href":"/react/docs/basics/variants#why-a-variant-and-not-something-else"},{"type":"docs","priority":0.49999999999999994,"title":"The five variant keys and the three APIs","description":"The keys that mean the same thing on styled, className and defineTemplates, and the one thing that differs — how a branch gets switched on.","teaches":"The five shared variant keys and how activation differs between the three APIs that accept them","subsection":true,"frameworks":["react","next","astro"],"keywords":["variants key","defaultVariants","compoundVariants","anyOfVariants","boolean variant","activation"],"tags":["Variants","API"],"href":"/react/docs/basics/variants#the-shape-once"},{"type":"docs","priority":0.49999999999999994,"title":"Variants as typed props on styled","description":"Two axes and a boolean flag on a button, the defaults that fill in the gaps, and why variant props never reach the DOM.","teaches":"How to declare variant axes on a styled component and how they behave as typed JSX props","subsection":true,"frameworks":["react","next","astro"],"keywords":["typed props","boolean variant","defaultVariants","button component","DOM attributes"],"tags":["Variants","Styled Components"],"href":"/react/docs/basics/variants#example-1-variants-as-typed-props-on-styled"},{"type":"docs","priority":0.49999999999999994,"title":"The same axes with className","description":"The identical options object activated by chaining .variant() instead of passing a prop, and the defaults gap that comes with it.","teaches":"How variants are activated without a component, and why className does not apply defaultVariants","subsection":true,"frameworks":["react","next","astro"],"keywords":["className","variant chain","immutable","defaultVariants gap","class string"],"tags":["Variants","Class Names"],"href":"/react/docs/basics/variants#example-2-the-same-axes-no-component"},{"type":"docs","priority":0.49999999999999994,"title":"Variants inside a template","description":"Giving a template node its own variant axis so every text style in the project inherits it, and the string or object call-site forms.","teaches":"How template nodes carry variants and how leaf inheritance works across a design system","subsection":true,"frameworks":["react","next","astro"],"keywords":["defineTemplates","template variants","textStyle","leaf inheritance","design system"],"tags":["Variants","Templates"],"href":"/react/docs/basics/variants#example-3-variants-inside-a-template"},{"type":"docs","priority":0.49999999999999994,"title":"Combining axes with compoundVariants and anyOfVariants","description":"AND rules for a specific combination, OR rules for a shared baseline, and the zero specificity that makes anyOfVariants always losable.","teaches":"When to reach for compoundVariants versus anyOfVariants and how their precedence resolves","subsection":true,"frameworks":["react","next","astro"],"keywords":["compoundVariants","anyOfVariants","where selector","zero specificity","orthogonal axes","cascade"],"tags":["Variants","Cascade Layers"],"href":"/react/docs/basics/variants#combining-axes-and-or-and-who-wins"},{"type":"docs","priority":0.49999999999999994,"title":"The limits of variants","description":"Closed sets only, not duplicating state the browser already tracks, axis multiplication, the unrelated defineFont variants, and where state management stops being Salty's business.","teaches":"Where the variant model stops working and which API takes over at each boundary","subsection":true,"frameworks":["react","next","astro"],"keywords":["closed set","dynamic values","disabled trap","passProps","defineFont","axis explosion","runtime styles"],"tags":["Variants","Limitations"],"href":"/react/docs/basics/variants#how-far-to-take-it"},{"type":"docs","priority":0.49999999999999994,"title":"Static tokens: the core case","description":"Defining values once with defineVariables, referencing them by path, and what the compiler writes onto :root.","teaches":"How to define and reference static design tokens, and how the paths become dashed custom properties","subsection":true,"frameworks":["react","next","astro"],"keywords":["defineVariables","static tokens","root","token path","build-time validation","token naming"],"tags":["Variables","Tokens"],"href":"/react/docs/basics/variables#example-1-static-tokens"},{"type":"docs","priority":0.49999999999999994,"title":"A different token value per breakpoint","description":"The responsive scope: one token name whose value is swapped by a media query, with no @media block at the call site.","teaches":"How to define responsive tokens that change value across breakpoints while the reference stays identical","subsection":true,"frameworks":["react","next","astro"],"keywords":["responsive scope","defineMediaQuery","breakpoints","base tokens","gutter","clamp"],"tags":["Variables","Responsive"],"href":"/react/docs/basics/variables#example-2-responsive-tokens"},{"type":"docs","priority":0.49999999999999994,"title":"A different token value per context","description":"The conditional scope: swapping a token value when an ancestor selector matches, which is the mechanism theming is built on.","teaches":"How conditional tokens repaint a whole tree from one attribute, with no re-render and no component changes","subsection":true,"frameworks":["react","next","astro"],"keywords":["conditional scope","data-theme","theme group","dark mode","ancestor selector","native cascade"],"tags":["Variables","Theming"],"href":"/react/docs/basics/variables#example-3-conditional-tokens"},{"type":"docs","priority":0.49999999999999994,"title":"Mixing scopes, and the build-graph gotcha","description":"All three scopes merge into one namespace and can be freely mixed — but a standalone defineVariables file only takes effect if something imports it.","teaches":"How to combine static, responsive and conditional tokens, and why unimported token files silently do nothing","subsection":true,"frameworks":["react","next","astro"],"keywords":["mixing scopes","build graph","unresolved token","styles barrel","defineConfig variables"],"tags":["Variables","Troubleshooting"],"href":"/react/docs/basics/variables#mixing-scopes-and-one-gotcha"},{"type":"docs","priority":0.49999999999999994,"title":"Sharing tokens in a monorepo","description":"Tokens are plain TypeScript exports, so a shared package can be one source of truth across apps — as long as it stays light.","teaches":"How to share one token source across a monorepo without dragging heavy dependencies into every build","subsection":true,"frameworks":["react","next","astro"],"keywords":["monorepo","shared tokens","token package","build-time evaluation","source of truth"],"tags":["Variables","Monorepo"],"href":"/react/docs/basics/variables#sharing-tokens-in-a-monorepo"},{"type":"docs","priority":0.49999999999999994,"title":"How theming works","description":"The vocabulary split between variables and theming, the atoms-and-molecules model, and the two scopes that decide how a theme switches.","teaches":"The mental model behind Salty theming and which scope to reach for based on who does the switching","subsection":true,"frameworks":["react","next","astro"],"keywords":["atoms and molecules","conditional scope","responsive scope","role-named tokens","color boundary"],"tags":["Theming","Concepts"],"href":"/react/docs/basics/theming#how-theming-works-briefly"},{"type":"docs","priority":0.49999999999999994,"title":"Light and dark: the core mechanism","description":"The compiled CSS a light/dark pair produces, then the authoring loop behind it: atoms, molecules, consume, activate.","teaches":"The full theming loop from palette to attribute, and why switching a theme causes no re-render","subsection":true,"frameworks":["react","next","astro"],"keywords":["light and dark","data-theme","atoms","molecules","native cascade","defineVariables"],"tags":["Theming","Dark Mode"],"href":"/react/docs/basics/theming#example-1-light-and-dark"},{"type":"docs","priority":0.49999999999999994,"title":"Many values per theme","description":"Named profile looks as modes in one conditional group, and the two habits that keep richer themes from going wrong.","teaches":"How to model a coordinated set of many molecules per theme, and which values should stay theme-agnostic","subsection":true,"frameworks":["react","next","astro"],"keywords":["profile themes","named looks","many molecules","role translation","theme-agnostic type","personal web"],"tags":["Theming","Design Systems"],"href":"/react/docs/basics/theming#example-2-many-values-per-theme"},{"type":"docs","priority":0.49999999999999994,"title":"Nesting themes and independent groups","description":"Themes nest for free because every element reads the nearest ancestor carrying the attribute — and a separate group gives you a second axis without writing out combinations.","teaches":"How to nest themes and when to reach for a second conditional group instead of nesting","subsection":true,"frameworks":["react","next","astro"],"keywords":["nested themes","nearest ancestor","sub-theme","independent axes","buttonTheme","orthogonal groups"],"tags":["Theming","Composition"],"href":"/react/docs/basics/theming#example-3-themes-within-themes"},{"type":"docs","priority":0.49999999999999994,"title":"Automatic light and dark from the OS","description":"The responsive scope keyed to prefers-color-scheme, where the browser resolves the preference before first paint and the consumption side is unchanged.","teaches":"How to follow the operating system colour preference with no JavaScript, and what you give up by doing so","subsection":true,"frameworks":["react","next","astro"],"keywords":["prefers-color-scheme","responsive scope","defineMediaQuery","no flash","os preference","user override"],"tags":["Theming","Responsive"],"href":"/react/docs/basics/theming#example-4-automatic-light-and-dark"},{"type":"docs","priority":0.49999999999999994,"title":"How global styles work","description":"Two places to declare them, the same shape either way, and the stranded-file gotcha that makes a global silently do nothing.","teaches":"How to declare global styles and why a global that never reaches the build graph produces no CSS","subsection":true,"frameworks":["react","next","astro"],"keywords":["defineGlobalStyles","defineConfig global","build graph","stranded file","export"],"tags":["Global Styles","Setup"],"href":"/react/docs/basics/global-styles#how-global-styles-work-briefly"},{"type":"docs","priority":0.49999999999999994,"title":"A realistic global base","description":"Document-level styles plus a nested selector, using tokens — and the fact that there is nothing to import at the call site.","teaches":"What a real global styles file looks like and why global styles have no call site","subsection":true,"frameworks":["react","next","astro"],"keywords":["document base","html body","nested selectors","tokens","no call site"],"tags":["Global Styles","Example"],"href":"/react/docs/basics/global-styles#define-once-applies-everywhere"},{"type":"docs","priority":0.49999999999999994,"title":"Document-wide utility classes","description":"A global key can be any selector including a class — fine for a small stable set of document-wide helpers, wrong for a utility system.","teaches":"When a utility class earns its place in a global and when className or a template is the right tool","subsection":true,"frameworks":["react","next","astro"],"keywords":["utility classes","sr-only","list reset","visually hidden","small and stable"],"tags":["Global Styles","Utilities"],"href":"/react/docs/basics/global-styles#a-pragmatic-utility-or-two"},{"type":"docs","priority":0.49999999999999994,"title":"What belongs in a global","description":"Good fits are document base, bare-element defaults, print styles and reset tweaks. Not this: styling components you own, or trying to override one.","teaches":"The rule of thumb for deciding whether a rule belongs in a global at all","subsection":true,"frameworks":["react","next","astro"],"keywords":["good fits","document base","print styles","leaking","priority","rule of thumb"],"tags":["Global Styles","Decisions"],"href":"/react/docs/basics/global-styles#what-global-styles-are-for"},{"type":"docs","priority":0.49999999999999994,"title":"The other global-CSS emitters","description":"Tokens, fonts, templates and third-party imports each have a dedicated factory that lands in the right layer with types and token access.","teaches":"Which factory owns which kind of global CSS, and why reaching for a raw global instead is a wrong turn","subsection":true,"frameworks":["react","next","astro"],"keywords":["defineVariables","defineFont","defineTemplates","defineImport","imports layer","dedicated factories"],"tags":["Global Styles","Factories"],"href":"/react/docs/basics/global-styles#not-the-only-global-css"},{"type":"docs","priority":0.49999999999999994,"title":"The built-in reset, briefly","description":"What Salty's small default reset does, and the reset option for turning it off or replacing it.","teaches":"What the built-in reset covers and how to bring your own instead","subsection":true,"frameworks":["react","next","astro"],"keywords":["reset","border-box","text-wrap","reset none","custom reset","defineConfig"],"tags":["Global Styles","Reset"],"href":"/react/docs/basics/global-styles#the-built-in-reset"},{"type":"docs","priority":0.49999999999999994,"title":"defineFont versus defineImport","description":"Both bring outside CSS into the build; the difference is how much Salty knows about what you handed it, and where the result lands in the cascade.","teaches":"Which of the two factories to reach for, and why imports always lose to your own styles","subsection":true,"frameworks":["react","next","astro"],"keywords":["defineFont","defineImport","imports layer","overlap","rule of thumb","cascade"],"tags":["Fonts","Concepts"],"href":"/react/docs/basics/fonts#how-the-two-apis-fit"},{"type":"docs","priority":0.49999999999999994,"title":"Registering a local font","description":"A variants array with one entry per @font-face rule, the src, fallback and display inputs, and the four members the returned object exposes.","teaches":"How to register self-hosted font files and the several ways to consume the result","subsection":true,"frameworks":["react","next","astro"],"keywords":["variants array","src","fallback","font-display","variable","className","stringifies"],"tags":["Fonts","Setup"],"href":"/react/docs/basics/fonts#example-1-a-local-font"},{"type":"docs","priority":0.49999999999999994,"title":"Hosted fonts and the fontFamily token","description":"Loading a font that ships its own stylesheet with the import option, and pairing defineFont with defineVariables so components reference a role rather than a typeface.","teaches":"How to load a remote font sheet and the indirection that makes a typeface swappable","subsection":true,"frameworks":["react","next","astro"],"keywords":["hosted font","google fonts","import option","fontFamily token","role not typeface","swappable"],"tags":["Fonts","Tokens"],"href":"/react/docs/basics/fonts#example-2-a-hosted-font"},{"type":"docs","priority":0.49999999999999994,"title":"Font loading practices Salty leaves to you","description":"Whether to lean on a framework loader, and the seven @font-face practices that cover most of the gap when you own the setup instead.","teaches":"What Salty does not optimize for you and which font-delivery practices matter most","subsection":true,"frameworks":["react","next","astro"],"keywords":["woff2","font-display","preload","metric overrides","unicodeRange","cors","next/font"],"tags":["Fonts","Performance"],"href":"/react/docs/basics/fonts#getting-font-face-right-yourself"},{"type":"docs","priority":0.49999999999999994,"title":"Pulling in any stylesheet with defineImport","description":"One call and one named export per source, how the path is resolved, and the warning about stacking a third-party reset on top of Salty own.","teaches":"How to import external CSS into a Salty build and what to check before adding a reset","subsection":true,"frameworks":["react","next","astro"],"keywords":["defineImport","npm package","relative path","remote sheet","double reset","build graph"],"tags":["Imports","Setup"],"href":"/react/docs/basics/fonts#define-import"},{"type":"docs","priority":0.49999999999999994,"title":"Installing Salty CSS","description":"One command reads your package.json, installs the right packages, writes the config and wires the plugin — and the real compatibility question is your bundler, not your framework.","teaches":"What init does for you and where the supported-stack line actually falls","subsection":true,"frameworks":["react","next","astro"],"keywords":["salty-css init","saltygen","gitignore","bundler","vite or webpack"],"tags":["Get Started","Setup"],"href":"/react/docs/getting-started/basic-setup#install"},{"type":"docs","priority":0.49999999999999994,"title":"Your first component","description":"A styled button, the two rules that quietly decide whether it produces any CSS, and how it is used with nothing to wrap or provide.","teaches":"How to write and use a first Salty component, and the two day-one mistakes","subsection":true,"frameworks":["react","next","astro"],"keywords":["first component","filename suffix","export","generate","stylesheet import","props pass through"],"tags":["Get Started","Styled Components"],"href":"/react/docs/getting-started/basic-setup#your-first-component"},{"type":"docs","priority":0.49999999999999994,"title":"Define, then reference by name","description":"Tokens, breakpoints, templates, fonts and keyframes all follow one shape — and there are exactly five reference syntaxes.","teaches":"The pattern that makes most of the API stop needing to be memorised","subsection":true,"frameworks":["react","next","astro"],"keywords":["define and use","no imports","five syntaxes","token path","at-name","build time"],"tags":["Get Started","API"],"href":"/react/docs/getting-started/api-overview#everything-follows-the-same-two-steps"},{"type":"docs","priority":0.49999999999999994,"title":"The four ways to author styles","description":"styled for a typed component, className for markup you already have, defineGlobalStyles for the document, defineRuntime for request-time values.","teaches":"Which authoring API fits which situation","subsection":true,"frameworks":["react","next","astro"],"keywords":["styled","className","defineGlobalStyles","defineRuntime","nesting","same surface"],"tags":["Get Started","API"],"href":"/react/docs/getting-started/api-overview#getting-styles-onto-something"},{"type":"docs","priority":0.49999999999999994,"title":"The four reuse features","description":"Variables, theming, templates, modifiers and helpers all mean \"don't write this again\" — the difference is what you are reusing.","teaches":"How to tell the reuse features apart, and why theming is worth building in early","subsection":true,"frameworks":["react","next","astro"],"keywords":["defineVariables","theming","defineTemplates","modifiers","helpers","retrofit"],"tags":["Get Started","API"],"href":"/react/docs/getting-started/api-overview#reusing-a-decision"},{"type":"docs","priority":0.49999999999999994,"title":"Reacting to state and environment","description":"Salty's bias: let the platform see the state if it can. A lot of what gets built with React state is something the browser already tracks.","teaches":"Which mechanism handles which kind of change, from media queries down to prop tokens","subsection":true,"frameworks":["react","next","astro"],"keywords":["media queries","container queries","nesting","variants","prop tokens","viewport clamp","aria"],"tags":["Get Started","API"],"href":"/react/docs/getting-started/api-overview#making-styles-react"},{"type":"docs","priority":0.49999999999999994,"title":"Where every symbol is imported from","description":"Almost everything comes from @salty-css/core/* and behaves identically everywhere — styled is the exception, and the react paths are straight re-exports.","teaches":"Which package each export lives in and what that means without React","subsection":true,"frameworks":["react","next","astro"],"keywords":["imports","core","react subpath","re-exports","framework agnostic","styled exception"],"tags":["Get Started","API"],"href":"/react/docs/getting-started/api-overview#where-the-imports-live"},{"type":"docs","priority":0.49999999999999994,"title":"Tie-breakers between overlapping APIs","description":"styled or className, token or template or modifier or helper, variant or prop token or runtime style, theming or runtime styles.","teaches":"How to choose between the four pairs that come up most often","subsection":true,"frameworks":["react","next","astro"],"keywords":["tie-breaker","styled vs className","token vs modifier","variant vs prop token","theming vs runtime"],"tags":["Get Started","Decisions"],"href":"/react/docs/getting-started/api-overview#when-two-could-do-the-job"},{"type":"docs","priority":0.49999999999999994,"title":"What Salty deliberately doesn't include","description":"No layout primitives, no component kit, no sanitization in defineRuntime, and no editor extension or language server.","teaches":"What not to go looking for, and why each omission is deliberate","subsection":true,"frameworks":["react","next","astro"],"keywords":["no component kit","no Box","no Stack","sanitization","no editor extension","reset"],"tags":["Get Started","Scope"],"href":"/react/docs/getting-started/api-overview#whats-not-included"},{"type":"docs","priority":0.49999999999999994,"title":"The config file","description":"salty.config.ts sits next to your bundler config because that is where the plugin looks, and defineConfig exists purely for TypeScript.","teaches":"Where the config file goes and what defineConfig actually does","subsection":true,"frameworks":["react","next","astro"],"keywords":["salty.config.ts","defineConfig","bundler config","blank config","framework subpaths"],"tags":["Get Started","Configuration"],"href":"/react/docs/getting-started/configuration#the-config-file"},{"type":"docs","priority":0.49999999999999994,"title":"The define* factories","description":"Every factory Salty exposes, with a minimal example and the import path that trips people up most.","teaches":"Which factory declares what, and that defineRuntime is not one of them","subsection":true,"frameworks":["react","next","astro"],"keywords":["defineVariables","defineGlobalStyles","defineTemplates","defineMediaQuery","defineFont","keyframes"],"tags":["Get Started","API"],"href":"/react/docs/getting-started/configuration#the-define-factories"},{"type":"docs","priority":0.49999999999999994,"title":"Where the names you choose end up","description":"Token paths become CSS variables, conditional group names become HTML attributes, media query exports become style keys, and template keys become properties.","teaches":"Where each kind of name lands before a few hundred call sites depend on it","subsection":true,"frameworks":["react","next","astro"],"keywords":["naming","css variables","data-theme","attribute names","style keys","role not value"],"tags":["Get Started","Naming"],"href":"/react/docs/getting-started/configuration#naming-is-your-call"},{"type":"docs","priority":0.49999999999999994,"title":"The .saltyrc.json file","description":"The other file init writes: salty.config.ts tells the compiler how to build your CSS, .saltyrc.json tells the CLI where your projects are.","teaches":"What defaultProject buys you and how the file describes a whole monorepo","subsection":true,"frameworks":["react","next","astro"],"keywords":["saltyrc","defaultProject","projects","monorepo","include exclude","schema"],"tags":["Get Started","CLI"],"href":"/react/docs/getting-started/configuration#saltyrc-json"},{"type":"docs","priority":0.49999999999999994,"title":"Why the type layer is generated","description":"Token paths, template paths and media query names autocomplete because the build writes a declaration file your editor reads like any other .d.ts.","teaches":"Where the autocomplete comes from and why no Salty plugin is involved","subsection":true,"frameworks":["react","next","astro"],"keywords":["autocomplete","declaration file","saltygen","typed variants","vscode","webstorm"],"tags":["Get Started","TypeScript"],"href":"/react/docs/getting-started/editor-setup#an-editor-with-real-typescript-support"},{"type":"docs","priority":0.49999999999999994,"title":"The ESLint plugin","description":"Two mistakes are valid TypeScript and invisible to it — an unexported definition, and variants nested inside base. That is the entire reason the plugin exists.","teaches":"How to install the lint config, what each rule catches, and how to autofix on save","subsection":true,"frameworks":["react","next","astro"],"keywords":["eslint-config-core","must-be-exported","no-variants-in-base","flat config","fix on save"],"tags":["Get Started","Linting"],"href":"/react/docs/getting-started/editor-setup#the-eslint-plugin"},{"type":"docs","priority":0.49999999999999994,"title":"The prepare script","description":"A fresh clone starts with no saltygen, and the failure mode is confusing: no token suggestions and an unstyled page on a repo that looks correctly committed.","teaches":"Why a prepare script matters and the two places it still gets skipped","subsection":true,"frameworks":["react","next","astro"],"keywords":["prepare script","fresh clone","ignore-scripts","mixed versions","gitignore","saltyrc"],"tags":["Get Started","Tooling"],"href":"/react/docs/getting-started/editor-setup#scripts-that-keep-generated-files-generated"},{"type":"docs","priority":0.49999999999999994,"title":"The shape of saltygen/","description":"Six directories created up front whether or not they are used — an empty folder is normal, and nothing in here is hand-editable.","teaches":"What each directory in the generated output holds","subsection":true,"frameworks":["react","next","astro"],"keywords":["saltygen","index.css","cache","css","imports","js","types"],"tags":["Get Started","Compiler Output"],"href":"/react/docs/getting-started/file-structure#what-salty-writes"},{"type":"docs","priority":0.49999999999999994,"title":"Tracing a class back to its source","description":"Build first, start at the element, take the hash to the folder — and know that two grep hits is healthy while one is the diagnosis.","teaches":"A backwards workflow from a rendered element to the code that produced it","subsection":true,"frameworks":["react","next","astro"],"keywords":["data-component-name","grep","layer bundle","two hits","debugging workflow","production build"],"tags":["Get Started","Debugging"],"href":"/react/docs/getting-started/file-structure#reading-it-back"},{"type":"docs","priority":0.49999999999999994,"title":"What a full build writes that a save does not","description":"The incremental path never prunes and never runs the config pass, which explains most \"the compiler is ignoring me\" moments.","teaches":"Why deleting a component leaves stale CSS and why config changes need a full rebuild","subsection":true,"frameworks":["react","next","astro"],"keywords":["full build","hmr","incremental","stale rules","config pass","restart dev server"],"tags":["Get Started","Debugging"],"href":"/react/docs/getting-started/file-structure#rebuilds-and-hot-reloads"},{"type":"docs","priority":0.49999999999999994,"title":"What not to do with saltygen/","description":"Don't commit it, don't hand-edit it, and don't build a test on its internals — the layout is implementation detail that can change in a minor release.","teaches":"How to treat the generated folder and what is safe to assert on instead","subsection":true,"frameworks":["react","next","astro"],"keywords":["gitignore","prepare","hand-edit","testing internals","pre-1.0","implementation detail"],"tags":["Get Started","Testing"],"href":"/react/docs/getting-started/file-structure#what-not-to-do-with-saltygen"},{"type":"docs","priority":0.49999999999999994,"title":"Where shared style files live","description":"A /styles folder split by what each file defines, and the rule that the compiler finds files by suffix rather than by import.","teaches":"The one layout decision and the two quiet failure modes that come before any of the APIs","subsection":true,"frameworks":["react","next","astro"],"keywords":["styles folder","suffix","top-level export","quiet failure","salty.config.ts","strict"],"tags":["Get Started","Project Layout"],"href":"/react/docs/getting-started/advanced-setup#where-this-stuff-lives"},{"type":"docs","priority":0.49999999999999994,"title":"What the shared layer unlocks","description":"Variants, interactive state and scoping, animations and helpers — nothing here is setup, it is what the layer above makes possible.","teaches":"Which component-level tools exist so you do not hand-roll them","subsection":true,"frameworks":["react","next","astro"],"keywords":["variants","defaultVariants","passProps","nesting","keyframes","helpers","color boundary"],"tags":["Get Started","Components"],"href":"/react/docs/getting-started/advanced-setup#back-in-the-component"},{"type":"docs","priority":0.49999999999999994,"title":"The DevTools triage","description":"Whether the hashed class is on the element, and whether it has a rule behind it, splits the problem three ways immediately.","teaches":"How to identify which build stage failed before opening any source file","subsection":true,"frameworks":["react","next","astro"],"keywords":["devtools","hashed class","styles panel","data-component-name","triage"],"tags":["Get Started","Debugging"],"href":"/react/docs/getting-started/troubleshooting#start-here-devtools"},{"type":"docs","priority":0.49999999999999994,"title":"First-time setup failures","description":"The filename suffix, the missing export, a config file in the wrong place, an un-wired plugin, and nobody importing the generated stylesheet.","teaches":"The six ways a fresh install produces no CSS, and what a working one looks like","subsection":true,"frameworks":["react","next","astro"],"keywords":["suffix","export","salty.config.ts location","withSaltyCss","stylesheet import","wrong framework"],"tags":["Get Started","Setup"],"href":"/react/docs/getting-started/troubleshooting#setting-it-up-for-the-first-time"},{"type":"docs","priority":0.49999999999999994,"title":"Where errors actually print","description":"Salty works before the browser is involved, so the messages worth having are in the terminal — and strict is what turns the silent failures loud.","teaches":"Where to look for compiler output, and which failures never print anything at all","subsection":true,"frameworks":["react","next","astro"],"keywords":["terminal not console","strict","permissive strings","modifier throws","color throws","no output"],"tags":["Get Started","Debugging"],"href":"/react/docs/getting-started/troubleshooting#errors-and-warnings"},{"type":"docs","priority":0.49999999999999994,"title":"Updating the packages","description":"One command bumps every Salty package together, and mixing versions across them produces confusing failures rather than clear ones.","teaches":"How to update Salty CSS and why every package must move together","subsection":true,"frameworks":["react","next","astro"],"keywords":["salty-css up","update command","pinning","legacy-peer-deps","saltygen rebuild","version output"],"tags":["Updates","CLI"],"href":"/react/docs/guides/updates#updating-the-packages"},{"type":"docs","priority":0.49999999999999994,"title":"Where the release notes live","description":"GitHub Releases is the canonical list of what changed, and the pre-1.0 framing: pin your versions rather than floating on a caret.","teaches":"Where to read what changed before bumping, and how to treat pre-1.0 versioning","subsection":true,"frameworks":["react","next","astro"],"keywords":["release notes","github releases","changelog","pre-1.0","pinning","caret"],"tags":["Updates","Releases"],"href":"/react/docs/guides/updates#where-the-release-notes-live"},{"type":"docs","priority":0.49999999999999994,"title":"The six universal changes","description":"Styles move into their own files, CSS text becomes objects, values resolve at build time, the cascade becomes @layer, theming stops being JavaScript, and the requirement is a bundler.","teaches":"What has to change structurally regardless of which library you are leaving","subsection":true,"frameworks":["react","next","astro"],"keywords":["file suffix","style objects","build time ladder","cascade layers","theming attribute","bundler"],"tags":["Guides","Migration"],"href":"/react/docs/guides/migration#what-changes-no-matter-what"},{"type":"docs","priority":0.49999999999999994,"title":"The four categories of migration","description":"Where you are coming from predicts the shape of the work more than the library name does — read the table as effort estimation.","teaches":"Which migrations are cheap, which are a re-architecture, and when not to migrate at all","subsection":true,"frameworks":["react","next","astro"],"keywords":["effort estimation","runtime css-in-js","build-time","atomic","preprocessors","fit check"],"tags":["Guides","Migration"],"href":"/react/docs/guides/migration#the-four-categories"},{"type":"docs","priority":0.49999999999999994,"title":"An incremental migration sequence","description":"Install alongside, port tokens first, work in warn mode, do leaves before containers, handle globals deliberately, and remove the old library last.","teaches":"An order of operations where every step ships","subsection":true,"frameworks":["react","next","astro"],"keywords":["sequence","install alongside","tokens first","leaf components","globals","remove last"],"tags":["Guides","Migration"],"href":"/react/docs/guides/migration#a-sequence-that-works"},{"type":"docs","priority":0.49999999999999994,"title":"Render time versus build time","description":"The split isn't React things and other things — styled is the only API that produces something your framework has to render. Everything else produces text.","teaches":"Which APIs come from core and which single one is framework-specific","subsection":true,"frameworks":["react","next","astro"],"keywords":["render time","build time","core imports","re-exports","styled exception"],"tags":["Guides","API"],"href":"/react/docs/guides/framework-agnostic#where-the-line-falls"},{"type":"docs","priority":0.49999999999999994,"title":"Why the requirement is a bundler","description":"The plugin's three jobs — a build-start hook, a loader hook and a watcher — are bundler vocabulary, which is why the framework list is really a bundler list.","teaches":"How to tell whether an unlisted stack will work, and how to wire the plugin","subsection":true,"frameworks":["react","next","astro"],"keywords":["vite plugin","webpack plugin","loader hook","watcher","build start","meta-frameworks"],"tags":["Guides","Setup"],"href":"/react/docs/guides/framework-agnostic#the-real-requirement"},{"type":"docs","priority":0.49999999999999994,"title":"Authoring with className","description":"The entire styling surface returned as a class string — plus the String-object caveat and the defaults wrapper that doubles as your component seam.","teaches":"How to author and consume Salty styles without a styled component","subsection":true,"frameworks":["react","next","astro"],"keywords":["className","variant chain","String object","defaultVariants","wrapper function","class binding"],"tags":["Guides","Class Names"],"href":"/react/docs/guides/framework-agnostic#authoring-with-classname"},{"type":"docs","priority":0.49999999999999994,"title":"The rest of the design system from core","description":"Tokens, themes, media queries, clamps, keyframes and templates all come out of core unchanged — and theming needs nothing from your framework at all.","teaches":"That the whole design-system layer is framework-independent, theming included","subsection":true,"frameworks":["react","next","astro"],"keywords":["defineVariables","conditional theme","no provider","attribute switch","templates","keyframes"],"tags":["Guides","Tokens"],"href":"/react/docs/guides/framework-agnostic#the-rest-of-the-system"},{"type":"docs","priority":0.49999999999999994,"title":"What you give up without styled","description":"Typed variant props, element and as, defaultProps and passProps, and extension with its automatic layer bump — every item is component ergonomics, none of it is CSS.","teaches":"The exact size of the gap, and the escape hatch below it","subsection":true,"frameworks":["react","next","astro"],"keywords":["component ergonomics","passProps","extension","layer bump","generator classes","unsupported"],"tags":["Guides","Tradeoffs"],"href":"/react/docs/guides/framework-agnostic#what-you-give-up"},{"type":"docs","priority":0.49999999999999994,"title":"styled signature","description":"The two arguments styled takes — a tag name or a component, plus an options object — and what the returned component accepts.","teaches":"The shape of a styled call and the one requirement a wrapped third-party component must meet","subsection":true,"frameworks":["react","next","astro"],"keywords":["signature","tag argument","StyledParams","className prop requirement","returns"],"tags":["Reference","API"],"href":"/react/docs/reference/styled#signature"},{"type":"docs","priority":0.49999999999999994,"title":"styled options","description":"The eleven keys the options object accepts, from base and variants through to className, displayName and priority.","teaches":"Which option to reach for, and what each key in the styled options object controls","subsection":true,"frameworks":["react","next","astro"],"keywords":["options table","base","variants","element","passProps","priority","displayName"],"tags":["Reference","API"],"href":"/react/docs/reference/styled#options"},{"type":"docs","priority":0.49999999999999994,"title":"What the rendered component accepts","description":"Variant props, native element props, className, style, as, css-* and ref — plus the caveat about refs through a wrapped component.","teaches":"The complete prop surface of a component returned by styled, and how each kind is handled","subsection":true,"frameworks":["react","next","astro"],"keywords":["rendered component","className","style prop","as prop","ref forwarding","data-component-name"],"tags":["Reference","API"],"href":"/react/docs/reference/styled#the-rendered-component"},{"type":"docs","priority":0.49999999999999994,"title":"Prop tokens (css-*)","description":"Referencing {props.X} generates a typed css-X prop, written into the inline style as a custom property the compiled rule already reads.","teaches":"The camelCase to dash-case to CSS-variable naming chain, and when a prop token beats a plain custom property","subsection":true,"frameworks":["react","next","astro"],"keywords":["prop tokens","css-*","props.X","custom property","inline style","typed contract"],"tags":["Reference","Prop Tokens"],"href":"/react/docs/reference/styled#prop-tokens"},{"type":"docs","priority":0.49999999999999994,"title":"Extending a component","description":"Passing a component as the first argument wraps it — both classes land on the element, variants coexist with the outer layer winning collisions, and chains compose.","teaches":"Exactly what changes when a styled component is wrapped rather than created from a tag","subsection":true,"frameworks":["react","next","astro"],"keywords":["extending","wrapping","class preservation","variant collision","chains","third-party components"],"tags":["Reference","Composition"],"href":"/react/docs/reference/styled#extending-a-component"},{"type":"docs","priority":0.49999999999999994,"title":"Compiler requirements","description":"Four constraints decide whether a styled call produces any CSS at all: the filename suffix, a top-level export, an import that reaches it, and a build-safe file.","teaches":"Why a styled call can type-check perfectly and still emit nothing","subsection":true,"frameworks":["react","next","astro"],"keywords":["compiler requirements","file suffix","top-level export","tree shaking","build time","content hashing"],"tags":["Reference","Compiler"],"href":"/react/docs/reference/styled#compiler-requirements"},{"type":"docs","priority":0.49999999999999994,"title":"className signature","description":"One options object in, a string-coercible object out — carrying the generated class plus a .variant() method.","teaches":"The shape of a className call and what the returned ClassNameFunction type contains","subsection":true,"frameworks":["react","next","astro"],"keywords":["signature","StyledParams","ClassNameFunction","variant method","generator","isClassName"],"tags":["Reference","API"],"href":"/react/docs/reference/class-name#signature"},{"type":"docs","priority":0.49999999999999994,"title":"className options","description":"The eight keys that have an effect, from base and variants through className, displayName and priority.","teaches":"Which option to reach for, and which keys the shared type accepts without doing anything","subsection":true,"frameworks":["react","next","astro"],"keywords":["options table","base","variants","defaultVariants","priority","displayName"],"tags":["Reference","API"],"href":"/react/docs/reference/class-name#options"},{"type":"docs","priority":0.49999999999999994,"title":"The returned value","description":"String coercion, the immutable .variant() chain, .generator and .isClassName — plus the String-object caveat that trips strict typeof checks.","teaches":"What each member of the returned value is for, and why typeof reports object rather than string","subsection":true,"frameworks":["react","next","astro"],"keywords":["string coercion","variant chain","generator","isClassName","String object","typeof"],"tags":["Reference","API"],"href":"/react/docs/reference/class-name#the-returned-value"},{"type":"docs","priority":0.49999999999999994,"title":"What gets generated","description":"One selector plus qualified forms of it, a five-character hash derived from the style object alone, and a file in the same namespace styled uses.","teaches":"Which selector each feature produces, what the hash is derived from, and how deduplication follows from that","subsection":true,"frameworks":["react","next","astro"],"keywords":["generated selectors","hash","deduplication","saltygen","where selector","interpolation"],"tags":["Reference","Compiled Output"],"href":"/react/docs/reference/class-name#what-gets-generated"},{"type":"docs","priority":0.49999999999999994,"title":"What className doesn't do","description":"No extending, no element or prop forwarding, no automatic defaults, and no css-* prop tokens — all component ergonomics rather than CSS.","teaches":"Which capabilities require a component, and the plain custom-property workaround for consumer-set values","subsection":true,"frameworks":["react","next","astro"],"keywords":["limitations","no extending","no css props","custom property fallback","styled alternative"],"tags":["Reference","Limitations"],"href":"/react/docs/reference/class-name#what-class-name-doesnt-do"},{"type":"docs","priority":0.49999999999999994,"title":"Compiler requirements","description":"The filename suffix, a top-level export, an import the bundler can see, and a build-safe file — with tree-shaking biting harder here than on styled.","teaches":"Why a className call can type-check perfectly and still emit nothing","subsection":true,"frameworks":["react","next","astro"],"keywords":["compiler requirements","file suffix","top-level export","tree shaking","devtools hash","build time"],"tags":["Reference","Compiler"],"href":"/react/docs/reference/class-name#compiler-requirements"},{"type":"docs","priority":0.49999999999999994,"title":"What the reset addresses","description":"The usual jobs of a reset, limited to the ones that reliably cause trouble — box model, spacing, typography, media, text flow and form elements.","teaches":"Which browser defaults the Salty reset corrects and where it deliberately stops","subsection":true,"frameworks":["react","next","astro"],"keywords":["box model","spacing","typography baseline","media","text flow","form elements"],"tags":["Reference","Reset"],"href":"/react/docs/reference/css-reset#what-it-addresses"},{"type":"docs","priority":0.49999999999999994,"title":"Where the reset sits in the cascade","description":"The reset is emitted into the reset layer near the bottom of the order, so everything you write lands higher and overriding it never needs !important.","teaches":"Why the reset can never fight your own styles","subsection":true,"frameworks":["react","next","astro"],"keywords":["reset layer","layer order","override","no important","cascade"],"tags":["Reference","Cascade Layers"],"href":"/react/docs/reference/css-reset#where-it-sits-in-the-cascade"},{"type":"docs","priority":0.49999999999999994,"title":"The reset config option","description":"Three values: the built-in default, none for bringing your own, or a custom object that replaces the built-in entirely rather than merging with it.","teaches":"How to disable or replace the reset, and why a partial tweak belongs in global styles instead","subsection":true,"frameworks":["react","next","astro"],"keywords":["reset option","salty.config.ts","none","custom reset","replaces not merges"],"tags":["Reference","Configuration"],"href":"/react/docs/reference/css-reset#configuration"},{"type":"docs","priority":0.49999999999999994,"title":"The full reset source","description":"The complete saltyReset object as it ships, usable as a starting point for your own reset.","teaches":"Exactly which rules the built-in reset applies","subsection":true,"frameworks":["react","next","astro"],"keywords":["saltyReset","source","border-box","text-wrap","font smoothing","starting point"],"tags":["Reference","Reset"],"href":"/react/docs/reference/css-reset#source"},{"type":"docs","priority":0.49999999999999994,"title":"The four commands","description":"init, generate, build and update at a glance — plus the rule that where you run the CLI decides what it acts on.","teaches":"What each command does and how paths and .saltyrc.json are resolved","subsection":true,"frameworks":["react","next","astro"],"keywords":["init","generate","build","update","working directory","prettier","never overwrites"],"tags":["Reference","CLI"],"href":"/react/docs/reference/cli#commands"},{"type":"docs","priority":0.49999999999999994,"title":"init","description":"Detects the project, installs matching packages, writes the config files, edits the bundler config and runs a first build.","teaches":"Everything init writes and why re-running it is safe","subsection":true,"frameworks":["react","next","astro"],"keywords":["init","css-file","skip-install","package.json required","idempotent","prepare script"],"tags":["Reference","CLI"],"href":"/react/docs/reference/cli#init"},{"type":"docs","priority":0.49999999999999994,"title":"generate","description":"Scaffolds a styled component in a file the compiler will actually read — the filename is the whole point.","teaches":"How generate fixes up the path and what the -r pair produces","subsection":true,"frameworks":["react","next","astro"],"keywords":["generate","scaffold","suffix","tag","name","reactComponent","wrapper"],"tags":["Reference","CLI"],"href":"/react/docs/reference/cli#generate"},{"type":"docs","priority":0.49999999999999994,"title":"build","description":"Compiles every Salty file it can reach and regenerates saltygen from scratch — plus the watch-mode split between incremental and full rebuilds.","teaches":"When you actually need to run build by hand and what --mode changes","subsection":true,"frameworks":["react","next","astro"],"keywords":["build","watch","mode","production","data-component-name","incremental","stale rules"],"tags":["Reference","CLI"],"href":"/react/docs/reference/cli#build"},{"type":"docs","priority":0.49999999999999994,"title":"update","description":"Bumps every @salty-css/* package together, then offers to rebuild — because mixing versions produces confusing failures rather than clear ones.","teaches":"What update reads and installs, and the two ways it stops early","subsection":true,"frameworks":["react","next","astro"],"keywords":["update","up","version pinning","legacy-peer-deps","rebuild","lockstep"],"tags":["Reference","CLI"],"href":"/react/docs/reference/cli#update"},{"type":"docs","priority":0.49999999999999994,"title":"Running the CLI in CI","description":"Three things behave differently without an interactive terminal — init fails, update skips the rebuild, and prepare does not always run.","teaches":"Which flags each command needs in a non-interactive environment","subsection":true,"frameworks":["react","next","astro"],"keywords":["ci","non-interactive","yes flag","skip-install","ignore-scripts","prepare"],"tags":["Reference","CLI"],"href":"/react/docs/reference/cli#running-it-in-ci"},{"type":"docs","priority":0.3999999999999999,"description":"How to decide between using styled components or class names in Salty CSS.","teaches":"When to use Styled Component versus Class Name","title":"When to use styled vs className","subsection":true,"frameworks":["react","next","astro"],"keywords":["styled","className"],"tags":["Styled Component","Class Name"],"href":"/react/docs/basics/styled-components#styled-or-classname"},{"type":"docs","priority":0.3999999999999999,"title":"A spacing scale modifier","description":"Making a 4px grid the easiest thing to type, with a loose pattern, a strict transform that throws on off-scale values, and the g flag that shorthands need.","teaches":"How to build an arithmetic modifier safely, and when a token is the better answer instead","subsection":true,"frameworks":["react","next","astro"],"keywords":["spacing scale","g flag","shorthand","throwing transform","design scale","tokens comparison"],"tags":["Modifiers","Design Systems"],"href":"/react/docs/basics/modifiers#a-spacing-scale"},{"type":"docs","priority":0.3999999999999999,"title":"Returning extra declarations from a modifier","description":"The css return value brings extra declarations along — plus where they land in the rule, and the typo cost of inventing a value nothing checks.","teaches":"How the css return key works, the declaration ordering it produces, and how to pin a generic pattern to one property","subsection":true,"frameworks":["react","next","astro"],"keywords":["flex-center","css return","declaration order","lookbehind","typo cost","scoping a pattern"],"tags":["Modifiers","Layout"],"href":"/react/docs/basics/modifiers#one-value-several-declarations"},{"type":"docs","priority":0.3999999999999999,"title":"A color opacity modifier","description":"Making {colors.black}/60 mean \"that color at 60%\", why it produces color-mix() rather than a precomputed color, and adding a progressive-enhancement fallback.","teaches":"Why a token cannot be shaded at build time, and how color-mix() follows the token through a theme switch","subsection":true,"frameworks":["react","next","astro"],"keywords":["color opacity","color-mix","var reference","token pointer","fallback","srgb"],"tags":["Modifiers","Color"],"href":"/react/docs/basics/modifiers#a-color-with-an-opacity-suffix"},{"type":"docs","priority":0.3999999999999999,"title":"Hiding a compat workaround in a modifier","description":"Four prefixed declarations that only work as a set, reduced to one value — and the argument that modifiers are a good home for knowledge that will expire.","teaches":"How to hide a vendor-prefixed workaround behind an invented value, and why that migration later is four lines","subsection":true,"frameworks":["react","next","astro"],"keywords":["line clamp","webkit-box","vendor prefix","lookbehind","compat workaround","migration"],"tags":["Modifiers","Compatibility"],"href":"/react/docs/basics/modifiers#line-clamp"},{"type":"docs","priority":0.3999999999999999,"title":"Helper, token, template, or modifier?","description":"The line is about what you are reusing: a named value, a bundle of properties, a value syntax, or logic that computes a value from arguments.","teaches":"Which of the four reuse tools fits a given problem, and the token-versus-helper distinction in particular","subsection":true,"frameworks":["react","next","astro"],"keywords":["decision table","tokens vs helpers","templates","modifiers","computed vs fixed"],"tags":["Helpers","Decisions"],"href":"/react/docs/basics/helpers#helper-token-template-or-modifier"},{"type":"docs","priority":0.3999999999999999,"title":"How nested selectors compile","description":"Every nested selector comes out with the component hash on the front, which is the whole isolation guarantee.","teaches":"Why nesting in Salty gives SCSS ergonomics without the global-nesting leak risk","subsection":true,"frameworks":["react","next","astro"],"keywords":["compiled output","hash anchoring","leak risk","global nesting","has selector","container queries"],"tags":["Scoping","Compiled Output"],"href":"/react/docs/basics/scoping-and-composition#nesting-how-it-compiles"},{"type":"docs","priority":0.3999999999999999,"title":"Why !important inverts layer order","description":"When two competing rules are both !important, the earlier layer wins instead of the later one — the one place in CSS where trying harder makes you lose.","teaches":"Why !important breaks the layer mental model and what to reach for instead","subsection":true,"frameworks":["react","next","astro"],"keywords":["important","layer inversion","cascade bugs","inline declaration","priority","override"],"tags":["Scoping","Cascade Layers"],"href":"/react/docs/basics/scoping-and-composition#the-important-trap"},{"type":"docs","priority":0.3999999999999999,"title":"What TypeScript won't catch","description":"Style values are permissive strings by design, and a wrong filename type-checks perfectly — the build and the linter cover what the type system cannot see.","teaches":"Why strict matters and why the filename problem is invisible to the type system","subsection":true,"frameworks":["react","next","astro"],"keywords":["permissive values","typo token path","strict","externalModules","wrong filename","no css"],"tags":["Tooling","TypeScript"],"href":"/react/docs/basics/tooling#tooling-what-typescript-wont-catch"},{"type":"docs","priority":0.3999999999999999,"title":"Stable hooks: className and defaultProps","description":"A class you picked changes when you change it; defaultProps binds the role and accessible name in the definition rather than in forty call sites.","teaches":"The two options that give a test something durable to query by","subsection":true,"frameworks":["react","next","astro"],"keywords":["className option","defaultProps","role","aria-modal","queryable","accessibility first"],"tags":["Testing","Assertions"],"href":"/react/docs/basics/testing#how-you-define-a-stable-hook"},{"type":"docs","priority":0.3999999999999999,"title":"Getting .css.ts files through a test runner","description":"A runner sharing your bundler config mostly works; runners with their own pipeline need the transform wired in, and there is no first-party package for that today.","teaches":"The least-settled corner of the testing story, and the CSS-stub pattern that silently swallows Salty files","subsection":true,"frameworks":["react","next","astro"],"keywords":["vitest","transform","bundler config","css stub","moduleNameMapper","anchored pattern"],"tags":["Testing","Setup"],"href":"/react/docs/basics/testing#getting-files-through-your-runner"},{"type":"docs","priority":0.3999999999999999,"title":"End-to-end selectors that survive a production build","description":"data-component-name is stripped in production, so a selector that works all through local development can vanish the first time the suite runs against a real build.","teaches":"Which three selector strategies survive the mode change","subsection":true,"frameworks":["react","next","astro"],"keywords":["data-component-name","production build","role","label","data-testid","call site"],"tags":["Testing","End-to-End"],"href":"/react/docs/basics/testing#end-to-end"},{"type":"docs","priority":0.3999999999999999,"title":"Visual regression testing","description":"Themes are one attribute per shot and animations switch off with reduced-motion emulation — but fonts are the thing that will actually make a suite flaky.","teaches":"Why screenshot diffing is less fiddly with Salty, and the one thing that still bites","subsection":true,"frameworks":["react","next","astro"],"keywords":["screenshot diffing","theme matrix","setAttribute","reduced motion","document.fonts.ready","flaky"],"tags":["Testing","Visual Regression"],"href":"/react/docs/basics/testing#visual-regression"},{"type":"docs","priority":0.3999999999999999,"title":"What a style file imports, the build imports","description":"A plain data module is free; a heavy browser-assuming dependency can slow compilation noticeably or crash the build outright.","teaches":"When to split a heavy import into a lightweight helper, and when that reflex costs more than it saves","subsection":true,"frameworks":["react","next","astro"],"keywords":["build performance","heavy imports","window","lightweight helper","proportion","ci complexity"],"tags":["Dynamic Values","Build Time"],"href":"/react/docs/basics/dynamic-values#the-one-warning-worth-reading"},{"type":"docs","priority":0.3999999999999999,"title":"The pseudo-classes people forget they have","description":":focus-within, :user-invalid, :user-valid and :placeholder-shown — Baseline-supported states that let a form react to itself with no state code.","teaches":"Which lesser-known pseudo-classes replace hand-rolled form state, and why :user-invalid beats :invalid","subsection":true,"frameworks":["react","next","astro"],"keywords":["focus-within","user-invalid","user-valid","placeholder-shown","form validation","baseline"],"tags":["Interactive State","Forms"],"href":"/react/docs/basics/interactive-state#the-ones-people-forget-they-have"},{"type":"docs","priority":0.3999999999999999,"title":"Native attributes as styling hooks","description":"The open attribute on details, plus the ARIA and data attributes already in your markup, all double as free styling hooks.","teaches":"How to style off native and ARIA attributes instead of tracking the same state twice","subsection":true,"frameworks":["react","next","astro"],"keywords":["details","open attribute","aria-current","aria-expanded","data attributes","disclosure"],"tags":["Interactive State","Attributes"],"href":"/react/docs/basics/interactive-state#and-its-not-only-pseudo-classes"},{"type":"docs","priority":0.3999999999999999,"title":"Relational styling with :has() and descendants","description":"Styling a parent by what it contains with :has(), and driving descendants from a parent state — both scoped to the component hash.","teaches":"How to style in both directions between a component and its children without any state code","subsection":true,"frameworks":["react","next","astro"],"keywords":["has selector","parent selector","descendant selectors","scoping","component hash","no leaking"],"tags":["Interactive State","Selectors"],"href":"/react/docs/basics/interactive-state#reacting-to-children-and-styling-into-children"},{"type":"docs","priority":0.3999999999999999,"title":"Data attributes instead of variants","description":"Keying off a data attribute when an external state machine owns the state — and why an unscoped attribute makes variants the safer default.","teaches":"When to key styling off a data attribute rather than a variant, and the leak risk that comes with it","subsection":true,"frameworks":["react","next","astro"],"keywords":["data attributes","state machine","xstate","unscoped attributes","query handle","variants default"],"tags":["Interactive State","Attributes"],"href":"/react/docs/basics/interactive-state#the-attribute-alternative"},{"type":"docs","priority":0.3999999999999999,"title":"The disabled variant trap","description":"A disabled variant styles a button that stays fully clickable, because variant props never reach the DOM — plus the two fixes and the one real exception.","teaches":"Why a disabled variant is usually a bug, how passProps fixes it, and what to do on non-form elements","subsection":true,"frameworks":["react","next","astro"],"keywords":["disabled trap","passProps","aria-disabled","native attributes","variant collision","form controls"],"tags":["Interactive State","Accessibility"],"href":"/react/docs/basics/interactive-state#the-disabled-trap"},{"type":"docs","priority":0.3999999999999999,"title":"What a token compiles to","description":"Every token becomes a dashed custom property on :root, and a component rule reads only the ones it references.","teaches":"How token paths map to CSS custom property names and what the compiled stylesheet looks like","subsection":true,"frameworks":["react","next","astro"],"keywords":["compiled output","root","dashed path","var()","devtools","token naming"],"tags":["Variables","Compiled Output"],"href":"/react/docs/basics/variables#example-1-what-actually-ships"},{"type":"docs","priority":0.3999999999999999,"title":"Extending a theme","description":"Adding a third scheme costs one more mode, and theme-aware interactive states come from reaching for the same conditional tokens inside pseudo-classes.","teaches":"How to add schemes and theme-aware states, and where the build-time color() boundary actually bites","subsection":true,"frameworks":["react","next","astro"],"keywords":["extra schemes","theme-aware states","hover","color function","build-time boundary","molecule restraint"],"tags":["Theming","Tokens"],"href":"/react/docs/basics/theming#example-1-extending-it"},{"type":"docs","priority":0.3999999999999999,"title":"Text style templates","description":"Folding family, size, weight and tracking into one name like headline.large, with a shared base, per-size leaves and opt-in variants.","teaches":"How to build a text-style system as a template group and tune each size without copy-pasting declarations","subsection":true,"frameworks":["react","next","astro"],"keywords":["text styles","textStyle","headline","leaf inheritance","template variants","type scale"],"tags":["Templates","Typography"],"href":"/react/docs/basics/templates#text-styles"},{"type":"docs","priority":0.3999999999999999,"title":"Interaction state templates","description":"The cluster of properties that make something feel interactive — cursor, transition, hover nudge, focus ring — as one base-only template.","teaches":"How to define and apply a base-only template, and which interaction properties are worth bundling","subsection":true,"frameworks":["react","next","astro"],"keywords":["interactive","base-only template","focus-visible","transition","hover","true"],"tags":["Templates","Interaction"],"href":"/react/docs/basics/templates#interaction-states"},{"type":"docs","priority":0.3999999999999999,"title":"Shorthand-like preset templates","description":"Bundling width, style, color and radius into named presets — and why a template must not be named after a real CSS shorthand.","teaches":"How to build a shorthand-style preset template and how to name it without shadowing a real CSS property","subsection":true,"frameworks":["react","next","astro"],"keywords":["bordered","presets","shorthand","naming","shadowing css properties"],"tags":["Templates","Naming"],"href":"/react/docs/basics/templates#a-border-ish-shorthand"},{"type":"docs","priority":0.3999999999999999,"title":"Theming values in a template","description":"A template that references themed tokens flips with the scheme for free, as long as it reads the molecule and not a raw brand color.","teaches":"How templates and theming compose, and which tokens a template should reference","subsection":true,"frameworks":["react","next","astro"],"keywords":["themed template","theme tokens","molecules","dark mode","token layering"],"tags":["Templates","Theming"],"href":"/react/docs/basics/templates#theming-values"},{"type":"docs","priority":0.3999999999999999,"title":"Function templates","description":"Exporting a function that takes a call-site argument and returns a style object, with all the logic running at build time.","teaches":"When to use a function template instead of a variant, and how a typed parameter flows to the call site","subsection":true,"frameworks":["react","next","astro"],"keywords":["function templates","options object","build-time logic","typed parameter","stack","surface"],"tags":["Templates","Build Time"],"href":"/react/docs/basics/templates#function-templates"},{"type":"docs","priority":0.3999999999999999,"title":"Props injection in templates","description":"The {props.X} form lets a template read a value off the rendered component props at runtime, for genuinely open-ended cases.","teaches":"That props injection exists, what it is for, and that it is the one template feature with a runtime cost","subsection":true,"frameworks":["react","next","astro"],"keywords":["props injection","runtime cost","open-ended values","user-picked color"],"tags":["Templates","Runtime"],"href":"/react/docs/basics/templates#beyond-the-basics"},{"type":"docs","priority":0.3999999999999999,"title":"Where global styles land in the cascade","description":"The global layer sits above reset and below l0, so your globals beat the reset and component styles always beat your globals.","teaches":"The two consequences of the layer ordering that save a debugging session later","subsection":true,"frameworks":["react","next","astro"],"keywords":["global layer","layer order","reset","component styles win","no important"],"tags":["Global Styles","Cascade Layers"],"href":"/react/docs/basics/global-styles#where-they-land-in-the-cascade"},{"type":"docs","priority":0.3999999999999999,"title":"Installing by hand","description":"Five steps that are the same in every framework, a plugin table per stack, and the peer-dependency versions each package expects.","teaches":"How to wire Salty CSS into a bundler yourself and which plugin package each stack needs","subsection":true,"frameworks":["react","next","astro"],"keywords":["manual install","plugin package","withSaltyCss","saltyPlugin","peer dependencies","typescript 5"],"tags":["Get Started","Setup"],"href":"/react/docs/getting-started/basic-setup#manual-install"},{"type":"docs","priority":0.3999999999999999,"title":"The five compiler settings","description":"strict, defaultUnit, importStrategy, externalModules and reset describe how the compiler behaves across the whole project.","teaches":"Which two config options matter on day one and why strict is worth leaving on","subsection":true,"frameworks":["react","next","astro"],"keywords":["strict","defaultUnit","importStrategy","externalModules","reset","typo token path"],"tags":["Get Started","Configuration"],"href":"/react/docs/getting-started/configuration#settings-that-only-live-here"},{"type":"docs","priority":0.3999999999999999,"title":"The design-system config keys","description":"variables, global and templates each have a standalone factory taking the same object, and Salty merges both sources — modifiers is the config-only exception.","teaches":"Which config keys can move into their own files later without rewriting call sites","subsection":true,"frameworks":["react","next","astro"],"keywords":["variables","global","templates","modifiers","merging sources","config-only"],"tags":["Get Started","Configuration"],"href":"/react/docs/getting-started/configuration#settings-that-dont-have-to-live-here"},{"type":"docs","priority":0.3999999999999999,"title":"The two rules that make it resolve","description":"A recognized filename suffix and a top-level export — both fail quietly, and there is no third rule, no registration step, no barrel.","teaches":"Why a definition silently produces nothing, and why file placement is genuinely free","subsection":true,"frameworks":["react","next","astro"],"keywords":["filename suffix","top-level export","quiet failure","eslint plugin","placement","no registration"],"tags":["Get Started","Troubleshooting"],"href":"/react/docs/getting-started/configuration#two-rules-and-no-third"},{"type":"docs","priority":0.3999999999999999,"title":"Three editor settings worth checking","description":"Use the workspace TypeScript, remember that types follow the build, and know that the TS server can hold a stale copy after you add a token.","teaches":"The three settings that explain most missing-autocomplete confusion","subsection":true,"frameworks":["react","next","astro"],"keywords":["workspace version","typescript 5","fresh clone","restart ts server","stale types"],"tags":["Get Started","TypeScript"],"href":"/react/docs/getting-started/editor-setup#three-settings-worth-checking"},{"type":"docs","priority":0.3999999999999999,"title":"The filename suffix is the contract","description":"Salty finds style files by filename, not by import — five suffixes compile, they are aliases rather than variants, and the export is the second half.","teaches":"Which suffixes compile and why neither mistake produces an error","subsection":true,"frameworks":["react","next","astro"],"keywords":["css.ts","salty.ts","styled.ts","styles.ts","export","aliases","no barrel"],"tags":["Get Started","Compiler"],"href":"/react/docs/getting-started/file-structure#the-suffix-is-the-contract"},{"type":"docs","priority":0.3999999999999999,"title":"Where style files sit","description":"Salty walks the project and takes whatever matches the suffix, so the layout is yours — plus two things about that walk worth knowing early.","teaches":"The layout most projects land on, and the difference between a file that fails to compile and one that was never looked at","subsection":true,"frameworks":["react","next","astro"],"keywords":["layout","styles folder","include exclude","double compile","defineX","project walk"],"tags":["Get Started","Project Layout"],"href":"/react/docs/getting-started/file-structure#where-the-files-sit"},{"type":"docs","priority":0.3999999999999999,"title":"Reading index.css","description":"The banner gives the writing version, the @layer line is the cascade order, and an absent import means a discovery problem rather than a write failure.","teaches":"Three things to read out of the generated entry stylesheet","subsection":true,"frameworks":["react","next","astro"],"keywords":["index.css","banner version","layer declaration","empty file","discovery problem"],"tags":["Get Started","Debugging"],"href":"/react/docs/getting-started/file-structure#index-css-the-entry-point"},{"type":"docs","priority":0.3999999999999999,"title":"The css/ prefix namespaces","description":"Every generated filename starts with a namespace, and reading it tells you which part of the compiler produced the file.","teaches":"What each of the five filename prefixes means","subsection":true,"frameworks":["react","next","astro"],"keywords":["prefixes","cl_","a_","l_","f_","globals","importStrategy"],"tags":["Get Started","Compiler Output"],"href":"/react/docs/getting-started/file-structure#css-the-prefix-says-who-wrote-it"},{"type":"docs","priority":0.3999999999999999,"title":"The generated token types","description":"Every token path, template path and media query name as TypeScript types — and one specific failure signal worth knowing.","teaches":"What the declaration file contains and what an empty union tells you","subsection":true,"frameworks":["react","next","astro"],"keywords":["css-tokens.d.ts","global declaration","empty union","discovery failure","autocomplete"],"tags":["Get Started","TypeScript"],"href":"/react/docs/getting-started/file-structure#types-css-tokens"},{"type":"docs","priority":0.3999999999999999,"title":"The working folders","description":"js/ is what the compiler actually executed, cache/config-cache.json is the merged config injected back into every file, and imports/ and temp/ are usually empty.","teaches":"Which generated folder answers \"what did the compiler think I wrote\"","subsection":true,"frameworks":["react","next","astro"],"keywords":["js folder","esbuild","config-cache","templatePaths","imports folder","temp"],"tags":["Get Started","Debugging"],"href":"/react/docs/getting-started/file-structure#the-working-folders"},{"type":"docs","priority":0.3999999999999999,"title":"The three hash lengths","description":"Five characters is a style object, six is a file path, four is a template path — all deterministic and alphabetic-only.","teaches":"How to tell the three kinds of generated hash apart when reading a bundle","subsection":true,"frameworks":["react","next","astro"],"keywords":["hash length","style object hash","file path hash","template hash","deterministic","diff"],"tags":["Get Started","Compiler Output"],"href":"/react/docs/getting-started/file-structure#three-hashes"},{"type":"docs","priority":0.3999999999999999,"title":"Variables, briefly","description":"A value you name once and reference everywhere, compiled into a real custom property on :root — plus the naming habit that is expensive to undo later.","teaches":"How to define and reference design tokens, and why to name by role","subsection":true,"frameworks":["react","next","astro"],"keywords":["defineVariables","token path","custom property","name by role","pageMargin"],"tags":["Get Started","Tokens"],"href":"/react/docs/getting-started/advanced-setup#shared-variables"},{"type":"docs","priority":0.3999999999999999,"title":"Theming, briefly","description":"The same token names with different values behind them, switched by an attribute — and the one layer of indirection that makes it work.","teaches":"Why a component should read a role-named value rather than a palette entry","subsection":true,"frameworks":["react","next","astro"],"keywords":["conditional scope","data-theme","indirection","no provider","no re-render"],"tags":["Get Started","Theming"],"href":"/react/docs/getting-started/advanced-setup#shared-theming"},{"type":"docs","priority":0.3999999999999999,"title":"One component is unstyled","description":"Scope is the diagnosis — if everything else still has its styles, nothing about the setup is broken and the problem is inside one file.","teaches":"The three per-file causes, including the tree-shaking one that only shows up in bigger projects","subsection":true,"frameworks":["react","next","astro"],"keywords":["scope","renamed file","lost export","tree-shaken","barrel file","not reachable"],"tags":["Get Started","Debugging"],"href":"/react/docs/getting-started/troubleshooting#one-component-is-unstyled"},{"type":"docs","priority":0.3999999999999999,"title":"The whole app is unstyled after a clone or deploy","description":"saltygen is a build artifact, so a fresh clone starts with neither the stylesheet nor the types — and platforms that install with --ignore-scripts skip the prepare script.","teaches":"Why the local fix and the deploy fix are different, and what each one is","subsection":true,"frameworks":["react","next","astro"],"keywords":["saltygen","gitignore","prepare script","ignore-scripts","preview url","fresh clone"],"tags":["Get Started","CI"],"href":"/react/docs/getting-started/troubleshooting#the-whole-app-is-unstyled"},{"type":"docs","priority":0.3999999999999999,"title":"The styles are there but something's off","description":"A token printing as literal text, cascade layers deciding the fight, anyOfVariants losing by design, a variant prop that never reaches the DOM, and variants nested inside base.","teaches":"Six subtler failures where the class and the rule both exist but the result is wrong","subsection":true,"frameworks":["react","next","astro"],"keywords":["literal token","cascade layers","anyOfVariants","disabled variant","passProps","variants in base"],"tags":["Get Started","Debugging"],"href":"/react/docs/getting-started/troubleshooting#the-styles-are-there-but-somethings-off"},{"type":"docs","priority":0.3999999999999999,"title":"Migrating from styled-components","description":"The component-first model carries over almost completely; the tagged templates, the function interpolations and the runtime do not.","teaches":"The full styled-components mapping and why interpolation count estimates effort better than line count","subsection":true,"frameworks":["react","next","astro"],"keywords":["styled-components","transient props","shouldForwardProp","createGlobalStyle","ThemeProvider","interpolations"],"tags":["Guides","Migration"],"href":"/react/docs/guides/migration#styled-components"},{"type":"docs","priority":0.3999999999999999,"title":"Migrating from Stitches","description":"The closest API on the page — same variant names, same semantics. Two syntax deltas do most of the work, and utils is the one that needs thought.","teaches":"The Stitches mapping and how utils split between templates and modifiers","subsection":true,"frameworks":["react","next","astro"],"keywords":["stitches","base key","token syntax","createStitches","utils","function template"],"tags":["Guides","Migration"],"href":"/react/docs/guides/migration#stitches"},{"type":"docs","priority":0.3999999999999999,"title":"Migrating from Panda CSS","description":"Shared vocabulary on purpose — but four things genuinely differ, and two of them are architectural: the extraction model and the output model.","teaches":"The Panda mapping and the scaling-curve tradeoff to decide on before starting","subsection":true,"frameworks":["react","next","astro"],"keywords":["panda css","static analysis","atomic output","codegen","patterns","style props"],"tags":["Guides","Migration"],"href":"/react/docs/guides/migration#panda-css"},{"type":"docs","priority":0.3999999999999999,"title":"Migrating from Linaria","description":"Mechanically the closest relative — both evaluate modules at build time and carry dynamic values on custom properties. The difference is scope.","teaches":"The Linaria mapping and why the system layer above the primitive is the real porting cost","subsection":true,"frameworks":["react","next","astro"],"keywords":["linaria","wyw-in-js","custom properties","typed contract","system layer","atomic"],"tags":["Guides","Migration"],"href":"/react/docs/guides/migration#linaria"},{"type":"docs","priority":0.3999999999999999,"title":"Migrating from Tailwind","description":"The largest conceptual distance on the page, because the unit of styling changes — plus an honest fit check before doing any work, and advice on running both at once.","teaches":"The Tailwind mapping, when not to migrate, and how layer ordering works with two stylesheets","subsection":true,"frameworks":["react","next","astro"],"keywords":["tailwind","utility classes","re-architecture","theme block","tailwind-merge","layer order"],"tags":["Guides","Migration"],"href":"/react/docs/guides/migration#tailwind"},{"type":"docs","priority":0.3999999999999999,"title":"Migrating from Sass or CSS Modules","description":"The most mechanical migration on the page — except for scoping, which genuinely changes, and tokens, which are an upgrade rather than a lateral move.","teaches":"The Sass mapping, what giving up cross-component selectors costs, and why real custom properties beat compile-time variables","subsection":true,"frameworks":["react","next","astro"],"keywords":["sass","scss","mixins","css modules","scoping","custom properties"],"tags":["Guides","Migration"],"href":"/react/docs/guides/migration#sass"},{"type":"docs","priority":0.3999999999999999,"title":"base","description":"Styles applied to every instance, in the full style-object syntax — nested selectors, token references, at-rules, templates and resolved values.","teaches":"Everything the base style object accepts, including what happens to functions, promises and bare numbers","subsection":true,"frameworks":["react","next","astro"],"keywords":["base","nested selectors","token references","at-rules","defaultUnit","media queries"],"tags":["Reference","API"],"href":"/react/docs/reference/styled#base"},{"type":"docs","priority":0.3999999999999999,"title":"variants","description":"Each top-level key is an axis exposed as a typed prop — and variant props are consumed rather than forwarded, which is where the disabled trap comes from.","teaches":"How to declare variant axes and the DOM consequence of variant props not being forwarded","subsection":true,"frameworks":["react","next","astro"],"keywords":["variants","typed props","boolean variant","consumed props","disabled","html attribute collision"],"tags":["Reference","Variants"],"href":"/react/docs/reference/styled#variants"},{"type":"docs","priority":0.3999999999999999,"title":"anyOfVariants","description":"OR semantics for shared baselines, emitted inside :where() so they carry zero specificity and can never win a conflict.","teaches":"When a shared rule belongs in anyOfVariants versus compoundVariants or base","subsection":true,"frameworks":["react","next","astro"],"keywords":["anyOfVariants","or semantics","where selector","zero specificity","shared baseline"],"tags":["Reference","Variants"],"href":"/react/docs/reference/styled#any-of-variants"},{"type":"docs","priority":0.3999999999999999,"title":"passProps","description":"Opts variant props back into the set forwarded to the element — the fix for wrapping a component that needs a specific prop to function.","teaches":"How to forward variant props selectively and why a wrapped component may otherwise never receive href","subsection":true,"frameworks":["react","next","astro"],"keywords":["passProps","forwarding props","next link","href","router link","wrapped components"],"tags":["Reference","Composition"],"href":"/react/docs/reference/styled#pass-props"},{"type":"docs","priority":0.3999999999999999,"title":"priority","description":"Which cascade layer the rules land in, 0 to 8 — and the two non-obvious behaviors: wrapping auto-bumps and accumulates, and !important inverts layer order.","teaches":"How priority selects a cascade layer without touching the selector, and why extension always beats what it extends","subsection":true,"frameworks":["react","next","astro"],"keywords":["priority","cascade layers","l0 to l8","auto bump","important inversion","layer order"],"tags":["Reference","Cascade Layers"],"href":"/react/docs/reference/styled#priority"},{"type":"docs","priority":0.3999999999999999,"title":"base","description":"Styles applied everywhere the class is used, in the full style-object syntax — including arrays, which are joined with a comma.","teaches":"Everything the base style object accepts on className, including the array-joining behaviour","subsection":true,"frameworks":["react","next","astro"],"keywords":["base","nested selectors","token references","at-rules","arrays","defaultUnit"],"tags":["Reference","API"],"href":"/react/docs/reference/class-name#base"},{"type":"docs","priority":0.3999999999999999,"title":"variants","description":"Axes opted into by chaining .variant(), which appends a class and returns a new instance — and takes plain strings, so a typo is silent.","teaches":"How variants are activated without props, and why a helper wrapper is worth writing","subsection":true,"frameworks":["react","next","astro"],"keywords":["variants","variant chain","immutable","boolean variant","string value","typo safety"],"tags":["Reference","Variants"],"href":"/react/docs/reference/class-name#variants"},{"type":"docs","priority":0.3999999999999999,"title":"defaultVariants and the helper pattern","description":"Accepted by the type and never applied — because className hands you a string at build time and never sees the render.","teaches":"Why defaultVariants cannot work here and how to express defaults in a typed wrapper function instead","subsection":true,"frameworks":["react","next","astro"],"keywords":["defaultVariants","helper function","defaults","typed axes","wrapper pattern"],"tags":["Reference","Variants"],"href":"/react/docs/reference/class-name#default-variants"},{"type":"docs","priority":0.3999999999999999,"title":"priority","description":"The cascade layer the rules land in — and the two consequences that bite harder here than on styled, since nothing auto-bumps a class.","teaches":"Why a class always starts at layer 0 and what happens when a Salty class meets a Salty component","subsection":true,"frameworks":["react","next","astro"],"keywords":["priority","cascade layers","no auto bump","source order","class on component","important"],"tags":["Reference","Cascade Layers"],"href":"/react/docs/reference/class-name#priority"},{"type":"docs","priority":0.3999999999999999,"title":"Framework and integration detection","description":"Two separate detections: the framework decides which runtime package you get, integrations decide which config files get edited.","teaches":"Why detection surprises happen and what each integration edits","subsection":true,"frameworks":["react","next","astro"],"keywords":["framework detection","integrations","vite","next","webpack","astro","eslint"],"tags":["Reference","CLI"],"href":"/react/docs/reference/cli#frameworks-and-integrations"},{"type":"docs","priority":0.29999999999999993,"title":"The cl_ naming and the hash","description":"The filename carries your export name and the class inside is the bare hash, derived from the style object only — which is where deduplication comes from.","teaches":"How to map between an export name, a filename and an opaque class in DevTools","subsection":true,"frameworks":["react","next","astro"],"keywords":["cl_ prefix","export name","content hash","deduplication","rename","variant selectors"],"tags":["Get Started","Debugging"],"href":"/react/docs/getting-started/file-structure#cl-one-file-per-component"},{"type":"docs","priority":0.29999999999999993,"title":"The layer bundles","description":"Every component at one priority, concatenated into its cascade layer with fence markers that make incremental patching possible.","teaches":"How priority decides which bundle a component lands in, and what a missing l_ file means","subsection":true,"frameworks":["react","next","astro"],"keywords":["layer bundle","fence markers","priority","incremental patch","undeclared layer","importStrategy component"],"tags":["Get Started","Cascade Layers"],"href":"/react/docs/getting-started/file-structure#l-the-layer-bundles"}]