Assuming you have a PRIMARY KEY or otherwise UNIQUE KEY called id (replace with whatever it's called in your table), consider the following query:
SELECT
cardnbr,
fname,
lname,
address,
city,
state,
postal
FROM
cards,
(
SELECT
GROUP_CONCAT(top_id_per_group) AS top_ids
FROM
(
SELECT
SUBSTRING_INDEX(GROUP_CONCAT(id ORDER BY lastvisit DESC), ',', 1) AS top_id_per_group
FROM
cards
GROUP BY
cardnbr
) s_top_ids_per_group
) s_top_codes
WHERE
FIND_IN_SET(id, top_ids)
ORDER BY
cardnbr
;
The idea is to get, per cardnbr, the id where the lastvisit is most recent. Then, get all row data for those ids.
The above is a simplification of Selecting Top N Records Per Group, where N = 1.
Another way to solve it is described in Selecting Non Aggregated Column Data in GROUP BY. The query presented in this post actually provides better performance than the above, but uses some parsing and casting to get the final results (all columns parsed as strings, then cast back to their original types). Also see this post. Apologies for the many links, but each post presents with a different solution to the problem.