diff --git a/src/view/netkeywidget.cpp b/src/view/netkeywidget.cpp
index 6389b6ecd..84c77de0b 100644
--- a/src/view/netkeywidget.cpp
+++ b/src/view/netkeywidget.cpp
@@ -1,282 +1,248 @@
 /*  view/netkeywidget.cpp
 
     This file is part of Kleopatra, the KDE keymanager
     SPDX-FileCopyrightText: 2017 Intevation GmbH
 
     SPDX-License-Identifier: GPL-2.0-or-later
 */
 #include "netkeywidget.h"
 
 #include "cardkeysview.h"
 #include "kleopatraapplication.h"
 #include "nullpinwidget.h"
 #include "systrayicon.h"
 
 #include "kleopatra_debug.h"
 
 #include "smartcard/netkeycard.h"
 #include "smartcard/readerstatus.h"
 
 #include "commands/changepincommand.h"
 #include "commands/createcsrforcardkeycommand.h"
 #include "commands/createopenpgpkeyfromcardkeyscommand.h"
 
 #include <Libkleo/Algorithm>
 #include <Libkleo/Compliance>
 #include <Libkleo/Debug>
 #include <Libkleo/KeyCache>
 #include <Libkleo/KeyHelpers>
 #include <Libkleo/KeyListModel>
 
 #include <KLocalizedString>
 #include <KMessageBox>
 #include <KSeparator>
 
 #include <QHBoxLayout>
 #include <QInputDialog>
 #include <QLabel>
 #include <QPushButton>
-#include <QScrollArea>
 #include <QVBoxLayout>
 
 #include <gpgme++/engineinfo.h>
 
 using namespace Kleo;
 using namespace Kleo::SmartCard;
 using namespace Kleo::Commands;
 
 NetKeyWidget::NetKeyWidget(QWidget *parent)
     : SmartCardWidget(parent)
 {
-    auto vLay = new QVBoxLayout;
-
-    // Set up the scroll are
-    mArea = new QScrollArea{this};
-    mArea->setFocusPolicy(Qt::NoFocus);
-    mArea->setFrameShape(QFrame::NoFrame);
-    mArea->setWidgetResizable(true);
-    auto mAreaWidget = new QWidget;
-    mAreaWidget->setLayout(vLay);
-    mArea->setWidget(mAreaWidget);
-    auto scrollLay = new QVBoxLayout(this);
-    scrollLay->setContentsMargins(0, 0, 0, 0);
-    scrollLay->addWidget(mArea);
-
-    // Add general widgets
-    mVersionLabel = new QLabel{this};
-    mVersionLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
-    vLay->addWidget(mVersionLabel, 0, Qt::AlignLeft);
-
-    {
-        auto hLay1 = new QHBoxLayout;
-        auto label = new QLabel(i18nc("@label", "Serial number:"));
-        mSerialNumberLabel = new QLabel{this};
-        mSerialNumberLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
-        label->setBuddy(mSerialNumberLabel);
-        hLay1->addWidget(label);
-        hLay1->addWidget(mSerialNumberLabel);
-        hLay1->addStretch(1);
-        vLay->addLayout(hLay1);
-    }
-
     mNullPinWidget = new NullPinWidget{this};
-    vLay->addWidget(mNullPinWidget);
+    mContentLayout->addWidget(mNullPinWidget);
 
     mErrorLabel = new QLabel{this};
     mErrorLabel->setVisible(false);
-    vLay->addWidget(mErrorLabel);
+    mContentLayout->addWidget(mErrorLabel);
 
-    vLay->addWidget(new KSeparator(Qt::Horizontal));
+    mContentLayout->addWidget(new KSeparator(Qt::Horizontal));
 
     mCardKeysView = new CardKeysView{this};
-    vLay->addWidget(mCardKeysView);
+    mContentLayout->addWidget(mCardKeysView);
 
     // The action area
-    vLay->addWidget(new KSeparator(Qt::Horizontal));
-    vLay->addWidget(new QLabel(QStringLiteral("<b>%1</b>").arg(i18n("Actions:"))), 0, Qt::AlignLeft);
+    mContentLayout->addWidget(new KSeparator(Qt::Horizontal));
+    mContentLayout->addWidget(new QLabel(QStringLiteral("<b>%1</b>").arg(i18n("Actions:"))), 0, Qt::AlignLeft);
 
     auto actionLayout = new QHBoxLayout();
 
     if (CreateOpenPGPKeyFromCardKeysCommand::isSupported()) {
         mKeyForCardKeysButton = new QPushButton(this);
         mKeyForCardKeysButton->setText(i18nc("@action:button", "Create OpenPGP Key"));
         mKeyForCardKeysButton->setToolTip(i18nc("@info:tooltip", "Create an OpenPGP key for the keys stored on the card."));
         actionLayout->addWidget(mKeyForCardKeysButton);
         connect(mKeyForCardKeysButton, &QPushButton::clicked, this, &NetKeyWidget::createKeyFromCardKeys);
     }
 
     if (!(engineInfo(GpgME::GpgSMEngine).engineVersion() < "2.2.26")) { // see https://dev.gnupg.org/T5184
         mCreateCSRButton = new QPushButton(this);
         mCreateCSRButton->setText(i18nc("@action:button", "Create CSR"));
         mCreateCSRButton->setToolTip(i18nc("@info:tooltip", "Create a certificate signing request for a key stored on the card."));
         mCreateCSRButton->setEnabled(false);
         actionLayout->addWidget(mCreateCSRButton);
         connect(mCreateCSRButton, &QPushButton::clicked, this, [this]() {
             createCSR();
         });
     }
 
     mChangeNKSPINBtn = new QPushButton{this};
     mChangeNKSPINBtn->setText(i18nc("@action:button NKS is an identifier for a type of keys on a NetKey card", "Change NKS PIN"));
     mChangeSigGPINBtn = new QPushButton{this};
     mChangeSigGPINBtn->setText(i18nc("@action:button SigG is an identifier for a type of keys on a NetKey card", "Change SigG PIN"));
 
     connect(mChangeNKSPINBtn, &QPushButton::clicked, this, [this]() {
         doChangePin(NetKeyCard::nksPinKeyRef());
     });
     connect(mChangeSigGPINBtn, &QPushButton::clicked, this, [this]() {
         doChangePin(NetKeyCard::sigGPinKeyRef());
     });
 
     actionLayout->addWidget(mChangeNKSPINBtn);
     actionLayout->addWidget(mChangeSigGPINBtn);
     actionLayout->addStretch(1);
 
-    vLay->addLayout(actionLayout);
-    vLay->addStretch(1);
+    mContentLayout->addLayout(actionLayout);
+    mContentLayout->addStretch(1);
 }
 
 NetKeyWidget::~NetKeyWidget() = default;
 
 namespace
 {
 std::vector<KeyPairInfo> getKeysSuitableForCSRCreation(const NetKeyCard *netKeyCard)
 {
     if (netKeyCard->hasNKSNullPin()) {
         return {};
     }
 
     std::vector<KeyPairInfo> keys;
     Kleo::copy_if(netKeyCard->keyInfos(), std::back_inserter(keys), [](const auto &keyInfo) {
         if (keyInfo.keyRef.substr(0, 9) == "NKS-SIGG.") {
             // SigG certificates for qualified signatures are issued with the physical cards;
             // it's not possible to request a certificate for them
             return false;
         }
         return keyInfo.canSign() //
             && (keyInfo.keyRef.substr(0, 9) == "NKS-NKS3.") //
             && DeVSCompliance::algorithmIsCompliant(keyInfo.algorithm);
     });
 
     return keys;
 }
 }
 
 void NetKeyWidget::setCard(const NetKeyCard *card)
 {
-    mSerialNumber = card->serialNumber();
-    mVersionLabel->setText(i18nc("1 is a Version number", "NetKey v%1 Card", card->appVersion()));
-    mSerialNumberLabel->setText(card->displaySerialNumber());
+    SmartCardWidget::setCard(card);
 
     mNullPinWidget->setSerialNumber(mSerialNumber);
     /* According to users of NetKey Cards it is fairly uncommon
      * to use SigG Certificates at all. So it should be optional to set the pins. */
     mNullPinWidget->setVisible(card->hasNKSNullPin() /*|| card->hasSigGNullPin()*/);
 
     mNullPinWidget->setSigGVisible(false /*card->hasSigGNullPin()*/);
     mNullPinWidget->setNKSVisible(card->hasNKSNullPin());
     mChangeNKSPINBtn->setEnabled(!card->hasNKSNullPin());
 
     if (card->hasSigGNullPin()) {
         mChangeSigGPINBtn->setText(i18nc("SigG is an identifier for a type of keys on a NetKey card", "Set SigG PIN"));
     } else {
         mChangeSigGPINBtn->setText(i18nc("SigG is an identifier for a type of keys on a NetKey card", "Change SigG PIN"));
     }
 
     const auto errMsg = card->errorMsg();
     if (!errMsg.isEmpty()) {
         mErrorLabel->setText(QStringLiteral("<b>%1:</b> %2").arg(i18n("Error"), errMsg));
         mErrorLabel->setVisible(true);
     } else {
         mErrorLabel->setVisible(false);
     }
 
     if (mKeyForCardKeysButton) {
         mKeyForCardKeysButton->setEnabled(!card->hasNKSNullPin() && card->hasSigningKey() && card->hasEncryptionKey()
                                           && DeVSCompliance::algorithmIsCompliant(card->keyInfo(card->signingKeyRef()).algorithm)
                                           && DeVSCompliance::algorithmIsCompliant(card->keyInfo(card->encryptionKeyRef()).algorithm));
     }
     if (mCreateCSRButton) {
         mCreateCSRButton->setEnabled(!getKeysSuitableForCSRCreation(card).empty());
     }
 
     mCardKeysView->setCard(card);
 }
 
 void NetKeyWidget::doChangePin(const std::string &keyRef)
 {
     const auto netKeyCard = ReaderStatus::instance()->getCard<NetKeyCard>(mSerialNumber);
     if (!netKeyCard) {
         KMessageBox::error(this, i18n("Failed to find the smartcard with the serial number: %1", QString::fromStdString(mSerialNumber)));
         return;
     }
 
     auto cmd = new ChangePinCommand(mSerialNumber, NetKeyCard::AppName, this);
     this->setEnabled(false);
     connect(cmd, &ChangePinCommand::finished, this, [this]() {
         this->setEnabled(true);
     });
     cmd->setKeyRef(keyRef);
     if ((keyRef == NetKeyCard::nksPinKeyRef() && netKeyCard->hasNKSNullPin()) //
         || (keyRef == NetKeyCard::sigGPinKeyRef() && netKeyCard->hasSigGNullPin())) {
         cmd->setMode(ChangePinCommand::NullPinMode);
     }
     cmd->start();
 }
 
 void NetKeyWidget::createKeyFromCardKeys()
 {
     auto cmd = new CreateOpenPGPKeyFromCardKeysCommand(mSerialNumber, NetKeyCard::AppName, this);
     this->setEnabled(false);
     connect(cmd, &CreateOpenPGPKeyFromCardKeysCommand::finished, this, [this]() {
         this->setEnabled(true);
     });
     cmd->start();
 }
 
 namespace
 {
 std::string getKeyRef(const std::vector<KeyPairInfo> &keys, QWidget *parent)
 {
     QStringList options;
     for (const auto &key : keys) {
         options << QStringLiteral("%1 - %2").arg(QString::fromStdString(key.keyRef), QString::fromStdString(key.grip));
     }
 
     bool ok;
     const QString choice = QInputDialog::getItem(parent,
                                                  i18n("Select Key"),
                                                  i18n("Please select the key you want to create a certificate signing request for:"),
                                                  options,
                                                  /* current= */ 0,
                                                  /* editable= */ false,
                                                  &ok);
     return ok ? keys[options.indexOf(choice)].keyRef : std::string();
 }
 }
 
 void NetKeyWidget::createCSR()
 {
     const auto netKeyCard = ReaderStatus::instance()->getCard<NetKeyCard>(mSerialNumber);
     if (!netKeyCard) {
         KMessageBox::error(this, i18n("Failed to find the smartcard with the serial number: %1", QString::fromStdString(mSerialNumber)));
         return;
     }
     const auto suitableKeys = getKeysSuitableForCSRCreation(netKeyCard.get());
     if (suitableKeys.empty()) {
         KMessageBox::error(this, i18n("Sorry! No keys suitable for creating a certificate signing request found on the smartcard."));
         return;
     }
     const auto keyRef = getKeyRef(suitableKeys, this);
     if (keyRef.empty()) {
         return;
     }
     auto cmd = new CreateCSRForCardKeyCommand(keyRef, mSerialNumber, NetKeyCard::AppName, this);
     this->setEnabled(false);
     connect(cmd, &CreateCSRForCardKeyCommand::finished, this, [this]() {
         this->setEnabled(true);
     });
     cmd->start();
 }
 
 #include "moc_netkeywidget.cpp"
