There was no miracle ending this time for the Arizona Cardinals. The magic in the right arm of quarterback Kyler Murray was replaced by discomfort in his throwing shoulder.

The Seattle Seahawks and their quarterback, Russell Wilson, steadied themselves and moved into first place in the NFC West. Wilson threw two touchdown passes and benefited from an improved running game as the Seahawks beat the Cardinals, 28-21, Thursday night in Seattle.

The Seahawks also played better than expected on defense to end a two-game losing skid and improve their record to 7-3. They’re a half-game ahead of the Los Angeles Rams, who play Monday night at Tampa, and a game ahead of the Cardinals, whose dropped to 6-4.

“It was huge,” Wilson told Fox after the game. “I think for us to be able to play such great defense like that ... so many guys made so many plays. It was a great game.”

Murray and the Cardinals, seeking a tying touchdown, moved to the Seattle 27-yard line in the game’s final minute. But the drive stalled there and Seahawks defensive end Carlos Dunlap sacked Murray on a fourth-and-10 play with 34 seconds left to seal the outcome.

“Obviously Kyler’s made some great plays this season,” Wilson said. “Obviously he was coming off a Hail Mary last week. I’ve seen that before. ... It gets you a little bit nervous. But we played a great game. Obviously Carlos Dunlap making that last play, that’s why we brought him here — a huge, huge addition.”

The Cardinals had been the NFL’s new “it” team after Murray’s Hail Mary pass to wide receiver DeAndre Hopkins that beat the Buffalo Bills on Sunday. They’d also secured a dramatic victory over the Seahawks last month in Arizona on a field goal late in overtime. That game started a 1-3 downward spiral for the Seahawks. Wilson threw seven interceptions over those four games.

But Wilson threw no interceptions Thursday and had touchdown passes to DK Metcalf and fellow wide receiver Tyler Lockett. Tailback Carlos Hyde ran for a touchdown for the Seahawks, who rushed for 165 yards.

“We ran the ball extremely well today,” said Wilson, who completed 23 of 28 passes for 197 yards. “We threw it well. We made our plays. And it was great.”

The Seahawks entered the game ranked last in the NFL in total defense by a wide margin. They’d surrendered 519 total yards to the Cardinals (while getting 572 yards themselves) in the 37-34 defeat Oct. 25 in Arizona. The Cardinals had a far more modest 314 yards Thursday. They matched their season low in points.

“We were adjusted,” Seahawks Coach Pete Carroll said in a postgame video news conference. “We were ready. We took advantage of Carlos being part of it. And some of the situations, we moved some guys around. And it worked out really well.”

Dunlap, playing his third game for Seattle after being obtained in a trade with the Cincinnati Bengals, had two of the Seahawks’ three sacks Thursday of Murray, including the big one at game’s end.

“That’s what they brought me here for,” Dunlap said.

Said Carroll: “He’s been a boost. ... He really helps us, and we desperately needed him. ... He really is comfortable now, fits right in, and that was really thrilling to see him come up with the game-winner like that.”

Murray appeared to hurt his right shoulder while absorbing a hit early in the game. He was seen grimacing while making warm-up throws on the sideline soon after. Members of the Cardinals’ medical staff worked on Murray’s shoulder while he was on the sideline throughout the game.

“I know he landed on it that first drive,” Cardinals Coach Kliff Kingsbury said. “Like I said, I don’t know the extent to which it affected him. But I was proud of the way he toughed it out and continued to play and continued to try to help us win the game.”

Murray still threw for two touchdowns in a 29-for-42, 269-yard passing performance. His touchdowns went to tight end Dan Arnold and running back Chase Edmonds. Tailback Kenyan Drake had a rushing touchdown for Arizona.

“We put up 21, had a chance to win the game at the end,” Murray said. “We started off slow. We just kept shooting ourselves in the foot. They won the game but I think we can play a lot better.”

The Cardinals were penalized 10 times for 115 yards.

“You’re not going to win in this league doing that, especially against a quality team like Seattle,” Kingsbury said. “That’s unacceptable to have that many and we’ve got to clean that up.”

Murray expressed similar sentiments, saying: “It wasn’t a clean game, by any means. ... We’ve got to be better. We say every week: try to give ourselves the best possible chance to win the game. And that doesn’t help you.”

The Cardinals handed the Seahawks a fourth-quarter safety with a holding penalty in the end zone. The Seahawks added a field goal after the ensuing free kick to increase their lead to 28-21 with just more than two minutes remaining. That set up the game-winning drive that wasn’t, this time, for the Cardinals.

“We had our chances,” Murray said. “We just didn’t play well enough to win the game.”