South Africa slumped to their record lowest score in Sri Lanka after being bowled out for 126 as the hosts took control of the first Test in Galle.
Dilruwan Perera claimed four for 46 as Sri Lanka's spinners picked up seven of the Proteas' wickets, turning the tourists' overnight four for one into a nightmare innings.
The hosts then edged to 111 for four - opener Dimuth Karunaratne adding 60 to his brilliant 158 not out on Thursday - in their second innings at the end of day two, for a 272-run lead.
Veteran spinner Rangana Herath claimed two for 39, with Lakshan Sandakan taking the other wicket from slow bowling. Seamer Suranga Lakmal chipping in by bagging with three important victims of his own.
Captain Faf du Plessis battled to stop the rot with a gritty 49, but South Africa's second-highest scorer proved Vernon Philander with just 18.
The day started to slip away from the tourists right from the off, with nightwatchman Keshan Maharaj departing for just three to leave South Africa nine for two.
Dean Elgar quickly followed for eight to make it 13 for three, and it became 51 for six before Du Plessis was able to stop the rot, albeit little more than momentarily.
Maharaj was at least able to help the Proteas save some face with the ball, claiming three for 37 from 16 overs as Sri Lanka set about building a victorious position in their second innings.
Kagiso Rabada removed Karunaratne after the opener had built a smart half-century, leaving Angelo Mathews and Roshen Silva at the crease at stumps.