diff --git a/src/view/netkeywidget.h b/src/view/netkeywidget.h
index b98149cd8..41216bcd2 100644
--- a/src/view/netkeywidget.h
+++ b/src/view/netkeywidget.h
@@ -1,60 +1,56 @@
 /*  view/netkeywidget.h
 
     This file is part of Kleopatra, the KDE keymanager
     SPDX-FileCopyrightText: 2017 Intevation GmbH
 
     SPDX-License-Identifier: GPL-2.0-or-later
 */
 #pragma once
 
 #include "smartcardwidget.h"
 
 #include <Libkleo/Predicates>
 
 #include <gpgme++/error.h>
 
 #include <set>
 #include <string>
 #include <vector>
 
 class QLabel;
 class QPushButton;
-class QScrollArea;
 
 namespace Kleo
 {
 class NullPinWidget;
 class CardKeysView;
 
 namespace SmartCard
 {
 class NetKeyCard;
 }
 
 class NetKeyWidget : public SmartCardWidget
 {
     Q_OBJECT
 public:
     explicit NetKeyWidget(QWidget *parent = nullptr);
     ~NetKeyWidget() override;
 
     void setCard(const SmartCard::NetKeyCard *card);
 
 private:
     void doChangePin(const std::string &keyRef);
     void createKeyFromCardKeys();
     void createCSR();
 
 private:
-    QLabel *mSerialNumberLabel = nullptr;
-    QLabel *mVersionLabel = nullptr;
     QLabel *mErrorLabel = nullptr;
     NullPinWidget *mNullPinWidget = nullptr;
     QPushButton *mKeyForCardKeysButton = nullptr;
     QPushButton *mCreateCSRButton = nullptr;
     QPushButton *mChangeNKSPINBtn = nullptr;
     QPushButton *mChangeSigGPINBtn = nullptr;
     CardKeysView *mCardKeysView = nullptr;
-    QScrollArea *mArea = nullptr;
 };
 } // namespace Kleo
diff --git a/src/view/p15cardwidget.cpp b/src/view/p15cardwidget.cpp
index 254f32d54..ee48478c6 100644
--- a/src/view/p15cardwidget.cpp
+++ b/src/view/p15cardwidget.cpp
@@ -1,187 +1,150 @@
 /*  view/p15cardwiget.cpp
 
     This file is part of Kleopatra, the KDE keymanager
     SPDX-FileCopyrightText: 2021 g10 Code GmbH
     SPDX-FileContributor: Andre Heinecke <aheinecke@g10code.com>
     SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
 
     SPDX-License-Identifier: GPL-2.0-or-later
 */
 
 #include "p15cardwidget.h"
 
 #include "cardkeysview.h"
 #include "openpgpkeycardwidget.h"
 
 #include "settings.h"
 
 #include "smartcard/openpgpcard.h"
 #include "smartcard/p15card.h"
 #include "smartcard/readerstatus.h"
 
-#include <QGridLayout>
 #include <QLabel>
 #include <QPushButton>
-#include <QScrollArea>
 #include <QStringList>
 #include <QVBoxLayout>
 
 #include <KLocalizedString>
 #include <KSeparator>
 
 #include <Libkleo/Compat>
 #include <Libkleo/Formatting>
 #include <Libkleo/GnuPG>
 #include <Libkleo/KeyCache>
 
 #include <QGpgME/CryptoConfig>
 #include <QGpgME/ImportFromKeyserverJob>
 #include <QGpgME/KeyListJob>
 #include <QGpgME/Protocol>
 
 #include <gpgme++/importresult.h>
 #include <gpgme++/keylistresult.h>
 
 #include "kleopatra_debug.h"
 
 using namespace Kleo;
 using namespace Kleo::SmartCard;
 
 P15CardWidget::P15CardWidget(QWidget *parent)
     : SmartCardWidget{parent}
 {
-    // Set up the scroll area
-    auto myLayout = new QVBoxLayout(this);
-    myLayout->setContentsMargins(0, 0, 0, 0);
-
-    auto area = new QScrollArea;
-    area->setFocusPolicy(Qt::NoFocus);
-    area->setFrameShape(QFrame::NoFrame);
-    area->setWidgetResizable(true);
-    myLayout->addWidget(area);
-
-    auto areaWidget = new QWidget;
-    area->setWidget(areaWidget);
-
-    auto areaVLay = new QVBoxLayout(areaWidget);
-
-    auto cardInfoGrid = new QGridLayout;
-    {
-        int row = 0;
-
-        // Version and Serialnumber
-        mVersionLabel = new QLabel{this};
-        mVersionLabel->setTextInteractionFlags(Qt::TextBrowserInteraction | Qt::TextSelectableByKeyboard);
-        cardInfoGrid->addWidget(mVersionLabel, row++, 0, 1, 2);
-
-        cardInfoGrid->addWidget(new QLabel(i18nc("@label:textbox", "Serial number:")), row, 0);
-        mSerialNumberLabel = new QLabel{this};
-        mSerialNumberLabel->setTextInteractionFlags(Qt::TextBrowserInteraction | Qt::TextSelectableByKeyboard);
-        cardInfoGrid->addWidget(mSerialNumberLabel, row++, 1);
-
-        cardInfoGrid->setColumnStretch(cardInfoGrid->columnCount(), 1);
-    }
-    areaVLay->addLayout(cardInfoGrid);
     mStatusLabel = new QLabel{this};
     mStatusLabel->setVisible(false);
-    areaVLay->addWidget(mStatusLabel);
+    mContentLayout->addWidget(mStatusLabel);
 
-    areaVLay->addWidget(new KSeparator(Qt::Horizontal));
+    mContentLayout->addWidget(new KSeparator(Qt::Horizontal));
 
     mOpenPGPKeysSection = new QWidget{this};
     {
         auto l = new QVBoxLayout{mOpenPGPKeysSection};
         l->setContentsMargins(0, 0, 0, 0);
         l->addWidget(new QLabel(QStringLiteral("<b>%1</b>").arg(i18n("OpenPGP keys:"))));
         mOpenPGPKeysWidget = new OpenPGPKeyCardWidget{this};
         mOpenPGPKeysWidget->setAllowedActions(OpenPGPKeyCardWidget::NoAction);
         l->addWidget(mOpenPGPKeysWidget);
         l->addWidget(new KSeparator(Qt::Horizontal));
     }
     mOpenPGPKeysSection->setVisible(false);
-    areaVLay->addWidget(mOpenPGPKeysSection);
+    mContentLayout->addWidget(mOpenPGPKeysSection);
 
     mCardKeysView = new CardKeysView{this};
     mCardKeysView->setVisible(false);
-    areaVLay->addWidget(mCardKeysView);
+    mContentLayout->addWidget(mCardKeysView);
 
-    areaVLay->addStretch(1);
+    mContentLayout->addStretch(1);
 }
 
 P15CardWidget::~P15CardWidget() = default;
 
 void P15CardWidget::searchPGPFpr(const std::string &fpr)
 {
     /* Only do auto import from LDAP */
     auto conf = QGpgME::cryptoConfig();
     Q_ASSERT(conf);
     if (!Settings().alwaysSearchCardOnKeyserver() && !Kleo::keyserver().startsWith(QLatin1StringView{"ldap"})) {
         return;
     }
     mStatusLabel->setText(i18n("Searching in directory service..."));
     mStatusLabel->setVisible(true);
     qCDebug(KLEOPATRA_LOG) << "Looking for:" << fpr.c_str() << "on ldap server";
     QGpgME::KeyListJob *job = QGpgME::openpgp()->keyListJob(true);
     connect(KeyCache::instance().get(), &KeyCache::keysMayHaveChanged, this, [this, fpr]() {
         qCDebug(KLEOPATRA_LOG) << "Updating key info after changes";
         ReaderStatus::mutableInstance()->updateStatus();
         mOpenPGPKeysWidget->update(nullptr);
     });
     connect(job, &QGpgME::KeyListJob::result, job, [this](GpgME::KeyListResult, std::vector<GpgME::Key> keys, QString, GpgME::Error) {
         if (keys.size() == 1) {
             auto importJob = QGpgME::openpgp()->importFromKeyserverJob();
             qCDebug(KLEOPATRA_LOG) << "Importing: " << keys[0].primaryFingerprint();
             connect(importJob, &QGpgME::ImportFromKeyserverJob::result, importJob, [this](GpgME::ImportResult, QString, GpgME::Error) {
                 qCDebug(KLEOPATRA_LOG) << "import job done";
                 mStatusLabel->setText(i18n("Automatic import finished."));
             });
             importJob->start(keys);
         } else if (keys.size() > 1) {
             qCDebug(KLEOPATRA_LOG) << "Multiple keys found on server";
             mStatusLabel->setText(i18n("Error multiple keys found on server."));
         } else {
             qCDebug(KLEOPATRA_LOG) << "No key found";
             mStatusLabel->setText(i18n("Key not found in directory service."));
         }
     });
     job->start(QStringList() << QString::fromStdString(fpr));
 }
 
 void P15CardWidget::setCard(const P15Card *card)
 {
-    mSerialNumber = card->serialNumber();
-    mVersionLabel->setText(i18nc("%1 is a smartcard manufacturer", "%1 PKCS#15 card", QString::fromStdString(card->manufacturer())));
-    mSerialNumberLabel->setText(card->displaySerialNumber());
-    mSerialNumberLabel->setToolTip(QString::fromStdString(card->serialNumber()));
+    SmartCardWidget::setCard(card);
 
     const auto sigInfo = card->keyInfo(card->signingKeyRef());
     if (!sigInfo.grip.empty()) {
         const auto key = KeyCache::instance()->findSubkeyByKeyGrip(sigInfo.grip, GpgME::OpenPGP).parent();
         if (key.isNull()) {
             qCDebug(KLEOPATRA_LOG) << "Failed to find key for grip:" << sigInfo.grip.c_str();
             const auto pgpSigFpr = card->keyFingerprint(OpenPGPCard::pgpSigKeyRef());
             if (!pgpSigFpr.empty()) {
                 qCDebug(KLEOPATRA_LOG) << "Should be pgp key:" << pgpSigFpr.c_str();
                 searchPGPFpr(pgpSigFpr);
             }
         } else {
             mStatusLabel->setVisible(false);
         }
     }
 
     const bool cardHasOpenPGPKeys = (!card->keyFingerprint(OpenPGPCard::pgpSigKeyRef()).empty() //
                                      || !card->keyFingerprint(OpenPGPCard::pgpEncKeyRef()).empty());
     mOpenPGPKeysSection->setVisible(cardHasOpenPGPKeys);
     if (cardHasOpenPGPKeys) {
         mOpenPGPKeysWidget->update(card);
     }
 
     /* Check if additional keys could be available */
     if (!Settings().autoLoadP15Certs()) {
         return;
     }
     mCardKeysView->setVisible(true);
     mCardKeysView->setCard(card);
 }
 
 #include "moc_p15cardwidget.cpp"
