Galle, Sri Lanka: Opener Dimuth Karunaratne hit an unbeaten 158 to lift Sri Lanka to 287 all out against South Africa on day one of the first Test in Galle on Thursday.
Fast bowler Kagiso Rabada claimed four wickets to reduce Sri Lanka to 176-8 but Karunaratne gave the total respect with his 222-ball knock after the hosts elected to bat first.
The left-handed Karunaratne, who registered his eighth century in his 50th Test, built crucial partnerships including a 63-run 10th wicket stand with Lakshan Sandakan, who made 25.
In response South Africa were in trouble at four for one at stumps after veteran spinner Rangana Herath got Aiden Markram out for nought.
Dean Elgar, on four, and nightwatchman Keshav Maharaj were at the crease at close of play on a tough day's cricket that saw rain in the afternoon and an extended final session.
The day belonged to Karunaratne who stood tall during his marathon stand after Rabada and then left-arm wrist spinner Tabraiz Shamsi tore into the Sri Lankan middle-order.
Rabada, who came back after an injury, returned figures of 4-50, while Shamsi took three wickets on a seemingly turning sub-continent pitch.
Rabada had made the first breakthrough for South Africa, dismissing Danushka Gunathilaka with a delivery that rose sharply and got the batsman caught behind for 26.
He then struck twice in his sixth over of the day, removing Angelo Mathews, for one, and Roshen Silva, for nought, shortly after lunch.
Those two wickets came towards the start of Sri Lanka's middle-order, when they lost six wickets for 61 runs, slipping from a relatively comfortable 115-2.
But Karunaratne rarely attempted to counterattack, preferring instead to steadily build his innings, which featured 13 fours and an impressive six off Dale Steyn in the first session.
He completed his ton with a boundary off Shamsi and then moved to 150 for the fourth time in his Test career.
South Africa skipper Faf du Plessis was forced to rotate his regular bowling options as Karunaratne played sensible cricket with the tail-enders.
Stand-in-captain Suranga Lakmal also fought with Karunaratne during their 48-run ninth wicket stand that frustrated the bowling side.
Sri Lanka's regular captain Dinesh Chandimal is suspended for the two-match series, after pleading guilty to breaching the spirit of cricket during the team's Test tour of West Indies last month.