chore: verify and finalize task completion for existing refactor tasks

This commit is contained in:
2026-03-22 13:32:46 +01:00
parent 7306b98a54
commit 20dd890746
10 changed files with 90 additions and 207 deletions

View File

@@ -14,6 +14,7 @@ import {
makeStyles,
tokens,
} from "@fluentui/react-components";
import { useCardStyles } from "../theme/commonStyles";
import type { BanOriginFilter, TimeRange } from "../types/ban";
import {
BAN_ORIGIN_FILTER_LABELS,
@@ -57,20 +58,6 @@ const useStyles = makeStyles({
alignItems: "center",
flexWrap: "wrap",
gap: tokens.spacingVerticalS,
backgroundColor: tokens.colorNeutralBackground1,
borderRadius: tokens.borderRadiusMedium,
borderTopWidth: "1px",
borderTopStyle: "solid",
borderTopColor: tokens.colorNeutralStroke2,
borderRightWidth: "1px",
borderRightStyle: "solid",
borderRightColor: tokens.colorNeutralStroke2,
borderBottomWidth: "1px",
borderBottomStyle: "solid",
borderBottomColor: tokens.colorNeutralStroke2,
borderLeftWidth: "1px",
borderLeftStyle: "solid",
borderLeftColor: tokens.colorNeutralStroke2,
paddingTop: tokens.spacingVerticalS,
paddingBottom: tokens.spacingVerticalS,
paddingLeft: tokens.spacingHorizontalM,
@@ -107,9 +94,10 @@ export function DashboardFilterBar({
onOriginFilterChange,
}: DashboardFilterBarProps): React.JSX.Element {
const styles = useStyles();
const cardStyles = useCardStyles();
return (
<div className={styles.container}>
<div className={`${styles.container} ${cardStyles.card}`}>
{/* Time-range group */}
<div className={styles.group}>
<Text weight="semibold" size={300}>

View File

@@ -18,6 +18,7 @@ import {
tokens,
Tooltip,
} from "@fluentui/react-components";
import { useCardStyles } from "../theme/commonStyles";
import { ArrowClockwiseRegular, ShieldRegular } from "@fluentui/react-icons";
import { useServerStatus } from "../hooks/useServerStatus";
@@ -31,20 +32,6 @@ const useStyles = makeStyles({
alignItems: "center",
gap: tokens.spacingHorizontalL,
padding: `${tokens.spacingVerticalS} ${tokens.spacingHorizontalL}`,
backgroundColor: tokens.colorNeutralBackground1,
borderRadius: tokens.borderRadiusMedium,
borderTopWidth: "1px",
borderTopStyle: "solid",
borderTopColor: tokens.colorNeutralStroke2,
borderRightWidth: "1px",
borderRightStyle: "solid",
borderRightColor: tokens.colorNeutralStroke2,
borderBottomWidth: "1px",
borderBottomStyle: "solid",
borderBottomColor: tokens.colorNeutralStroke2,
borderLeftWidth: "1px",
borderLeftStyle: "solid",
borderLeftColor: tokens.colorNeutralStroke2,
marginBottom: tokens.spacingVerticalL,
flexWrap: "wrap",
},
@@ -85,8 +72,10 @@ export function ServerStatusBar(): React.JSX.Element {
const styles = useStyles();
const { status, loading, error, refresh } = useServerStatus();
const cardStyles = useCardStyles();
return (
<div className={styles.bar} role="status" aria-label="fail2ban server status">
<div className={`${cardStyles.card} ${styles.bar}`} role="status" aria-label="fail2ban server status">
{/* ---------------------------------------------------------------- */}
{/* Online / Offline badge */}
{/* ---------------------------------------------------------------- */}

View File

@@ -10,6 +10,7 @@
import { useCallback, useState } from "react";
import { ComposableMap, ZoomableGroup, Geography, useGeographies } from "react-simple-maps";
import { Button, makeStyles, tokens } from "@fluentui/react-components";
import { useCardStyles } from "../theme/commonStyles";
import type { GeoPermissibleObjects } from "d3-geo";
import { ISO_NUMERIC_TO_ALPHA2 } from "../data/isoNumericToAlpha2";
import { getBanCountColor } from "../utils/mapColors";
@@ -29,9 +30,6 @@ const useStyles = makeStyles({
mapWrapper: {
width: "100%",
position: "relative",
backgroundColor: tokens.colorNeutralBackground2,
borderRadius: tokens.borderRadiusMedium,
border: `1px solid ${tokens.colorNeutralStroke1}`,
overflow: "hidden",
},
countLabel: {
@@ -211,6 +209,7 @@ export function WorldMap({
thresholdHigh = 100,
}: WorldMapProps): React.JSX.Element {
const styles = useStyles();
const cardStyles = useCardStyles();
const [zoom, setZoom] = useState<number>(1);
const [center, setCenter] = useState<[number, number]>([0, 0]);
@@ -229,7 +228,7 @@ export function WorldMap({
return (
<div
className={styles.mapWrapper}
className={`${cardStyles.card} ${styles.mapWrapper}`}
role="img"
aria-label="World map showing banned IP counts by country. Click a country to filter the table below."
>

View File

@@ -32,6 +32,7 @@ import {
type TableColumnDefinition,
createTableColumn,
} from "@fluentui/react-components";
import { useCommonSectionStyles } from "../../theme/commonStyles";
import { formatTimestamp } from "../../utils/formatDate";
import {
ArrowClockwiseRegular,
@@ -54,26 +55,6 @@ const PAGE_SIZE_OPTIONS = [10, 25, 50, 100] as const;
// ---------------------------------------------------------------------------
const useStyles = makeStyles({
root: {
display: "flex",
flexDirection: "column",
gap: tokens.spacingVerticalS,
backgroundColor: tokens.colorNeutralBackground1,
borderRadius: tokens.borderRadiusMedium,
borderTopWidth: "1px",
borderTopStyle: "solid",
borderTopColor: tokens.colorNeutralStroke2,
borderRightWidth: "1px",
borderRightStyle: "solid",
borderRightColor: tokens.colorNeutralStroke2,
borderBottomWidth: "1px",
borderBottomStyle: "solid",
borderBottomColor: tokens.colorNeutralStroke2,
borderLeftWidth: "1px",
borderLeftStyle: "solid",
borderLeftColor: tokens.colorNeutralStroke2,
padding: tokens.spacingVerticalM,
},
header: {
display: "flex",
alignItems: "center",
@@ -243,6 +224,7 @@ export function BannedIpsSection({
onUnban,
}: BannedIpsSectionProps): React.JSX.Element {
const styles = useStyles();
const sectionStyles = useCommonSectionStyles();
const rows: BanRow[] = items.map((ban) => ({
ban,
@@ -252,7 +234,7 @@ export function BannedIpsSection({
const totalPages = pageSize > 0 ? Math.ceil(total / pageSize) : 1;
return (
<div className={styles.root}>
<div className={sectionStyles.section}>
{/* Section header */}
<div className={styles.header}>
<div className={styles.headerLeft}>

View File

@@ -37,6 +37,7 @@ import {
makeStyles,
tokens,
} from "@fluentui/react-components";
import { useCommonSectionStyles } from "../theme/commonStyles";
import {
AddRegular,
ArrowClockwiseRegular,
@@ -69,35 +70,7 @@ const useStyles = makeStyles({
flexDirection: "column",
gap: tokens.spacingVerticalXL,
},
section: {
backgroundColor: tokens.colorNeutralBackground1,
borderRadius: tokens.borderRadiusMedium,
borderTopWidth: "1px",
borderTopStyle: "solid",
borderTopColor: tokens.colorNeutralStroke2,
borderRightWidth: "1px",
borderRightStyle: "solid",
borderRightColor: tokens.colorNeutralStroke2,
borderBottomWidth: "1px",
borderBottomStyle: "solid",
borderBottomColor: tokens.colorNeutralStroke2,
borderLeftWidth: "1px",
borderLeftStyle: "solid",
borderLeftColor: tokens.colorNeutralStroke2,
padding: tokens.spacingVerticalM,
display: "flex",
flexDirection: "column",
gap: tokens.spacingVerticalS,
},
sectionHeader: {
display: "flex",
alignItems: "center",
justifyContent: "space-between",
paddingBottom: tokens.spacingVerticalS,
borderBottomWidth: "1px",
borderBottomStyle: "solid",
borderBottomColor: tokens.colorNeutralStroke2,
},
tableWrapper: { overflowX: "auto" },
actionsCell: { display: "flex", gap: tokens.spacingHorizontalS, flexWrap: "wrap" },
mono: { fontFamily: "Consolas, 'Courier New', monospace", fontSize: "12px" },
@@ -400,6 +373,7 @@ interface SourcesSectionProps {
function SourcesSection({ onRunImport, runImportRunning }: SourcesSectionProps): React.JSX.Element {
const styles = useStyles();
const sectionStyles = useCommonSectionStyles();
const { sources, loading, error, refresh, createSource, updateSource, removeSource, previewSource } =
useBlocklists();
@@ -471,8 +445,8 @@ function SourcesSection({ onRunImport, runImportRunning }: SourcesSectionProps):
}, []);
return (
<div className={styles.section}>
<div className={styles.sectionHeader}>
<div className={sectionStyles.section}>
<div className={sectionStyles.sectionHeader}>
<Text size={500} weight="semibold">
Blocklist Sources
</Text>
@@ -631,6 +605,7 @@ interface ScheduleSectionProps {
function ScheduleSection({ onRunImport, runImportRunning }: ScheduleSectionProps): React.JSX.Element {
const styles = useStyles();
const sectionStyles = useCommonSectionStyles();
const { info, loading, error, saveSchedule } = useSchedule();
const [saving, setSaving] = useState(false);
const [saveMsg, setSaveMsg] = useState<string | null>(null);
@@ -663,8 +638,8 @@ function ScheduleSection({ onRunImport, runImportRunning }: ScheduleSectionProps
}, [draft, saveSchedule]);
return (
<div className={styles.section}>
<div className={styles.sectionHeader}>
<div className={sectionStyles.section}>
<div className={sectionStyles.sectionHeader}>
<Text size={500} weight="semibold">
Import Schedule
</Text>
@@ -810,11 +785,12 @@ function ScheduleSection({ onRunImport, runImportRunning }: ScheduleSectionProps
function ImportLogSection(): React.JSX.Element {
const styles = useStyles();
const sectionStyles = useCommonSectionStyles();
const { data, loading, error, page, setPage, refresh } = useImportLog(undefined, 20);
return (
<div className={styles.section}>
<div className={styles.sectionHeader}>
<div className={sectionStyles.section}>
<div className={sectionStyles.sectionHeader}>
<Text size={500} weight="semibold">
Import Log
</Text>

View File

@@ -15,6 +15,7 @@ import { DashboardFilterBar } from "../components/DashboardFilterBar";
import { ServerStatusBar } from "../components/ServerStatusBar";
import { TopCountriesBarChart } from "../components/TopCountriesBarChart";
import { TopCountriesPieChart } from "../components/TopCountriesPieChart";
import { useCommonSectionStyles } from "../theme/commonStyles";
import { useDashboardCountryData } from "../hooks/useDashboardCountryData";
import type { BanOriginFilter, TimeRange } from "../types/ban";
@@ -29,26 +30,6 @@ const useStyles = makeStyles({
flexDirection: "column",
gap: tokens.spacingVerticalM,
},
section: {
display: "flex",
flexDirection: "column",
gap: tokens.spacingVerticalS,
backgroundColor: tokens.colorNeutralBackground1,
borderRadius: tokens.borderRadiusMedium,
borderTopWidth: "1px",
borderTopStyle: "solid",
borderTopColor: tokens.colorNeutralStroke2,
borderRightWidth: "1px",
borderRightStyle: "solid",
borderRightColor: tokens.colorNeutralStroke2,
borderBottomWidth: "1px",
borderBottomStyle: "solid",
borderBottomColor: tokens.colorNeutralStroke2,
borderLeftWidth: "1px",
borderLeftStyle: "solid",
borderLeftColor: tokens.colorNeutralStroke2,
padding: tokens.spacingVerticalM,
},
sectionHeader: {
display: "flex",
alignItems: "center",
@@ -93,6 +74,8 @@ export function DashboardPage(): React.JSX.Element {
const { countries, countryNames, isLoading: countryLoading, error: countryError, reload: reloadCountry } =
useDashboardCountryData(timeRange, originFilter);
const sectionStyles = useCommonSectionStyles();
return (
<div className={styles.root}>
{/* ------------------------------------------------------------------ */}
@@ -113,7 +96,7 @@ export function DashboardPage(): React.JSX.Element {
{/* ------------------------------------------------------------------ */}
{/* Ban Trend section */}
{/* ------------------------------------------------------------------ */}
<div className={styles.section}>
<div className={sectionStyles.section}>
<div className={styles.sectionHeader}>
<Text as="h2" size={500} weight="semibold">
Ban Trend
@@ -127,7 +110,7 @@ export function DashboardPage(): React.JSX.Element {
{/* ------------------------------------------------------------------ */}
{/* Charts section */}
{/* ------------------------------------------------------------------ */}
<div className={styles.section}>
<div className={sectionStyles.section}>
<div className={styles.sectionHeader}>
<Text as="h2" size={500} weight="semibold">
Top Countries
@@ -162,7 +145,7 @@ export function DashboardPage(): React.JSX.Element {
{/* ------------------------------------------------------------------ */}
{/* Ban list section */}
{/* ------------------------------------------------------------------ */}
<div className={styles.section}>
<div className={sectionStyles.section}>
<div className={styles.sectionHeader}>
<Text as="h2" size={500} weight="semibold">
Ban List

View File

@@ -36,6 +36,7 @@ import {
makeStyles,
tokens,
} from "@fluentui/react-components";
import { useCardStyles } from "../theme/commonStyles";
import {
ArrowCounterclockwiseRegular,
ArrowLeftRegular,
@@ -118,9 +119,6 @@ const useStyles = makeStyles({
gridTemplateColumns: "repeat(auto-fit, minmax(160px, 1fr))",
gap: tokens.spacingVerticalM,
padding: tokens.spacingVerticalM,
background: tokens.colorNeutralBackground2,
borderRadius: tokens.borderRadiusMedium,
border: `1px solid ${tokens.colorNeutralStroke1}`,
marginBottom: tokens.spacingVerticalM,
},
detailField: {
@@ -222,6 +220,7 @@ interface IpDetailViewProps {
function IpDetailView({ ip, onBack }: IpDetailViewProps): React.JSX.Element {
const styles = useStyles();
const cardStyles = useCardStyles();
const { detail, loading, error, refresh } = useIpHistory(ip);
if (loading) {
@@ -278,7 +277,7 @@ function IpDetailView({ ip, onBack }: IpDetailViewProps): React.JSX.Element {
</div>
{/* Summary grid */}
<div className={styles.detailGrid}>
<div className={`${cardStyles.card} ${styles.detailGrid}`}>
<div className={styles.detailField}>
<span className={styles.detailLabel}>Total Bans</span>
<span className={styles.detailValue}>{String(detail.total_bans)}</span>

View File

@@ -23,6 +23,7 @@ import {
makeStyles,
tokens,
} from "@fluentui/react-components";
import { useCommonSectionStyles } from "../theme/commonStyles";
import {
ArrowClockwiseRegular,
ArrowLeftRegular,
@@ -53,36 +54,7 @@ const useStyles = makeStyles({
alignItems: "center",
gap: tokens.spacingHorizontalS,
},
section: {
display: "flex",
flexDirection: "column",
gap: tokens.spacingVerticalS,
backgroundColor: tokens.colorNeutralBackground1,
borderRadius: tokens.borderRadiusMedium,
borderTopWidth: "1px",
borderTopStyle: "solid",
borderTopColor: tokens.colorNeutralStroke2,
borderRightWidth: "1px",
borderRightStyle: "solid",
borderRightColor: tokens.colorNeutralStroke2,
borderBottomWidth: "1px",
borderBottomStyle: "solid",
borderBottomColor: tokens.colorNeutralStroke2,
borderLeftWidth: "1px",
borderLeftStyle: "solid",
borderLeftColor: tokens.colorNeutralStroke2,
padding: tokens.spacingVerticalM,
},
sectionHeader: {
display: "flex",
alignItems: "center",
justifyContent: "space-between",
gap: tokens.spacingHorizontalM,
paddingBottom: tokens.spacingVerticalS,
borderBottomWidth: "1px",
borderBottomStyle: "solid",
borderBottomColor: tokens.colorNeutralStroke2,
},
headerRow: {
display: "flex",
alignItems: "center",
@@ -181,6 +153,7 @@ interface JailInfoProps {
function JailInfoSection({ jail, onRefresh, onStart, onStop, onSetIdle, onReload }: JailInfoProps): React.JSX.Element {
const styles = useStyles();
const sectionStyles = useCommonSectionStyles();
const navigate = useNavigate();
const [ctrlError, setCtrlError] = useState<string | null>(null);
@@ -206,8 +179,8 @@ function JailInfoSection({ jail, onRefresh, onStart, onStop, onSetIdle, onReload
};
return (
<div className={styles.section}>
<div className={styles.sectionHeader}>
<div className={sectionStyles.section}>
<div className={sectionStyles.sectionHeader}>
<div className={styles.headerRow}>
<Text
size={600}
@@ -334,10 +307,10 @@ function JailInfoSection({ jail, onRefresh, onStart, onStop, onSetIdle, onReload
// ---------------------------------------------------------------------------
function PatternsSection({ jail }: { jail: Jail }): React.JSX.Element {
const styles = useStyles();
const sectionStyles = useCommonSectionStyles();
return (
<div className={styles.section}>
<div className={styles.sectionHeader}>
<div className={sectionStyles.section}>
<div className={sectionStyles.sectionHeader}>
<Text as="h2" size={500} weight="semibold">
Log Paths &amp; Patterns
</Text>
@@ -374,12 +347,13 @@ function PatternsSection({ jail }: { jail: Jail }): React.JSX.Element {
function BantimeEscalationSection({ jail }: { jail: Jail }): React.JSX.Element | null {
const styles = useStyles();
const sectionStyles = useCommonSectionStyles();
const esc = jail.bantime_escalation;
if (!esc?.increment) return null;
return (
<div className={styles.section}>
<div className={styles.sectionHeader}>
<div className={sectionStyles.section}>
<div className={sectionStyles.sectionHeader}>
<Text as="h2" size={500} weight="semibold">
Ban-time Escalation
</Text>
@@ -445,6 +419,7 @@ function IgnoreListSection({
onToggleIgnoreSelf,
}: IgnoreListSectionProps): React.JSX.Element {
const styles = useStyles();
const sectionStyles = useCommonSectionStyles();
const [inputVal, setInputVal] = useState("");
const [opError, setOpError] = useState<string | null>(null);
@@ -470,8 +445,8 @@ function IgnoreListSection({
};
return (
<div className={styles.section}>
<div className={styles.sectionHeader}>
<div className={sectionStyles.section}>
<div className={sectionStyles.sectionHeader}>
<div style={{ display: "flex", alignItems: "center", gap: tokens.spacingHorizontalM }}>
<Text as="h2" size={500} weight="semibold">
Ignore List (IP Whitelist)

View File

@@ -33,6 +33,7 @@ import {
type TableColumnDefinition,
createTableColumn,
} from "@fluentui/react-components";
import { useCardStyles, useCommonSectionStyles } from "../theme/commonStyles";
import {
ArrowClockwiseRegular,
ArrowSyncRegular,
@@ -58,36 +59,7 @@ const useStyles = makeStyles({
flexDirection: "column",
gap: tokens.spacingVerticalL,
},
section: {
display: "flex",
flexDirection: "column",
gap: tokens.spacingVerticalS,
backgroundColor: tokens.colorNeutralBackground1,
borderRadius: tokens.borderRadiusMedium,
borderTopWidth: "1px",
borderTopStyle: "solid",
borderTopColor: tokens.colorNeutralStroke2,
borderRightWidth: "1px",
borderRightStyle: "solid",
borderRightColor: tokens.colorNeutralStroke2,
borderBottomWidth: "1px",
borderBottomStyle: "solid",
borderBottomColor: tokens.colorNeutralStroke2,
borderLeftWidth: "1px",
borderLeftStyle: "solid",
borderLeftColor: tokens.colorNeutralStroke2,
padding: tokens.spacingVerticalM,
},
sectionHeader: {
display: "flex",
alignItems: "center",
justifyContent: "space-between",
gap: tokens.spacingHorizontalM,
paddingBottom: tokens.spacingVerticalS,
borderBottomWidth: "1px",
borderBottomStyle: "solid",
borderBottomColor: tokens.colorNeutralStroke2,
},
tableWrapper: { overflowX: "auto" },
centred: {
display: "flex",
@@ -117,20 +89,6 @@ const useStyles = makeStyles({
gap: tokens.spacingVerticalS,
marginTop: tokens.spacingVerticalS,
padding: tokens.spacingVerticalS,
backgroundColor: tokens.colorNeutralBackground2,
borderRadius: tokens.borderRadiusMedium,
borderTopWidth: "1px",
borderTopStyle: "solid",
borderTopColor: tokens.colorNeutralStroke2,
borderRightWidth: "1px",
borderRightStyle: "solid",
borderRightColor: tokens.colorNeutralStroke2,
borderBottomWidth: "1px",
borderBottomStyle: "solid",
borderBottomColor: tokens.colorNeutralStroke2,
borderLeftWidth: "1px",
borderLeftStyle: "solid",
borderLeftColor: tokens.colorNeutralStroke2,
},
lookupRow: {
display: "flex",
@@ -208,6 +166,7 @@ const jailColumns: TableColumnDefinition<JailSummary>[] = [
function JailOverviewSection(): React.JSX.Element {
const styles = useStyles();
const sectionStyles = useCommonSectionStyles();
const { jails, total, loading, error, refresh, startJail, stopJail, setIdle, reloadJail, reloadAll } =
useJails();
const [opError, setOpError] = useState<string | null>(null);
@@ -220,8 +179,8 @@ function JailOverviewSection(): React.JSX.Element {
};
return (
<div className={styles.section}>
<div className={styles.sectionHeader}>
<div className={sectionStyles.section}>
<div className={sectionStyles.sectionHeader}>
<Text as="h2" size={500} weight="semibold">
Jail Overview
{total > 0 && (
@@ -358,6 +317,7 @@ interface BanUnbanFormProps {
function BanUnbanForm({ jailNames, onBan, onUnban }: BanUnbanFormProps): React.JSX.Element {
const styles = useStyles();
const sectionStyles = useCommonSectionStyles();
const [banIpVal, setBanIpVal] = useState("");
const [banJail, setBanJail] = useState("");
const [unbanIpVal, setUnbanIpVal] = useState("");
@@ -415,8 +375,8 @@ function BanUnbanForm({ jailNames, onBan, onUnban }: BanUnbanFormProps): React.J
};
return (
<div className={styles.section}>
<div className={styles.sectionHeader}>
<div className={sectionStyles.section}>
<div className={sectionStyles.sectionHeader}>
<Text as="h2" size={500} weight="semibold">
Ban / Unban IP
</Text>
@@ -544,6 +504,8 @@ function BanUnbanForm({ jailNames, onBan, onUnban }: BanUnbanFormProps): React.J
function IpLookupSection(): React.JSX.Element {
const styles = useStyles();
const sectionStyles = useCommonSectionStyles();
const cardStyles = useCardStyles();
const { result, loading, error, lookup, clear } = useIpLookup();
const [inputVal, setInputVal] = useState("");
@@ -554,8 +516,8 @@ function IpLookupSection(): React.JSX.Element {
};
return (
<div className={styles.section}>
<div className={styles.sectionHeader}>
<div className={sectionStyles.section}>
<div className={sectionStyles.sectionHeader}>
<Text as="h2" size={500} weight="semibold">
IP Lookup
</Text>
@@ -595,7 +557,7 @@ function IpLookupSection(): React.JSX.Element {
)}
{result && (
<div className={styles.lookupResult}>
<div className={`${cardStyles.card} ${styles.lookupResult}`}>
<div className={styles.lookupRow}>
<Text className={styles.lookupLabel}>IP:</Text>
<Text className={styles.mono}>{result.ip}</Text>

View File

@@ -0,0 +1,30 @@
import { makeStyles, tokens } from "@fluentui/react-components";
export const useCommonSectionStyles = makeStyles({
section: {
display: "flex",
flexDirection: "column",
gap: tokens.spacingVerticalS,
backgroundColor: tokens.colorNeutralBackground1,
borderRadius: tokens.borderRadiusMedium,
border: `1px solid ${tokens.colorNeutralStroke2}`,
padding: tokens.spacingVerticalM,
},
sectionHeader: {
display: "flex",
alignItems: "center",
justifyContent: "space-between",
gap: tokens.spacingHorizontalM,
paddingBottom: tokens.spacingVerticalS,
borderBottom: `1px solid ${tokens.colorNeutralStroke2}`,
},
});
export const useCardStyles = makeStyles({
card: {
backgroundColor: tokens.colorNeutralBackground1,
borderRadius: tokens.borderRadiusMedium,
border: `1px solid ${tokens.colorNeutralStroke2}`,
padding: tokens.spacingVerticalM,
},
});