diff --git a/src/view/p15cardwidget.h b/src/view/p15cardwidget.h
index 26a494025..716fdffc9 100644
--- a/src/view/p15cardwidget.h
+++ b/src/view/p15cardwidget.h
@@ -1,47 +1,45 @@
 /*  view/p15cardwiget.h
 
     This file is part of Kleopatra, the KDE keymanager
     SPDX-FileCopyrightText: 2021 g10 Code GmbH
     SPDX-FileContributor: Andre Heinecke <aheinecke@g10code.com>
     SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
 
     SPDX-License-Identifier: GPL-2.0-or-later
 */
 #pragma once
 
 #include "smartcardwidget.h"
 
 class QLabel;
 
 namespace Kleo
 {
 class CardKeysView;
 class OpenPGPKeyCardWidget;
 
 namespace SmartCard
 {
 class P15Card;
 }
 
 class P15CardWidget : public SmartCardWidget
 {
     Q_OBJECT
 public:
     explicit P15CardWidget(QWidget *parent = nullptr);
     ~P15CardWidget() override;
 
     void setCard(const SmartCard::P15Card *card);
 
 private:
     void searchPGPFpr(const std::string &fpr);
 
 private:
-    QLabel *mVersionLabel = nullptr;
-    QLabel *mSerialNumberLabel = nullptr;
     QLabel *mStatusLabel = nullptr;
     QWidget *mOpenPGPKeysSection = nullptr;
     OpenPGPKeyCardWidget *mOpenPGPKeysWidget = nullptr;
     CardKeysView *mCardKeysView = nullptr;
 };
 
 }
diff --git a/src/view/pgpcardwidget.cpp b/src/view/pgpcardwidget.cpp
index f955e528b..cf467bbe4 100644
--- a/src/view/pgpcardwidget.cpp
+++ b/src/view/pgpcardwidget.cpp
@@ -1,573 +1,536 @@
 /*  view/pgpcardwiget.cpp
 
     This file is part of Kleopatra, the KDE keymanager
     SPDX-FileCopyrightText: 2017 Bundesamt für Sicherheit in der Informationstechnik
     SPDX-FileContributor: Intevation GmbH
     SPDX-FileCopyrightText: 2020, 2022 g10 Code GmbH
     SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
 
     SPDX-License-Identifier: GPL-2.0-or-later
 */
 
 #include <config-kleopatra.h>
 
 #include "pgpcardwidget.h"
 
 #include "openpgpkeycardwidget.h"
 
 #include "kleopatra_debug.h"
 
 #include "commands/createcsrforcardkeycommand.h"
 #include "commands/openpgpgeneratecardkeycommand.h"
 
 #include "smartcard/algorithminfo.h"
 #include "smartcard/openpgpcard.h"
 #include "smartcard/readerstatus.h"
 #include "smartcard/utils.h"
 
 #include "dialogs/gencardkeydialog.h"
 
 #include <Libkleo/Compliance>
 #include <Libkleo/GnuPG>
 
 #include <QFileDialog>
 #include <QFileInfo>
 #include <QGridLayout>
 #include <QHBoxLayout>
 #include <QInputDialog>
 #include <QLabel>
 #include <QProgressDialog>
 #include <QPushButton>
