The cascade has historically been an arms race of specificity. @layer is the native CSS feature that ends the war by giving you explicit cascade ordering. Tailwind v4 builds on it.
What @layer is
@layer creates named groups in the cascade. Rules in a later-named layer beat earlier ones regardless of specificity. @layer reset, base, components, utilities; declares an explicit order — anything in utilities wins over anything in components, even if the components selector is longer.
Tailwind v4 uses three layers
When you write @import "tailwindcss", Tailwind sets up three layers internally: theme (your CSS variables from @theme), base (browser resets, defaults), components (slot for your custom component classes), utilities (the bg-brand, p-4 classes). Order is fixed; you add to the slots.
Why you'd add to a layer
Sometimes a Tailwind utility isn't enough — you need a named component class with multiple lines of CSS (e.g. an animation keyframe, a complex pseudo-element). Put it in @layer components so it sits in Tailwind's expected cascade position. Then in JSX you can still override with a utility (<button className="btn-primary px-6">) and Tailwind's utilities layer wins over your components layer.
The escape hatch
If you write a rule outside any layer, it lands after all layered rules in the cascade — meaning it beats everything by default (because unlayered rules are not in a layer). Avoid this for component CSS — use @layer components. Reserve it for genuine globals like third-party widget overrides where you need to win against the library's own rules.
.foo.foo.foo { color: red !important; } to win the cascade, layers are the answer. Put your rule in the right layer and the cascade resolves cleanly.