Hard Shadows Are a Constraint, Not a Style
When I redesigned my portfolio, I wrote a rule into the design system: shadows are solid color, fixed offset, zero blur, zero spread. No exceptions. The rule is Neo Brutalist in origin, but the interesting part is not the aesthetic. It is what the ban does to every decision that comes after it.
Blur is an escape hatch
Soft shadows work because blur hides imprecision. Two elements overlapping at an awkward angle look intentional under a diffused drop shadow. Weak spacing reads as considered negative space when a glowing halo wraps the card. Remove the blur and the offset is either right or obviously wrong. There is nowhere to hide.
The same logic applies to gradients and opacity. A gradient can smooth over a color pairing that has no real contrast logic. A semi-transparent overlay makes layering problems invisible. These are tools with legitimate uses, but they are also the design equivalent of tuning the reverb to cover a bad take.
When I banned all three, I expected the work to get harder. It did. I did not expect the resulting system to be more legible to everyone who looked at it.
Four tiers instead of infinite blur
With hard shadows, hierarchy has to come from things that actually carry meaning: spacing, scale, weight, and a small set of deliberate tiers.
My system has four:
--shadow-sm: 2px 2px 0 #000; /* tags, badges */
--shadow-md: 4px 4px 0 #000; /* cards, buttons */
--shadow-lg: 8px 8px 0 #000; /* featured cards */
--shadow-xl: 12px 12px 0 #000; /* modals, overlays */
Each offset is a statement. A 2px shadow says "minor supporting element." A 12px shadow says "this is the most important thing on the screen right now." There is no continuous dial to nudge until something looks vaguely right. You pick a tier and commit.
Compare this to a soft-shadow approach where the radius might drift from 4px to 6px to 8px across components without anyone noticing, and the visual hierarchy is a gradient rather than a decision.
What the linting actually catches
The concrete gain here is that the rules are binary. blur > 0 is a violation. alpha < 1 is a violation. Binary rules can be linted, not debated.
Soft-shadow systems produce design review conversations like: "Is the blur on that card a bit much?" "Maybe try 6px instead of 8px?" These are valid conversations. They are also slow, subjective, and drift-prone. With hard shadows the conversation is: "Is this a card-level element or a featured element?" That is a faster, more concrete question.
Spacing and contrast mistakes also surface immediately. When you remove the blurring and layering effects that typically soften rough edges, a 12px gap that should be 16px is visible at a glance. The system becomes self-auditing in a way that polished, effect-heavy systems are not.
The honest cost
Fewer escape hatches means the underlying structure has to be right. The soft tools are soft for a reason: some visual problems genuinely do require graduation, softness, or transparency. Long-form reading contexts, photography-adjacent layouts, dark-mode surfaces with fine grain detail: this system has to work harder in all of those cases.
I have had moments working within these constraints where the correct move was clearly to add a subtle gradient, and I could not. I found a structural fix instead, which took longer. Sometimes the structural fix was better. Sometimes it was just different.
The constraint does not make every outcome better. It makes every weakness visible, which is not the same thing.
Try banning one escape hatch
Pick the visual trick you reach for most often. For most people it is shadow blur. For others it is opacity layers. Ban it for a week on a personal project or a component you are rebuilding anyway.
What breaks is a map of where your layout was leaning on the effect rather than on structure. That map is useful. Some of what it reveals you will fix. Some of it will remind you why the escape hatch existed in the first place.
Either way, you will know your own work better for having removed the insulation.