-#include <QScrollArea>
 #include <QThread>
 #include <QVBoxLayout>
 
 #include <KLocalizedString>
 #include <KMessageBox>
 #include <KSeparator>
 
 #include <Libkleo/Formatting>
 #include <Libkleo/KeyCache>
 
 #include <gpgme++/context.h>
 #include <gpgme++/data.h>
 
 #include <QGpgME/DataProvider>
 
 #include <gpgme++/gpggencardkeyinteractor.h>
 
 using namespace Kleo;
 using namespace Kleo::Commands;
 using namespace Kleo::SmartCard;
 
 namespace
 {
 class GenKeyThread : public QThread
 {
     Q_OBJECT
 
 public:
     explicit GenKeyThread(const GenCardKeyDialog::KeyParams &params, const std::string &serial)
         : mSerial(serial)
         , mParams(params)
     {
     }
 
     GpgME::Error error()
     {
         return mErr;
     }
 
     std::string bkpFile()
     {
         return mBkpFile;
     }
 
 protected:
     void run() override
     {
         // the index of the curves in this list has to match the enum values
         // minus 1 of GpgGenCardKeyInteractor::Curve
         static const std::vector<std::string> curves = {
             "curve25519",
             "curve448",
             "nistp256",
             "nistp384",
             "nistp521",
             "brainpoolP256r1",
             "brainpoolP384r1",
             "brainpoolP512r1",
             "secp256k1", // keep it, even if we don't support it in Kleopatra
         };
 
         auto ei = std::make_unique<GpgME::GpgGenCardKeyInteractor>(mSerial);
         if (mParams.algorithm.starts_with("rsa")) {
             ei->setAlgo(GpgME::GpgGenCardKeyInteractor::RSA);
             ei->setKeySize(QByteArray::fromStdString(mParams.algorithm.substr(3)).toInt());
         } else {
             ei->setAlgo(GpgME::GpgGenCardKeyInteractor::ECC);
             const auto curveIt = std::find(curves.cbegin(), curves.cend(), mParams.algorithm);
             if (curveIt != curves.end()) {
                 ei->setCurve(static_cast<GpgME::GpgGenCardKeyInteractor::Curve>(curveIt - curves.cbegin() + 1));
             } else {
                 qCWarning(KLEOPATRA_LOG) << this << __func__ << "Invalid curve name:" << mParams.algorithm;
                 mErr = GpgME::Error::fromCode(GPG_ERR_INV_VALUE);
                 return;
             }
         }
         ei->setNameUtf8(mParams.name.toStdString());
         ei->setEmailUtf8(mParams.email.toStdString());
         ei->setDoBackup(mParams.backup);
 
         const auto ctx = std::shared_ptr<GpgME::Context>(GpgME::Context::createForProtocol(GpgME::OpenPGP));
         ctx->setFlag("extended-edit", "1"); // we want to be able to select all curves
         QGpgME::QByteArrayDataProvider dp;
         GpgME::Data data(&dp);
 
         mErr = ctx->cardEdit(GpgME::Key(), std::move(ei), data);
         mBkpFile = static_cast<GpgME::GpgGenCardKeyInteractor *>(ctx->lastCardEditInteractor())->backupFileName();
     }
 
 private:
     GpgME::Error mErr;
     std::string mSerial;
     GenCardKeyDialog::KeyParams mParams;
 
     std::string mBkpFile;
 };
 
 } // Namespace
 
 PGPCardWidget::PGPCardWidget(QWidget *parent)
     : SmartCardWidget(parent)
 {
-    // Set up the scroll area
-    auto myLayout = new QVBoxLayout(this);
-    myLayout->setContentsMargins(0, 0, 0, 0);
-
-    auto area = new QScrollArea;
-    area->setFocusPolicy(Qt::NoFocus);
-    area->setFrameShape(QFrame::NoFrame);
-    area->setWidgetResizable(true);
-    myLayout->addWidget(area);
-
-    auto areaWidget = new QWidget;
-    area->setWidget(areaWidget);
-
-    auto areaVLay = new QVBoxLayout(areaWidget);
-
-    auto cardInfoGrid = new QGridLayout;
     {
-        int row = 0;
-
-        // Version and Serialnumber
-        mVersionLabel = new QLabel{this};
-        mVersionLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
-        cardInfoGrid->addWidget(mVersionLabel, row, 0, 1, 2);
-        row++;
-
-        cardInfoGrid->addWidget(new QLabel(i18nc("@label:textbox", "Serial number:")), row, 0);
-        mSerialNumberLabel = new QLabel{this};
-        mSerialNumberLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
-        cardInfoGrid->addWidget(mSerialNumberLabel, row, 1);
-        row++;
+        mInfoGridLayout->setColumnStretch(mInfoGridLayout->columnCount() - 1, 0); // undo stretch set by base widget
+        int row = mInfoGridLayout->rowCount();
 
         // Cardholder Row
-        cardInfoGrid->addWidget(new QLabel(i18nc("The owner of a smartcard. GnuPG refers to this as cardholder.", "Cardholder:")), row, 0);
+        mInfoGridLayout->addWidget(new QLabel(i18nc("The owner of a smartcard. GnuPG refers to this as cardholder.", "Cardholder:")), row, 0);
         mCardHolderLabel = new QLabel{this};
         mCardHolderLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
-        cardInfoGrid->addWidget(mCardHolderLabel, row, 1);
+        mInfoGridLayout->addWidget(mCardHolderLabel, row, 1);
         {
             auto button = new QPushButton{this};
             button->setIcon(QIcon::fromTheme(QStringLiteral("cell_edit")));
             button->setAccessibleName(i18nc("@action:button", "Edit"));
             button->setToolTip(i18nc("@info:tooltip", "Change"));
-            cardInfoGrid->addWidget(button, row, 2);
+            mInfoGridLayout->addWidget(button, row, 2);
             connect(button, &QPushButton::clicked, this, &PGPCardWidget::changeNameRequested);
         }
         row++;
 
         // URL Row
-        cardInfoGrid->addWidget(new QLabel(i18nc("The URL under which a public key that "
-                                                 "corresponds to a smartcard can be downloaded",
-                                                 "Pubkey URL:")),
-                                row,
-                                0);
+        mInfoGridLayout->addWidget(new QLabel(i18nc("The URL under which a public key that "
+                                                    "corresponds to a smartcard can be downloaded",
+                                                    "Pubkey URL:")),
+                                   row,
+                                   0);
         mUrlLabel = new QLabel{this};
         mUrlLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
-        cardInfoGrid->addWidget(mUrlLabel, row, 1);
+        mInfoGridLayout->addWidget(mUrlLabel, row, 1);
         {
             auto button = new QPushButton{this};
             button->setIcon(QIcon::fromTheme(QStringLiteral("cell_edit")));
             button->setAccessibleName(i18nc("@action:button", "Edit"));
             button->setToolTip(i18nc("@info:tooltip", "Change"));
-            cardInfoGrid->addWidget(button, row, 2);
+            mInfoGridLayout->addWidget(button, row, 2);
             connect(button, &QPushButton::clicked, this, &PGPCardWidget::changeUrlRequested);
         }
         row++;
 
         // PIN counters row
         {
-            cardInfoGrid->addWidget(new QLabel(i18nc("@label The number of remaining attempts to enter a PIN or PUK, as in "
-                                                     "Remaining attempts: PIN: 2, PUK: 3, Admin PIN: 3",
-                                                     "Remaining attempts:")),
-                                    row,
-                                    0);
+            mInfoGridLayout->addWidget(new QLabel(i18nc("@label The number of remaining attempts to enter a PIN or PUK, as in "
+                                                        "Remaining attempts: PIN: 2, PUK: 3, Admin PIN: 3",
+                                                        "Remaining attempts:")),
+                                       row,
+                                       0);
             mPinCounterLabel = new QLabel{this};
             mPinCounterLabel->setToolTip(xi18nc("@info:tooltip", "Shows the number of remaining attempts for entering the correct PIN or PUK."));
             mPinCounterLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
-            cardInfoGrid->addWidget(mPinCounterLabel, row, 1);
+            mInfoGridLayout->addWidget(mPinCounterLabel, row, 1);
         }
 
-        cardInfoGrid->setColumnStretch(cardInfoGrid->columnCount(), 1);
+        mInfoGridLayout->setColumnStretch(mInfoGridLayout->columnCount(), 1);
     }
-    areaVLay->addLayout(cardInfoGrid);
 
-    areaVLay->addWidget(new KSeparator(Qt::Horizontal));
+    mContentLayout->addWidget(new KSeparator(Qt::Horizontal));
 
     // The keys
-    areaVLay->addWidget(new QLabel(QStringLiteral("<b>%1</b>").arg(i18n("Keys:"))));
+    mContentLayout->addWidget(new QLabel(QStringLiteral("<b>%1</b>").arg(i18n("Keys:"))));
 
     mKeysWidget = new OpenPGPKeyCardWidget{this};
-    areaVLay->addWidget(mKeysWidget);
+    mContentLayout->addWidget(mKeysWidget);
     connect(mKeysWidget, &OpenPGPKeyCardWidget::createCSRRequested, this, &PGPCardWidget::createCSR);
     connect(mKeysWidget, &OpenPGPKeyCardWidget::generateKeyRequested, this, &PGPCardWidget::generateKey);
 
-    areaVLay->addWidget(new KSeparator(Qt::Horizontal));
+    mContentLayout->addWidget(new KSeparator(Qt::Horizontal));
 
-    areaVLay->addWidget(new QLabel(QStringLiteral("<b>%1</b>").arg(i18n("Actions:"))));
+    mContentLayout->addWidget(new QLabel(QStringLiteral("<b>%1</b>").arg(i18n("Actions:"))));
 
     auto actionLayout = new QHBoxLayout;
 
     {
         auto generateButton = new QPushButton(i18nc("@action:button", "Generate New Keys"), this);
         generateButton->setToolTip(xi18nc("@info:tooltip",
                                           "<para>Generate three new keys on the smart card and create a new OpenPGP "
                                           "certificate with those keys. Optionally, the encryption key is generated "
                                           "off-card and a backup is created so that you can still access data encrypted "
                                           "with this key in case the card is lost or damaged.</para>"
                                           "<para><emphasis strong='true'>"
                                           "Existing keys on the smart card will be overwritten."
                                           "</emphasis></para>"));
         actionLayout->addWidget(generateButton);
         connect(generateButton, &QPushButton::clicked, this, &PGPCardWidget::genkeyRequested);
     }
     {
         auto pinButton = new QPushButton(i18nc("@action:button", "Change PIN"), this);
         pinButton->setToolTip(i18nc("@info:tooltip",
                                     "Change the PIN required for using the keys on the smart card. "
                                     "The PIN must contain at least six characters."));
         actionLayout->addWidget(pinButton);
         connect(pinButton, &QPushButton::clicked, this, [this]() {
             doChangePin(OpenPGPCard::pinKeyRef());
         });
     }
     {
         auto unblockButton = new QPushButton(i18nc("@action:button", "Unblock Card"), this);
         unblockButton->setToolTip(i18nc("@info:tooltip", "Unblock the smart card with the PUK (if available) or the Admin PIN."));
         actionLayout->addWidget(unblockButton);
         connect(unblockButton, &QPushButton::clicked, this, [this]() {
             if (mPUKIsAvailable) {
                 // unblock card with the PUK
                 doChangePin(OpenPGPCard::resetCodeKeyRef());
             } else {
                 // unblock card with the Admin PIN
                 doChangePin(OpenPGPCard::pinKeyRef(), ChangePinCommand::ResetMode);
             }
         });
     }
     {
         auto pukButton = new QPushButton(i18nc("@action:button", "Change Admin PIN"), this);
         pukButton->setToolTip(i18nc("@info:tooltip", "Change the PIN required for administrative operations."));
         actionLayout->addWidget(pukButton);
         connect(pukButton, &QPushButton::clicked, this, [this]() {
             doChangePin(OpenPGPCard::adminPinKeyRef());
         });
     }
     {
         mSetOrChangePUKButton = new QPushButton(i18nc("@action:button", "Set PUK"), this);
         mSetOrChangePUKButton->setToolTip(i18nc("@info:tooltip",
                                                 "Set or change the PUK that can be used to unblock the smart card. "
                                                 "The PUK must contain at least eight characters."));
         actionLayout->addWidget(mSetOrChangePUKButton);
         connect(mSetOrChangePUKButton, &QPushButton::clicked, this, [this]() {
             doChangePin(OpenPGPCard::resetCodeKeyRef(), ChangePinCommand::ResetMode);
         });
     }
 
     actionLayout->addStretch(-1);
-    areaVLay->addLayout(actionLayout);
+    mContentLayout->addLayout(actionLayout);
 
-    areaVLay->addStretch(1);
+    mContentLayout->addStretch(1);
 }
 
 void PGPCardWidget::setCard(const OpenPGPCard *card)
 {
-    const QString version = card->displayAppVersion();
+    SmartCardWidget::setCard(card);
 
     mIs21 = card->appVersion() >= 0x0201;
-    const QString manufacturer = QString::fromStdString(card->manufacturer());
-    const bool manufacturerIsUnknown = manufacturer.isEmpty() || manufacturer == QLatin1StringView("unknown");
-    mVersionLabel->setText(
-        manufacturerIsUnknown
-            ? i18nc("Placeholder is a version number", "Unknown OpenPGP v%1 card", version)
-            : i18nc("First placeholder is manufacturer, second placeholder is a version number", "%1 OpenPGP v%2 card", manufacturer, version));
-    mSerialNumberLabel->setText(card->displaySerialNumber());
-    mSerialNumber = card->serialNumber();
 
     const auto holder = card->cardHolder();
     const auto url = QString::fromStdString(card->pubkeyUrl());
     mCardHolderLabel->setText(holder.isEmpty() ? i18n("not set") : holder);
     mUrl = url;
     mUrlLabel->setText(url.isEmpty() ? i18n("not set") : QStringLiteral("<a href=\"%1\">%1</a>").arg(url.toHtmlEscaped()));
     mUrlLabel->setOpenExternalLinks(true);
 
     const auto pinLabels = card->pinLabels();
     const auto pinCounters = card->pinCounters();
     QStringList countersWithLabels;
     countersWithLabels.reserve(pinCounters.size());
     for (const auto &pinCounter : pinCounters) {
         // sanity check
         if (countersWithLabels.size() == pinLabels.size()) {
             break;
         }
         countersWithLabels.push_back(i18nc("label: value", "%1: %2", pinLabels[countersWithLabels.size()], pinCounter));
     }
     mPinCounterLabel->setText(countersWithLabels.join(QLatin1String(", ")));
     mPUKIsAvailable = (pinCounters.size() == 3) && (pinCounters[1] > 0);
     mSetOrChangePUKButton->setText(mPUKIsAvailable ? i18nc("@action:button", "Change PUK") : i18nc("@action:button", "Set PUK"));
 
     mKeysWidget->update(card);
 
     mCardIsEmpty = card->keyFingerprint(OpenPGPCard::pgpSigKeyRef()).empty() && card->keyFingerprint(OpenPGPCard::pgpEncKeyRef()).empty()
         && card->keyFingerprint(OpenPGPCard::pgpAuthKeyRef()).empty();
 }
 
 void PGPCardWidget::doChangePin(const std::string &keyRef, ChangePinCommand::ChangePinMode mode)
 {
     auto cmd = new ChangePinCommand(mSerialNumber, OpenPGPCard::AppName, this);
     this->setEnabled(false);
     connect(cmd, &ChangePinCommand::finished, this, [this]() {
         this->setEnabled(true);
     });
     cmd->setKeyRef(keyRef);
     cmd->setMode(mode);
     cmd->start();
 }
 
 void PGPCardWidget::doGenKey(GenCardKeyDialog *dlg)
 {
     const GpgME::Error err = ReaderStatus::switchCardAndApp(mSerialNumber, OpenPGPCard::AppName);
     if (err) {
         return;
     }
 
     const auto params = dlg->getKeyParams();
 
     auto progress = new QProgressDialog(this, Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::Dialog);
     progress->setAutoClose(true);
     progress->setMinimumDuration(0);
     progress->setMaximum(0);
     progress->setMinimum(0);
     progress->setModal(true);
     progress->setCancelButton(nullptr);
     progress->setWindowTitle(i18nc("@title:window", "Generating Keys"));
     progress->setLabel(new QLabel(i18nc("@label:textbox", "This may take several minutes...")));
     auto workerThread = new GenKeyThread(params, mSerialNumber);
     connect(workerThread, &QThread::finished, this, [this, workerThread, progress] {
         progress->accept();
         progress->deleteLater();
         genKeyDone(workerThread->error(), workerThread->bkpFile());
         delete workerThread;
     });
     workerThread->start();
     progress->exec();
 }
 
 void PGPCardWidget::genKeyDone(const GpgME::Error &err, const std::string &backup)
 {
     if (err) {
         KMessageBox::error(this, i18nc("@info", "Failed to generate new key: %1", Formatting::errorAsString(err)));
         return;
     }
     if (err.isCanceled()) {
         return;
     }
     if (!backup.empty()) {
         const auto bkpFile = QString::fromStdString(backup);
         QFileInfo fi(bkpFile);
         const auto target =
             QFileDialog::getSaveFileName(this, i18n("Save backup of encryption key"), fi.fileName(), QStringLiteral("%1 (*.gpg)").arg(i18n("Backup Key")));
         if (!target.isEmpty() && !QFile::copy(bkpFile, target)) {
             KMessageBox::error(this, i18nc("@info", "Failed to move backup. The backup key is still stored under: %1", bkpFile));
         } else if (!target.isEmpty()) {
             QFile::remove(bkpFile);
         }
     }
 
     KMessageBox::information(this, i18nc("@info", "Successfully generated a new key for this card."), i18nc("@title", "Success"));
     ReaderStatus::mutableInstance()->updateStatus();
 }
 
 void PGPCardWidget::genkeyRequested()
 {
     const auto pgpCard = ReaderStatus::instance()->getCard<OpenPGPCard>(mSerialNumber);
     if (!pgpCard) {
         KMessageBox::error(this, i18n("Failed to find the OpenPGP card with the serial number: %1", QString::fromStdString(mSerialNumber)));
         return;
     }
 
     if (!mCardIsEmpty) {
         auto ret = KMessageBox::warningContinueCancel(this,
                                                       i18n("The existing keys on this card will be <b>deleted</b> "
                                                            "and replaced by new keys.")
                                                           + QStringLiteral("<br/><br/>")
                                                           + i18n("It will no longer be possible to decrypt past communication "
                                                                  "encrypted for the existing key."),
                                                       i18n("Secret Key Deletion"),
                                                       KStandardGuiItem::guiItem(KStandardGuiItem::Delete),
                                                       KStandardGuiItem::cancel(),
                                                       QString(),
                                                       KMessageBox::Notify | KMessageBox::Dangerous);
 
         if (ret != KMessageBox::Continue) {
             return;
         }
     }
 
     auto dlg = new GenCardKeyDialog(GenCardKeyDialog::AllKeyAttributes, this);
     const auto allowedAlgos = getAllowedAlgorithms(pgpCard->supportedAlgorithms());
     if (allowedAlgos.empty()) {
         KMessageBox::error(this, i18nc("@info", "You cannot generate keys on this smart card because it doesn't support any of the compliant algorithms."));
         return;
     }
     dlg->setSupportedAlgorithms(allowedAlgos, getPreferredAlgorithm(allowedAlgos));
     connect(dlg, &QDialog::accepted, this, [this, dlg]() {
         doGenKey(dlg);
         dlg->deleteLater();
     });
     dlg->setModal(true);
     dlg->show();
 }
 
 void PGPCardWidget::changeNameRequested()
 {
     QString text = mCardHolderLabel->text();
     while (true) {
         bool ok = false;
         text = QInputDialog::getText(this, i18n("Change cardholder"), i18n("New name:"), QLineEdit::Normal, text, &ok, Qt::WindowFlags(), Qt::ImhLatinOnly);
         if (!ok) {
             return;
         }
         // Some additional restrictions imposed by gnupg
         if (text.contains(QLatin1Char('<'))) {
             KMessageBox::error(this, i18nc("@info", "The \"<\" character may not be used."));
             continue;
         }
         if (text.contains(QLatin1StringView("  "))) {
             KMessageBox::error(this, i18nc("@info", "Double spaces are not allowed"));
             continue;
         }
         if (text.size() > 38) {
             KMessageBox::error(this, i18nc("@info", "The size of the name may not exceed 38 characters."));
         }
         break;
     }
     auto parts = text.split(QLatin1Char(' '));
     const auto lastName = parts.takeLast();
     const QString formatted = lastName + QStringLiteral("<<") + parts.join(QLatin1Char('<'));
 
     const auto pgpCard = ReaderStatus::instance()->getCard<OpenPGPCard>(mSerialNumber);
     if (!pgpCard) {
         KMessageBox::error(this, i18n("Failed to find the OpenPGP card with the serial number: %1", QString::fromStdString(mSerialNumber)));
         return;
     }
 
     const QByteArray command = QByteArrayLiteral("SCD SETATTR DISP-NAME ") + formatted.toUtf8();
     ReaderStatus::mutableInstance()->startSimpleTransaction(pgpCard, command, this, [this](const GpgME::Error &err) {
         changeNameResult(err);
     });
 }
 
 void PGPCardWidget::changeNameResult(const GpgME::Error &err)
 {
     if (err) {
         KMessageBox::error(this, i18nc("@info", "Name change failed: %1", Formatting::errorAsString(err)));
         return;
     }
     if (!err.isCanceled()) {
         KMessageBox::information(this, i18nc("@info", "Name successfully changed."), i18nc("@title", "Success"));
         ReaderStatus::mutableInstance()->updateStatus();
     }
 }
 
 void PGPCardWidget::changeUrlRequested()
 {
     QString text = mUrl;
     while (true) {
         bool ok = false;
         text = QInputDialog::getText(this,
                                      i18n("Change the URL where the pubkey can be found"),
                                      i18n("New pubkey URL:"),
                                      QLineEdit::Normal,
                                      text,
                                      &ok,
                                      Qt::WindowFlags(),
                                      Qt::ImhLatinOnly);
         if (!ok) {
             return;
         }
         // Some additional restrictions imposed by gnupg
         if (text.size() > 254) {
             KMessageBox::error(this, i18nc("@info", "The size of the URL may not exceed 254 characters."));
         }
         break;
     }
 
     const auto pgpCard = ReaderStatus::instance()->getCard<OpenPGPCard>(mSerialNumber);
     if (!pgpCard) {
         KMessageBox::error(this, i18n("Failed to find the OpenPGP card with the serial number: %1", QString::fromStdString(mSerialNumber)));
         return;
     }
 
     const QByteArray command = QByteArrayLiteral("SCD SETATTR PUBKEY-URL ") + text.toUtf8();
     ReaderStatus::mutableInstance()->startSimpleTransaction(pgpCard, command, this, [this](const GpgME::Error &err) {
         changeUrlResult(err);
     });
 }
 
 void PGPCardWidget::changeUrlResult(const GpgME::Error &err)
 {
     if (err) {
         KMessageBox::error(this, i18nc("@info", "URL change failed: %1", Formatting::errorAsString(err)));
         return;
     }
     if (!err.isCanceled()) {
         KMessageBox::information(this, i18nc("@info", "URL successfully changed."), i18nc("@title", "Success"));
         ReaderStatus::mutableInstance()->updateStatus();
     }
 }
 
 void PGPCardWidget::createCSR(const std::string &keyref)
 {
     auto cmd = new CreateCSRForCardKeyCommand(keyref, mSerialNumber, OpenPGPCard::AppName, this);
     this->setEnabled(false);
     connect(cmd, &CreateCSRForCardKeyCommand::finished, this, [this]() {
         this->setEnabled(true);
     });
     cmd->start();
 }
 
 void PGPCardWidget::generateKey(const std::string &keyref)
 {
     auto cmd = new OpenPGPGenerateCardKeyCommand(keyref, mSerialNumber, this);
     this->setEnabled(false);
     connect(cmd, &OpenPGPGenerateCardKeyCommand::finished, this, [this]() {
         this->setEnabled(true);
     });
     cmd->start();
 }
 
 #include "pgpcardwidget.moc"
 
 #include "moc_pgpcardwidget.cpp"
