Good migration is not heroic rewrites. It is controlled improvement.
You should not need to pause delivery, rebuild the whole frontend,
or pretend the old CSS is not still in the room.
Ask this first
Ask first: Can this be safely replaced now?
Yes — replace properly.
No — contain it and improve around it.
Most migration mistakes come from trying to fix everything at once.
Decide whether the code should be replaced or safely contained.
Migration principles
Contain first
Put existing CSS somewhere predictable before changing how
new CSS is written.
Improve active code
Fix the CSS people touch every week, not the fossil no one
has opened since 2018.
Delete over time
Migration succeeds when legacy CSS gets smaller, not when it
gets renamed and promoted.
Recommended migration path
Introduce the layer order first.
Move old CSS into the legacy layer.
Put tokens and settings in the settings layer.
Move broad element defaults into base.
Write all new work as proper component partials.
Reduce selector depth when touching existing code.
Replace unclear names with semantic component ownership.
Use modifiers for variants and state classes for temporary state.
Move emergency fixes into hacks with comments.
Delete old CSS when the UI is replaced.
Common migration milestones
Milestone 1: Layer order is defined and legacy CSS is isolated.
Milestone 2: New component work follows naming, state, and token rules.
Milestone 3: Legacy selectors shrink release by release.
Milestone 4: Hacks are tracked and retired on a regular cadence.
Expected effort range
Small codebase: 1-3 sprints for a stable migration baseline.
Mid-size codebase: 1-2 quarters for broad consistency.
Large or multi-team codebase: phased migration over multiple quarters.
Step 1: define the cascade order
Add layer order before moving code. This gives the project a stable
override model immediately and stops specificity wars from breeding.