Components

Card

AntD Card is the wrapper for create/edit forms, list-page filter blocks and dashboard KPI tiles — a styled title slot, default border, and a 12px body-padding override that the sticky form footer depends on.

Source in the MFEs
CreateUser.vueDashboardKpis.vueDashboard.vuePolicyCreate.vue

General card

No custom wrapper is enforced — cards are plain AntD Card (antd / ant-design-vue) with the default border and shadow. The title slot is always a styled span: text-primary fw-bold font-size-13.

Preview
Create User

Card body — form fields, tables or dashboard content go here. In administrator-fe the body padding is overridden to 12px.

/* React — title slot is a styled span */
<Card title={<span className="text-primary fw-bold font-size-13">Create User</span>}>
  {/* form content */}
</Card>

Form card markup

The production create/edit shape (administrator-fe CreateUser.vue): breadcrumb → Card with styled title → vertical Form → AppFormFooter as the last child. The live form itself is documented under Components → Input & Form.

<template>
  <Row class="w-100">
    <AppBreadcrumb :items="USER_BREADCRUMB_ITEMS.create" :showBack="true" :translate="t" />
    <Row :gutter="[12, 0]" class="w-100">
      <Col :xs="24" :lg="24">
        <!-- Form Card -->
        <Card>
          <template #title>
            <span class="text-primary fw-bold font-size-13">Create User</span>
          </template>

          <Form layout="vertical" :model="userData" @finish="handleSubmit">
            <Row :gutter="[12, 0]">
              <Col :xs="24" :md="12">
                <Form.Item label="Auth Type" name="source">
                  <Select v-model:value="userData.source" placeholder="Select auth type" />
                </Form.Item>
              </Col>
              <Col :xs="24" :md="12">
                <Form.Item label="Username" name="username">
                  <Input v-model:value="userData.username" />
                </Form.Item>
              </Col>
            </Row>

            <AppFormFooter>
              <Button type="primary" html-type="submit">Save</Button>
              <Button @click="handleReset">Cancel</Button>
            </AppFormFooter>
          </Form>
        </Card>
      </Col>
    </Row>
  </Row>
</template>

Props

NameTypeDefaultDescription
titleslot / ReactNodeStyled span — text-primary fw-bold font-size-13. Omit for the search card.
borderedbooleantrueDefault AntD border and shadow. Set false or restyle via CSS when needed.
hoverablebooleanfalseOptional lift-on-hover, used on dashboard tiles.
classstringCustom card types: .kpi-card (12px radius, flex Row/Col metric layout), .stats-card (min-height 250px).

Dashboard variants keep their scoped styles (administrator-fe Dashboard.vue):

:deep(.kpi-card) {
  border-radius: 12px;
  height: 100%;
  width: 100%;
}

:deep(.kpi-icon) {
  font-size: 22px;
  opacity: 0.85;
}

:deep(.kpi-label) {
  display: block;
  font-size: 12px;
  color: #8c8c8c;
  margin-bottom: 2px;
}

:deep(.kpi-value) {
  display: block;
  font-size: 22px;
  line-height: 1.2;
}

:deep(.stats-card) {
  height: 100%;
  min-height: 250px;
}

Notes

Body padding and the sticky footer are coupled
administrator-fe / reference-fe override .ant-card-body to padding: 12px !important. The AppFormFooter sticky bar relies on it — its margin: 16px -12px -12px -12px bleeds exactly to the card edges. Change one and you must change the other, or the footer floats inside the card with a gap.
React list pages do not use Card
rate-fe, reference-fe and racar-fe list pages use the AppSearchBar / AppActionBar patterns instead (see Patterns → List screen). Card is the form/edit/create and dashboard wrapper; the search card shown above is the administrator-fe (Vue) shape.
12px gutters
Dashboard and form cards space content with 12px gutters — Row :gutter="[12, 12]" for grids of cards, [12, 0] inside forms.