diff --git a/src/view/pgpcardwidget.h b/src/view/pgpcardwidget.h
index 66db13e08..c2fb12a2c 100644
--- a/src/view/pgpcardwidget.h
+++ b/src/view/pgpcardwidget.h
@@ -1,70 +1,68 @@
 /*  view/pgpcardwiget.h
 
     This file is part of Kleopatra, the KDE keymanager
     SPDX-FileCopyrightText: 2017 Bundesamt für Sicherheit in der Informationstechnik
     SPDX-FileContributor: Intevation GmbH
     SPDX-FileCopyrightText: 2020, 2022 g10 Code GmbH
     SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
 
     SPDX-License-Identifier: GPL-2.0-or-later
 */
 #pragma once
 
 #include "smartcardwidget.h"
 
 #include "commands/changepincommand.h"
 
 #include <gpgme++/error.h>
 
 #include <string>
 
 class QLabel;
 class QPushButton;
 
 namespace Kleo
 {
 class GenCardKeyDialog;
 class OpenPGPKeyCardWidget;
 
 namespace SmartCard
 {
 struct KeyPairInfo;
 class OpenPGPCard;
 } // namespace SmartCard
 
 class PGPCardWidget : public SmartCardWidget
 {
     Q_OBJECT
 public:
     explicit PGPCardWidget(QWidget *parent = nullptr);
 
     void setCard(const SmartCard::OpenPGPCard *card);
     void doGenKey(GenCardKeyDialog *dlg);
     void genKeyDone(const GpgME::Error &err, const std::string &backup);
 
 public Q_SLOTS:
     void genkeyRequested();
     void changeNameRequested();
     void changeNameResult(const GpgME::Error &err);
     void changeUrlRequested();
     void changeUrlResult(const GpgME::Error &err);
     void createCSR(const std::string &keyref);
     void generateKey(const std::string &keyref);
 
 private:
     void doChangePin(const std::string &keyRef, Commands::ChangePinCommand::ChangePinMode mode = Commands::ChangePinCommand::NormalMode);
 
 private:
-    QLabel *mSerialNumberLabel = nullptr;
     QLabel *mCardHolderLabel = nullptr;
-    QLabel *mVersionLabel = nullptr;
     QLabel *mUrlLabel = nullptr;
     QLabel *mPinCounterLabel = nullptr;
     QPushButton *mSetOrChangePUKButton = nullptr;
     OpenPGPKeyCardWidget *mKeysWidget = nullptr;
     QString mUrl;
     bool mCardIsEmpty = false;
     bool mIs21 = false;
     bool mPUKIsAvailable = false;
 };
 } // namespace Kleo
diff --git a/src/view/pivcardwidget.cpp b/src/view/pivcardwidget.cpp
index 3e4333360..1508d1e4b 100644
--- a/src/view/pivcardwidget.cpp
+++ b/src/view/pivcardwidget.cpp
@@ -1,397 +1,358 @@
 /*  view/pivcardwiget.cpp
 
     This file is part of Kleopatra, the KDE keymanager
     SPDX-FileCopyrightText: 2020 g10 Code GmbH
     SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
 
     SPDX-License-Identifier: GPL-2.0-or-later
 */
 
 #include "pivcardwidget.h"
 
 #include "tooltippreferences.h"
 
 #include "commands/certificatetopivcardcommand.h"
 #include "commands/changepincommand.h"
 #include "commands/createcsrforcardkeycommand.h"
 #include "commands/createopenpgpkeyfromcardkeyscommand.h"
 #include "commands/importcertificatefrompivcardcommand.h"
 #include "commands/keytocardcommand.h"
 #include "commands/pivgeneratecardkeycommand.h"
 #include "commands/setpivcardapplicationadministrationkeycommand.h"
 
 #include "smartcard/pivcard.h"
 #include "smartcard/readerstatus.h"
 
 #include <Libkleo/Compliance>
 #include <Libkleo/Dn>
 #include <Libkleo/Formatting>
 #include <Libkleo/KeyCache>
 
 #include <KLocalizedString>
 #include <KSeparator>
 
-#include <QFrame>
 #include <QGridLayout>
 #include <QLabel>
 #include <QPushButton>
-#include <QScrollArea>
 #include <QVBoxLayout>
 
 using namespace GpgME;
 using namespace Kleo;
 using namespace Kleo::Commands;
 using namespace Kleo::SmartCard;
 
 namespace
 {
 static void layoutKeyWidgets(QGridLayout *grid, const QString &keyName, const PIVCardWidget::KeyWidgets &keyWidgets)
 {
     int row = grid->rowCount();
     grid->addWidget(new QLabel(keyName), row, 0);
     grid->addWidget(keyWidgets.keyGrip, row, 1);
     grid->addWidget(keyWidgets.keyAlgorithm, row, 2);
     grid->addWidget(keyWidgets.generateButton, row, 3);
     if (keyWidgets.writeKeyButton) {
         grid->addWidget(keyWidgets.writeKeyButton, row, 4);
     }
 
     row++;
     grid->addWidget(keyWidgets.certificateInfo, row, 1, 1, 2);
     grid->addWidget(keyWidgets.writeCertificateButton, row, 3);
     grid->addWidget(keyWidgets.importCertificateButton, row, 4);
     if (keyWidgets.createCSRButton) {
         grid->addWidget(keyWidgets.createCSRButton, row, 5);
     }
 }
 
 static int toolTipOptions()
 {
     using namespace Kleo::Formatting;
     static const int validityFlags = Validity | Issuer | ExpiryDates | CertificateUsage;
     static const int ownerFlags = Subject | UserIDs | OwnerTrust;
     static const int detailsFlags = StorageLocation | CertificateType | SerialNumber | Fingerprint;
 
     const TooltipPreferences prefs;
 
     int flags = KeyID;
     flags |= prefs.showValidity() ? validityFlags : 0;
     flags |= prefs.showOwnerInformation() ? ownerFlags : 0;
     flags |= prefs.showCertificateDetails() ? detailsFlags : 0;
     return flags;
 }
 }
 
 PIVCardWidget::PIVCardWidget(QWidget *parent)
     : SmartCardWidget(parent)
 {
-    // Set up the scroll area
-    auto myLayout = new QVBoxLayout(this);
-    myLayout->setContentsMargins(0, 0, 0, 0);
+    mContentLayout->addWidget(new KSeparator(Qt::Horizontal));
 
-    auto area = new QScrollArea;
-    area->setFocusPolicy(Qt::NoFocus);
-    area->setFrameShape(QFrame::NoFrame);
-    area->setWidgetResizable(true);
-    myLayout->addWidget(area);
-
-    auto areaWidget = new QWidget;
-    area->setWidget(areaWidget);
-
-    auto areaVLay = new QVBoxLayout(areaWidget);
-
-    auto cardInfoGrid = new QGridLayout;
-    {
-        int row = 0;
-
-        // Version and Serialnumber
-        mVersionLabel = new QLabel{this};
-        mVersionLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
-        cardInfoGrid->addWidget(mVersionLabel, row++, 0, 1, 2);
-
-        cardInfoGrid->addWidget(new QLabel(i18nc("@label:textbox", "Serial number:")), row, 0);
-        mSerialNumberLabel = new QLabel{this};
-        mSerialNumberLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
-        cardInfoGrid->addWidget(mSerialNumberLabel, row++, 1);
-
-        cardInfoGrid->setColumnStretch(cardInfoGrid->columnCount(), 1);
-    }
-    areaVLay->addLayout(cardInfoGrid);
-
-    areaVLay->addWidget(new KSeparator(Qt::Horizontal));
-
-    areaVLay->addWidget(new QLabel(QStringLiteral("<b>%1</b>").arg(i18n("Keys:")), this));
+    mContentLayout->addWidget(new QLabel(QStringLiteral("<b>%1</b>").arg(i18n("Keys:")), this));
 
     auto keysGrid = new QGridLayout;
     for (const auto &keyInfo : PIVCard::supportedKeys()) {
         KeyWidgets keyWidgets = createKeyWidgets(keyInfo);
         layoutKeyWidgets(keysGrid, PIVCard::keyDisplayName(keyInfo.keyRef), keyWidgets);
     }
-    areaVLay->addLayout(keysGrid);
+    mContentLayout->addLayout(keysGrid);
 
-    areaVLay->addWidget(new KSeparator(Qt::Horizontal));
+    mContentLayout->addWidget(new KSeparator(Qt::Horizontal));
 
     auto actionLayout = new QHBoxLayout;
 
     if (CreateOpenPGPKeyFromCardKeysCommand::isSupported()) {
         mKeyForCardKeysButton = new QPushButton(this);
         mKeyForCardKeysButton->setText(i18nc("@action:button", "Create OpenPGP Key"));
         mKeyForCardKeysButton->setToolTip(i18nc("@info:tooltip", "Create an OpenPGP key for the keys stored on the card."));
         actionLayout->addWidget(mKeyForCardKeysButton);
         connect(mKeyForCardKeysButton, &QPushButton::clicked, this, &PIVCardWidget::createKeyFromCardKeys);
     }
 
     {
         auto button = new QPushButton(i18nc("@action:button", "Change PIN"), this);
         button->setToolTip(i18nc("@info:tooltip",
                                  "Change the PIV Card Application PIN that activates the PIV Card "
                                  "and enables private key operations using the stored keys."));
         actionLayout->addWidget(button);
         connect(button, &QPushButton::clicked, this, [this]() {
             changePin(PIVCard::pinKeyRef());
         });
     }
     {
         auto button = new QPushButton(i18nc("@action:button", "Change PUK"), this);
         button->setToolTip(i18nc("@info:tooltip", "Change the PIN Unblocking Key that enables a reset of the PIN."));
         actionLayout->addWidget(button);
         connect(button, &QPushButton::clicked, this, [this]() {
             changePin(PIVCard::pukKeyRef());
         });
     }
     {
         auto button = new QPushButton(i18nc("@action:button", "Change Admin Key"), this);
         button->setToolTip(i18nc("@info:tooltip",
                                  "Change the PIV Card Application Administration Key that is used by the "
                                  "PIV Card Application to authenticate the PIV Card Application Administrator and by the "
                                  "administrator (resp. Kleopatra) to authenticate the PIV Card Application."));
         actionLayout->addWidget(button);
         connect(button, &QPushButton::clicked, this, [this]() {
             setAdminKey();
         });
     }
 
     actionLayout->addStretch(-1);
-    areaVLay->addLayout(actionLayout);
+    mContentLayout->addLayout(actionLayout);
 
-    areaVLay->addStretch(1);
+    mContentLayout->addStretch(1);
 }
 
 PIVCardWidget::KeyWidgets PIVCardWidget::createKeyWidgets(const KeyPairInfo &keyInfo)
 {
     const std::string keyRef = keyInfo.keyRef;
     KeyWidgets keyWidgets;
     keyWidgets.keyGrip = new QLabel(this);
     keyWidgets.keyGrip->setTextInteractionFlags(Qt::TextBrowserInteraction);
     keyWidgets.keyAlgorithm = new QLabel(this);
     keyWidgets.keyAlgorithm->setTextInteractionFlags(Qt::TextSelectableByMouse);
     keyWidgets.generateButton = new QPushButton(i18nc("@action:button", "Generate"), this);
     keyWidgets.generateButton->setEnabled(false);
     connect(keyWidgets.generateButton, &QPushButton::clicked, this, [this, keyRef]() {
         generateKey(keyRef);
     });
     if (keyRef == PIVCard::cardAuthenticationKeyRef() || keyRef == PIVCard::keyManagementKeyRef()) {
         keyWidgets.writeKeyButton = new QPushButton(i18nc("@action:button", "Write Key"), this);
         keyWidgets.writeKeyButton->setToolTip(i18nc("@info:tooltip", "Write the key pair of a certificate to the card"));
         keyWidgets.writeKeyButton->setEnabled(true);
         connect(keyWidgets.writeKeyButton, &QPushButton::clicked, this, [this, keyRef]() {
             writeKeyToCard(keyRef);
         });
     }
     keyWidgets.certificateInfo = new QLabel(this);
     keyWidgets.certificateInfo->setTextInteractionFlags(Qt::TextBrowserInteraction);
     keyWidgets.writeCertificateButton = new QPushButton(i18nc("@action:button", "Write Certificate"), this);
     keyWidgets.writeCertificateButton->setToolTip(i18nc("@info:tooltip", "Write the certificate corresponding to this key to the card"));
     keyWidgets.writeCertificateButton->setEnabled(false);
     connect(keyWidgets.writeCertificateButton, &QPushButton::clicked, this, [this, keyRef]() {
         writeCertificateToCard(keyRef);
     });
     keyWidgets.importCertificateButton = new QPushButton(i18nc("@action:button", "Import Certificate"), this);
     keyWidgets.importCertificateButton->setToolTip(i18nc("@info:tooltip", "Import the certificate stored on the card"));
     keyWidgets.importCertificateButton->setEnabled(false);
     connect(keyWidgets.importCertificateButton, &QPushButton::clicked, this, [this, keyRef]() {
         importCertificateFromCard(keyRef);
     });
     if (keyInfo.canSign() || keyInfo.canEncrypt()) {
         keyWidgets.createCSRButton = new QPushButton(i18nc("@action:button", "Create CSR"), this);
         keyWidgets.createCSRButton->setToolTip(i18nc("@info:tooltip", "Create a certificate signing request for this key"));
         keyWidgets.createCSRButton->setEnabled(false);
         connect(keyWidgets.createCSRButton, &QPushButton::clicked, this, [this, keyRef]() {
             createCSR(keyRef);
         });
     }
     mKeyWidgets.insert({keyRef, keyWidgets});
     return keyWidgets;
 }
 
 PIVCardWidget::~PIVCardWidget()
 {
 }
 
 void PIVCardWidget::setCard(const PIVCard *card)
 {
-    mSerialNumber = card->serialNumber();
-    mVersionLabel->setText(i18nc("%1 version number", "PIV v%1 card", card->displayAppVersion()));
-
-    mSerialNumberLabel->setText(card->displaySerialNumber());
-    mSerialNumberLabel->setToolTip(QString::fromStdString(card->serialNumber()));
+    SmartCardWidget::setCard(card);
 
     if (card) {
         updateCachedValues(PIVCard::pivAuthenticationKeyRef(), card);
         updateCachedValues(PIVCard::cardAuthenticationKeyRef(), card);
         updateCachedValues(PIVCard::digitalSignatureKeyRef(), card);
         updateCachedValues(PIVCard::keyManagementKeyRef(), card);
     }
     updateKeyWidgets(PIVCard::pivAuthenticationKeyRef());
     updateKeyWidgets(PIVCard::cardAuthenticationKeyRef());
     updateKeyWidgets(PIVCard::digitalSignatureKeyRef());
     updateKeyWidgets(PIVCard::keyManagementKeyRef());
 
     if (mKeyForCardKeysButton) {
         mKeyForCardKeysButton->setEnabled(card->hasSigningKey() //
                                           && card->hasEncryptionKey() //
                                           && DeVSCompliance::algorithmIsCompliant(card->keyInfo(card->signingKeyRef()).algorithm)
                                           && DeVSCompliance::algorithmIsCompliant(card->keyInfo(card->encryptionKeyRef()).algorithm));
     }
 }
 
 void PIVCardWidget::updateCachedValues(const std::string &keyRef, const SmartCard::PIVCard *card)
 {
     KeyWidgets &widgets = mKeyWidgets.at(keyRef);
     widgets.keyInfo = card->keyInfo(keyRef);
     widgets.certificateData = card->certificateData(keyRef);
 }
 
 void PIVCardWidget::updateKeyWidgets(const std::string &keyRef)
 {
     const KeyWidgets &widgets = mKeyWidgets.at(keyRef);
     const std::string grip = widgets.keyInfo.grip;
     if (grip.empty()) {
         widgets.certificateInfo->setText(i18nc("@info", "<em>slot empty</em>"));
         widgets.certificateInfo->setToolTip(QString());
         widgets.keyGrip->setText(QString());
         widgets.keyAlgorithm->setText(QString());
         widgets.generateButton->setText(i18nc("@action:button", "Generate"));
         widgets.generateButton->setToolTip(i18nc("@info:tooltip %1 display name of a key", "Generate %1", PIVCard::keyDisplayName(keyRef)));
         if (widgets.createCSRButton) {
             widgets.createCSRButton->setEnabled(false);
         }
         widgets.writeCertificateButton->setEnabled(false);
         widgets.importCertificateButton->setEnabled(false);
     } else {
         const Key certificate = KeyCache::instance()->findSubkeyByKeyGrip(grip, GpgME::CMS).parent();
         if (!certificate.isNull()) {
             widgets.certificateInfo->setText(i18nc("X.509 certificate DN (validity, created: date)",
                                                    "%1 (%2, created: %3)",
                                                    DN(certificate.userID(0).id()).prettyDN(),
                                                    Formatting::complianceStringShort(certificate),
                                                    Formatting::creationDateString(certificate)));
             widgets.certificateInfo->setToolTip(Formatting::toolTip(certificate, toolTipOptions()));
             widgets.writeCertificateButton->setEnabled(true);
         } else {
             widgets.certificateInfo->setText(i18nc("@info", "<em>no matching certificate</em>"));
             widgets.certificateInfo->setToolTip(QString());
             widgets.writeCertificateButton->setEnabled(false);
         }
         widgets.keyGrip->setText(QString::fromStdString(grip));
         const std::string algo = widgets.keyInfo.algorithm;
         widgets.keyAlgorithm->setText(algo.empty() ? i18nc("@info unknown key algorithm", "unknown") : QString::fromStdString(algo));
         widgets.importCertificateButton->setEnabled(!widgets.certificateData.empty());
 
         widgets.generateButton->setText(i18nc("@action:button", "Replace"));
         widgets.generateButton->setToolTip(i18nc("@info:tooltip %1 display name of a key", "Replace %1 with new key", PIVCard::keyDisplayName(keyRef)));
         if (widgets.createCSRButton) {
             widgets.createCSRButton->setEnabled(DeVSCompliance::algorithmIsCompliant(algo));
         }
     }
 
     widgets.generateButton->setEnabled(true);
 }
 
 void PIVCardWidget::generateKey(const std::string &keyref)
 {
     auto cmd = new PIVGenerateCardKeyCommand(mSerialNumber, this);
     this->setEnabled(false);
     connect(cmd, &PIVGenerateCardKeyCommand::finished, this, [this]() {
         this->setEnabled(true);
     });
     cmd->setKeyRef(keyref);
     cmd->start();
 }
 
 void PIVCardWidget::createCSR(const std::string &keyref)
 {
     auto cmd = new CreateCSRForCardKeyCommand(keyref, mSerialNumber, PIVCard::AppName, this);
     this->setEnabled(false);
     connect(cmd, &CreateCSRForCardKeyCommand::finished, this, [this]() {
         this->setEnabled(true);
     });
     cmd->start();
 }
 
 void PIVCardWidget::writeCertificateToCard(const std::string &keyref)
 {
     auto cmd = new CertificateToPIVCardCommand(keyref, mSerialNumber);
     this->setEnabled(false);
     connect(cmd, &CertificateToPIVCardCommand::finished, this, [this]() {
         this->setEnabled(true);
     });
     cmd->setParentWidget(this);
     cmd->start();
 }
 
 void PIVCardWidget::importCertificateFromCard(const std::string &keyref)
 {
     auto cmd = new ImportCertificateFromPIVCardCommand(keyref, mSerialNumber);
     this->setEnabled(false);
     connect(cmd, &ImportCertificateFromPIVCardCommand::finished, this, [this, keyref]() {
         this->updateKeyWidgets(keyref);
         this->setEnabled(true);
     });
     cmd->setParentWidget(this);
     cmd->start();
 }
 
 void PIVCardWidget::writeKeyToCard(const std::string &keyref)
 {
     auto cmd = new KeyToCardCommand(keyref, mSerialNumber, PIVCard::AppName);
     this->setEnabled(false);
     connect(cmd, &KeyToCardCommand::finished, this, [this]() {
         this->setEnabled(true);
     });
     cmd->setParentWidget(this);
     cmd->start();
 }
 
 void PIVCardWidget::createKeyFromCardKeys()
 {
     auto cmd = new CreateOpenPGPKeyFromCardKeysCommand(mSerialNumber, PIVCard::AppName, this);
     this->setEnabled(false);
     connect(cmd, &CreateOpenPGPKeyFromCardKeysCommand::finished, this, [this]() {
         this->setEnabled(true);
     });
     cmd->start();
 }
 
 void PIVCardWidget::changePin(const std::string &keyRef)
 {
     auto cmd = new ChangePinCommand(mSerialNumber, PIVCard::AppName, this);
     this->setEnabled(false);
     connect(cmd, &ChangePinCommand::finished, this, [this]() {
         this->setEnabled(true);
     });
     cmd->setKeyRef(keyRef);
     cmd->start();
 }
 
 void PIVCardWidget::setAdminKey()
 {
     auto cmd = new SetPIVCardApplicationAdministrationKeyCommand(mSerialNumber, this);
     this->setEnabled(false);
     connect(cmd, &SetPIVCardApplicationAdministrationKeyCommand::finished, this, [this]() {
         this->setEnabled(true);
     });
     cmd->start();
 }
 
 #include "moc_pivcardwidget.cpp"
diff --git a/src/view/pivcardwidget.h b/src/view/pivcardwidget.h
index 18333a928..3e5c3ea87 100644
--- a/src/view/pivcardwidget.h
+++ b/src/view/pivcardwidget.h
@@ -1,71 +1,69 @@
 /*  view/pivcardwiget.h
 
     This file is part of Kleopatra, the KDE keymanager
     SPDX-FileCopyrightText: 2020 g10 Code GmbH
     SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
 
     SPDX-License-Identifier: GPL-2.0-or-later
 */
 #pragma once
 
 #include "smartcardwidget.h"
 
 #include <smartcard/keypairinfo.h>
 
 #include <QMap>
 
 #include <gpgme++/error.h>
 
 class QLabel;
 class QPushButton;
 
 namespace Kleo
 {
 
 namespace SmartCard
 {
 class PIVCard;
 } // namespace SmartCard
 
 class PIVCardWidget : public SmartCardWidget
 {
     Q_OBJECT
 public:
     explicit PIVCardWidget(QWidget *parent = nullptr);
     ~PIVCardWidget() override;
 
     void setCard(const SmartCard::PIVCard *card);
 
     struct KeyWidgets {
         SmartCard::KeyPairInfo keyInfo;
         std::string certificateData;
         QLabel *keyGrip = nullptr;
         QLabel *keyAlgorithm = nullptr;
         QLabel *certificateInfo = nullptr;
         QPushButton *generateButton = nullptr;
         QPushButton *createCSRButton = nullptr;
         QPushButton *writeCertificateButton = nullptr;
         QPushButton *importCertificateButton = nullptr;
         QPushButton *writeKeyButton = nullptr;
     };
 
 private:
     KeyWidgets createKeyWidgets(const SmartCard::KeyPairInfo &keyInfo);
     void updateCachedValues(const std::string &keyRef, const SmartCard::PIVCard *card);
     void updateKeyWidgets(const std::string &keyRef);
     void generateKey(const std::string &keyref);
     void createCSR(const std::string &keyref);
     void writeCertificateToCard(const std::string &keyref);
     void importCertificateFromCard(const std::string &keyref);
     void writeKeyToCard(const std::string &keyref);
     void createKeyFromCardKeys();
     void changePin(const std::string &keyRef);
     void setAdminKey();
 
 private:
-    QLabel *mSerialNumberLabel = nullptr;
-    QLabel *mVersionLabel = nullptr;
     QPushButton *mKeyForCardKeysButton = nullptr;
     std::map<std::string, KeyWidgets> mKeyWidgets;
 };
 } // namespace Kleo
diff --git a/src/view/smartcardwidget.cpp b/src/view/smartcardwidget.cpp
index 151217b5a..eb2aa27fc 100644
--- a/src/view/smartcardwidget.cpp
+++ b/src/view/smartcardwidget.cpp
@@ -1,17 +1,101 @@
 /*  view/smartcardwidget.cpp
 
     This file is part of Kleopatra, the KDE keymanager
     SPDX-FileCopyrightText: 2024 g10 Code GmbH
     SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
 
     SPDX-License-Identifier: GPL-2.0-or-later
 */
 
 #include "smartcardwidget.h"
 
+#include "infofield.h"
+
+#include <smartcard/card.h>
+
+#include <KLocalizedString>
+
+#include <QGridLayout>
+#include <QLabel>
+#include <QScrollArea>
+#include <QVBoxLayout>
+
+using namespace Kleo;
+using namespace Kleo::SmartCard;
+
+QString cardType(const Card *card)
+{
+    switch (card->appType()) {
+    case AppType::NetKeyApp:
+        return i18nc("1 is a Version number", "NetKey v%1 Card", card->appVersion());
+    case AppType::OpenPGPApp: {
+        const std::string manufacturer = card->manufacturer();
+        const bool manufacturerIsUnknown = manufacturer.empty() || manufacturer == "unknown";
+        return (manufacturerIsUnknown //
+                    ? i18nc("Placeholder is a version number", "Unknown OpenPGP v%1 card", card->displayAppVersion())
+                    : i18nc("First placeholder is manufacturer, second placeholder is a version number",
+                            "%1 OpenPGP v%2 card",
+                            QString::fromStdString(manufacturer),
+                            card->displayAppVersion()));
+    }
+    case AppType::P15App:
+        return i18nc("%1 is a smartcard manufacturer", "%1 PKCS#15 card", QString::fromStdString(card->manufacturer()));
+    case AppType::PIVApp:
+        return i18nc("%1 version number", "PIV v%1 card", card->displayAppVersion());
+    default:
+        return {};
+    };
+}
+
 SmartCardWidget::SmartCardWidget(QWidget *parent)
     : QWidget{parent}
 {
+    auto mainLayout = new QVBoxLayout{this};
+    mainLayout->setContentsMargins({});
+
+    auto area = new QScrollArea{this};
+    area->setFocusPolicy(Qt::NoFocus);
+    area->setFrameShape(QFrame::NoFrame);
+    area->setWidgetResizable(true);
+    mainLayout->addWidget(area);
+
+    auto areaWidget = new QWidget{this};
+    area->setWidget(areaWidget);
+    mContentLayout = new QVBoxLayout{areaWidget};
+    auto contentLayout = mContentLayout;
+
+    {
+        // auto gridLayout = new QGridLayout;
+        mInfoGridLayout = new QGridLayout;
+        auto gridLayout = mInfoGridLayout;
+        // gridLayout->setColumnStretch(1, 1);
+
+        int row = -1;
+
+        row++;
+        mCardTypeField = std::make_unique<InfoField>(i18nc("@label", "Card type:"), parent);
+        gridLayout->addWidget(mCardTypeField->label(), row, 0);
+        gridLayout->addLayout(mCardTypeField->layout(), row, 1);
+
+        row++;
+        mSerialNumberField = std::make_unique<InfoField>(i18nc("@label", "Serial number:"), parent);
+        gridLayout->addWidget(mSerialNumberField->label(), row, 0);
+        gridLayout->addLayout(mSerialNumberField->layout(), row, 1);
+
+        gridLayout->setColumnStretch(gridLayout->columnCount(), 1);
+
+        contentLayout->addLayout(gridLayout);
+    }
 }
 
 SmartCardWidget::~SmartCardWidget() = default;
+
+void SmartCardWidget::setCard(const Card *card)
+{
+    mSerialNumber = card->serialNumber();
+    mAppName = card->appName();
+    mAppType = card->appType();
+
+    mCardTypeField->setValue(cardType(card));
+    mSerialNumberField->setValue(card->displaySerialNumber());
+}
diff --git a/src/view/smartcardwidget.h b/src/view/smartcardwidget.h
index 457f61bfa..063d1b3fd 100644
--- a/src/view/smartcardwidget.h
+++ b/src/view/smartcardwidget.h
@@ -1,23 +1,49 @@
 /*  view/smartcardwidget.h
 
     This file is part of Kleopatra, the KDE keymanager
     SPDX-FileCopyrightText: 2024 g10 Code GmbH
     SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
 
     SPDX-License-Identifier: GPL-2.0-or-later
 */
 #pragma once
 
 #include <QWidget>
 
+#include <memory>
 #include <string>
 
+class QGridLayout;
+class QVBoxLayout;
+
+namespace Kleo
+{
+class InfoField;
+}
+namespace Kleo::SmartCard
+{
+enum class AppType;
+class Card;
+}
+
 class SmartCardWidget : public QWidget
 {
 public:
     SmartCardWidget(QWidget *parent = nullptr);
     ~SmartCardWidget() override;
 
+    void setCard(const Kleo::SmartCard::Card *card);
+
 protected:
     std::string mSerialNumber;
+
+    QVBoxLayout *mContentLayout = nullptr;
+    QGridLayout *mInfoGridLayout = nullptr;
+
+private:
+    std::string mAppName;
+    Kleo::SmartCard::AppType mAppType;
+
+    std::unique_ptr<Kleo::InfoField> mCardTypeField;
+    std::unique_ptr<Kleo::InfoField> mSerialNumberField;
 };