ui improvement
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
import { useMemo, useState } from 'react';
|
||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import { Text } from '@astryxdesign/core/Text';
|
||||
import { VStack } from '@astryxdesign/core/VStack';
|
||||
import { Bike, Check, Truck } from 'lucide-react';
|
||||
import { errorMessage } from '@/api/client';
|
||||
@@ -8,7 +7,7 @@ import { tenantsApi } from '@/api/tenants';
|
||||
import { useAllPartners, useAppRegions } from '@/queries/hooks';
|
||||
import { queryKeys } from '@/queries/keys';
|
||||
import { Drawer } from '@/features/store-admin/Drawer';
|
||||
import { DrawerButton, DrawerCard, Note, Row, Section } from '@/features/store-admin/drawerKit';
|
||||
import { Alert, DrawerButton, DrawerCard, Note, Row, Section } from '@/features/store-admin/drawerKit';
|
||||
|
||||
/**
|
||||
* Which delivery partner supplies a merchant's riders.
|
||||
@@ -89,11 +88,7 @@ export function PartnerAssignDrawer({
|
||||
}
|
||||
>
|
||||
<VStack gap={2}>
|
||||
{error ? (
|
||||
<Text type="body" size="sm" style={{ color: 'var(--color-error, #d64545)' }}>
|
||||
{error}
|
||||
</Text>
|
||||
) : null}
|
||||
{error ? <Alert>{error}</Alert> : null}
|
||||
|
||||
<Note icon={<Bike size={15} />}>
|
||||
A partner supplies riders to this shop. With one set, the assign screen offers the
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
import { useState } from 'react';
|
||||
import { Button } from '@astryxdesign/core/Button';
|
||||
import { Text } from '@astryxdesign/core/Text';
|
||||
import { VStack } from '@astryxdesign/core/VStack';
|
||||
import { Bike, Plus } from 'lucide-react';
|
||||
import type { Partner, RiderRosterRow } from '@/api/deliveries';
|
||||
import { usePartnerRiders } from '@/queries/hooks';
|
||||
import { Drawer } from '@/features/store-admin/Drawer';
|
||||
import { Badge, DrawerButton, DrawerCard, Note, Row, Section } from '@/features/store-admin/drawerKit';
|
||||
import {
|
||||
Badge,
|
||||
DrawerButton,
|
||||
DrawerCard,
|
||||
LinkAction,
|
||||
Note,
|
||||
Row,
|
||||
Section,
|
||||
} from '@/features/store-admin/drawerKit';
|
||||
import { RiderDrawer } from '@/features/store-admin/RiderDrawer';
|
||||
|
||||
/**
|
||||
@@ -59,7 +64,11 @@ export function PartnerRidersDrawer({
|
||||
</>
|
||||
}
|
||||
>
|
||||
<VStack gap={2}>
|
||||
{/* No `VStack` around this. The drawer body IS a column with the
|
||||
system's own gap; a second stack inside it set a second, different
|
||||
one, which is why this drawer's sections sat closer together than
|
||||
every other drawer's. */}
|
||||
<>
|
||||
<Note icon={<Bike size={15} />}>
|
||||
These riders deliver for every merchant this partner supplies. A rider hired here does
|
||||
not appear in the on-duty fleet until they open the rider app and start a shift — that
|
||||
@@ -67,9 +76,7 @@ export function PartnerRidersDrawer({
|
||||
</Note>
|
||||
|
||||
{riders.isLoading ? (
|
||||
<Text type="body" size="sm" color="secondary">
|
||||
Reading riders…
|
||||
</Text>
|
||||
<Note>Reading riders…</Note>
|
||||
) : rows.length === 0 ? (
|
||||
<Section title="No riders yet">
|
||||
<DrawerCard>
|
||||
@@ -88,17 +95,17 @@ export function PartnerRidersDrawer({
|
||||
key={rider.userid}
|
||||
label={rider.fullname?.trim() || rider.firstname || `Rider ${rider.userid}`}
|
||||
value={
|
||||
<span style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
|
||||
<span style={{ display: 'inline-flex', alignItems: 'center', gap: 12 }}>
|
||||
<Badge
|
||||
label={rider.isonduty ? 'On duty' : 'Off shift'}
|
||||
colour={rider.isonduty ? '#0f8a5f' : 'var(--color-ink-4)'}
|
||||
/>
|
||||
<Button
|
||||
label="Edit"
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={() => setEditing(rider)}
|
||||
/* The success token, not a hex green typed here. The
|
||||
#0f8a5f this used was a fourth green in a console
|
||||
that has one. */
|
||||
colour={
|
||||
rider.isonduty ? 'var(--color-success, #1f9d55)' : 'var(--color-ink-4)'
|
||||
}
|
||||
/>
|
||||
<LinkAction label="Edit" onClick={() => setEditing(rider)} />
|
||||
</span>
|
||||
}
|
||||
/>
|
||||
@@ -106,7 +113,7 @@ export function PartnerRidersDrawer({
|
||||
</DrawerCard>
|
||||
</Section>
|
||||
)}
|
||||
</VStack>
|
||||
</>
|
||||
</Drawer>
|
||||
|
||||
{editing ? (
|
||||
|
||||
@@ -139,7 +139,7 @@ export function ShiftsPanel({ partnerid }: { partnerid: number }) {
|
||||
</div>
|
||||
|
||||
<div className="fleet-body">
|
||||
<Card padding={0} elevation="low">
|
||||
<Card padding={0}>
|
||||
<VStack gap={1.5} padding={2}>
|
||||
<Text type="label" size="sm" weight="semibold">
|
||||
Where the fleet is registered
|
||||
@@ -162,7 +162,7 @@ export function ShiftsPanel({ partnerid }: { partnerid: number }) {
|
||||
</VStack>
|
||||
</Card>
|
||||
|
||||
<Card padding={0} elevation="low">
|
||||
<Card padding={0}>
|
||||
<VStack gap={1.5} padding={2}>
|
||||
<Text type="label" size="sm" weight="semibold">
|
||||
The day, rider by rider
|
||||
@@ -202,7 +202,7 @@ export function ShiftsPanel({ partnerid }: { partnerid: number }) {
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<Card padding={0} elevation="low">
|
||||
<Card padding={0}>
|
||||
<VStack gap={1} padding={2}>
|
||||
<HStack gap={1} align="center">
|
||||
<span className="fleet-note-icon">
|
||||
|
||||
@@ -138,7 +138,7 @@ export function OnboardTenantPage() {
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<Card padding={4} elevation="low">
|
||||
<Card padding={4}>
|
||||
<VStack gap={3}>
|
||||
<HStack align="center" gap={1.5}>
|
||||
<CheckCircle2 size={24} style={{ color: 'var(--color-success, #10b981)' }} />
|
||||
@@ -153,7 +153,7 @@ export function OnboardTenantPage() {
|
||||
</Text>
|
||||
|
||||
{created?.tenantid && created?.locationid ? (
|
||||
<Card padding={3} elevation="low" variant="transparent">
|
||||
<Card padding={3} variant="transparent">
|
||||
<StoreQrPanel
|
||||
tenantid={created.tenantid}
|
||||
locationid={created.locationid}
|
||||
@@ -241,7 +241,7 @@ export function OnboardTenantPage() {
|
||||
</div>
|
||||
|
||||
{/* Section 1: Business Details Card */}
|
||||
<Card padding={0} elevation="low">
|
||||
<Card padding={0}>
|
||||
<VStack gap={2} padding={3}>
|
||||
<div
|
||||
style={{
|
||||
@@ -318,7 +318,7 @@ export function OnboardTenantPage() {
|
||||
</Card>
|
||||
|
||||
{/* Section 2: Head Office Card */}
|
||||
<Card padding={0} elevation="low">
|
||||
<Card padding={0}>
|
||||
<VStack gap={2} padding={3}>
|
||||
<div
|
||||
style={{
|
||||
|
||||
@@ -8,7 +8,6 @@ import { useMemo, useState } from 'react';
|
||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import { Badge } from '@astryxdesign/core/Badge';
|
||||
import { Button } from '@astryxdesign/core/Button';
|
||||
import { Card } from '@astryxdesign/core/Card';
|
||||
import { HStack } from '@astryxdesign/core/HStack';
|
||||
import { Table, type TableColumn } from '@astryxdesign/core/Table';
|
||||
import { Text } from '@astryxdesign/core/Text';
|
||||
@@ -28,6 +27,8 @@ import { Selector } from '@astryxdesign/core/Selector';
|
||||
import { districtOptions, isRunning, matchDistrict } from '../tamilNaduDistricts';
|
||||
import { DataState } from '@/components/DataState';
|
||||
import { PageHeader } from '@/components/PageHeader';
|
||||
import { Panel } from '@/components/Panel';
|
||||
import { SearchInput } from '@/components/SearchInput';
|
||||
import { TablePager } from '@/components/TablePager';
|
||||
import { usePaged } from '@/components/usePaged';
|
||||
import {
|
||||
@@ -256,7 +257,11 @@ export function PartnersPage() {
|
||||
/>
|
||||
|
||||
{/* Partners Table Card */}
|
||||
<Card padding={0} elevation="low" style={{ background: '#ffffff', borderRadius: 12 }}>
|
||||
<Panel
|
||||
count={paged.total}
|
||||
countLabel="partners"
|
||||
footer={<TablePager paged={paged} label="partners" />}
|
||||
>
|
||||
<DataState
|
||||
isLoading={partners.isLoading}
|
||||
error={null}
|
||||
@@ -274,9 +279,8 @@ export function PartnersPage() {
|
||||
dividers="rows"
|
||||
/>
|
||||
</div>
|
||||
<TablePager paged={paged} label="partners" />
|
||||
</DataState>
|
||||
</Card>
|
||||
</Panel>
|
||||
|
||||
{/* Drawers */}
|
||||
{ridersFor ? (
|
||||
@@ -553,14 +557,15 @@ function PartnerDrawer({ partner, onClose }: { partner: Partner | null; onClose:
|
||||
<Text type="label" size="sm" weight="semibold">
|
||||
District
|
||||
</Text>
|
||||
<TextInput
|
||||
{/* Full width, not a fixed one: this sits above the 38-row district
|
||||
list it filters, inside a drawer, and a 260px box over a list that
|
||||
fills the panel reads as unrelated to it. */}
|
||||
<SearchInput
|
||||
label="Search districts"
|
||||
isLabelHidden
|
||||
size="sm"
|
||||
value={districtSearch}
|
||||
onChange={setDistrictSearch}
|
||||
placeholder="Search all 38 districts…"
|
||||
hasClear
|
||||
width="full"
|
||||
/>
|
||||
<div className="district-list" role="listbox" aria-label="Tamil Nadu districts">
|
||||
{shown.map((option) => {
|
||||
|
||||
@@ -2,7 +2,6 @@ import { useMemo, useState } from 'react';
|
||||
import { Link, useParams } from 'react-router-dom';
|
||||
import { Badge } from '@astryxdesign/core/Badge';
|
||||
import { Button } from '@astryxdesign/core/Button';
|
||||
import { Card } from '@astryxdesign/core/Card';
|
||||
import { HStack } from '@astryxdesign/core/HStack';
|
||||
import { Table, type TableColumn } from '@astryxdesign/core/Table';
|
||||
import { Text } from '@astryxdesign/core/Text';
|
||||
@@ -12,10 +11,10 @@ import { DataState } from '@/components/DataState';
|
||||
import { Freshness } from '@/components/Freshness';
|
||||
import { KpiCard } from '@/components/KpiCard';
|
||||
import { PageHeader } from '@/components/PageHeader';
|
||||
import { SectionHeader } from '@/components/SectionHeader';
|
||||
import { useOrderSummary, useOrders, useTenantLocations, useTenants } from '@/queries/hooks';
|
||||
import { branchOrderStats, NO_ORDERS } from '@/features/store-admin/branchStats';
|
||||
import type { TenantInfo, TenantLocation } from '@/api/types';
|
||||
import { Panel } from '@/components/Panel';
|
||||
import { TablePager } from '@/components/TablePager';
|
||||
import { usePaged } from '@/components/usePaged';
|
||||
import { Drawer } from '@/features/store-admin/Drawer';
|
||||
@@ -279,12 +278,13 @@ export function StoreDetailPage() {
|
||||
</div>
|
||||
|
||||
<VStack gap={1.5}>
|
||||
<SectionHeader
|
||||
<Panel
|
||||
title="Branches"
|
||||
action={<Freshness updatedAt={summary.dataUpdatedAt} isFetching={summary.isFetching} />}
|
||||
/>
|
||||
|
||||
<Card padding={0} elevation="low">
|
||||
count={paged.total}
|
||||
countLabel="branches"
|
||||
actions={<Freshness updatedAt={summary.dataUpdatedAt} isFetching={summary.isFetching} />}
|
||||
footer={<TablePager paged={paged} label="branches" />}
|
||||
>
|
||||
<DataState
|
||||
isLoading={isLoading}
|
||||
error={error}
|
||||
@@ -307,9 +307,8 @@ export function StoreDetailPage() {
|
||||
dividers="rows"
|
||||
/>
|
||||
</div>
|
||||
<TablePager paged={paged} label="branches" />
|
||||
</DataState>
|
||||
</Card>
|
||||
</Panel>
|
||||
</VStack>
|
||||
|
||||
{isPartnerOpen && tenantid ? (
|
||||
|
||||
@@ -6,13 +6,14 @@ import { Card } from '@astryxdesign/core/Card';
|
||||
import { Table, type TableColumn } from '@astryxdesign/core/Table';
|
||||
import { HStack } from '@astryxdesign/core/HStack';
|
||||
import { Text } from '@astryxdesign/core/Text';
|
||||
import { TextInput } from '@astryxdesign/core/TextInput';
|
||||
import { VStack } from '@astryxdesign/core/VStack';
|
||||
import { Building2, Plus, Store, Users } from 'lucide-react';
|
||||
import { SearchInput } from '@/components/SearchInput';
|
||||
import { DataState } from '@/components/DataState';
|
||||
import { KpiCard } from '@/components/KpiCard';
|
||||
import { PageHeader } from '@/components/PageHeader';
|
||||
import { SectionHeader } from '@/components/SectionHeader';
|
||||
import { Tab, TabBar } from '@/components/TabBar';
|
||||
import { Panel } from '@/components/Panel';
|
||||
import { useTenants, useTenantsByApproval } from '@/queries/hooks';
|
||||
import type { TenantInfo } from '@/api/types';
|
||||
|
||||
@@ -240,43 +241,66 @@ export function StoresPage() {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<HStack gap={0.5} wrap="wrap">
|
||||
<TabButton
|
||||
<TabBar>
|
||||
<Tab
|
||||
label="Directory"
|
||||
isActive={tab === 'directory'}
|
||||
onClick={() => setTab('directory')}
|
||||
/>
|
||||
<TabButton
|
||||
<Tab
|
||||
label="Awaiting approval"
|
||||
isActive={tab === 'pending'}
|
||||
badge={pending.data?.length || undefined}
|
||||
count={pending.data?.length || undefined}
|
||||
onClick={() => setTab('pending')}
|
||||
/>
|
||||
</HStack>
|
||||
</TabBar>
|
||||
|
||||
{tab === 'pending' ? (
|
||||
<PendingPanel rows={pending.data ?? []} isLoading={pending.isLoading} />
|
||||
) : (
|
||||
<VStack gap={1.5}>
|
||||
<SectionHeader
|
||||
title="Tenant directory"
|
||||
note={`${rows.length} shown`}
|
||||
action={
|
||||
<div className="toolbar-stack" style={{ maxWidth: 260 }}>
|
||||
<TextInput
|
||||
label="Search tenants"
|
||||
isLabelHidden
|
||||
value={search}
|
||||
onChange={setSearch}
|
||||
placeholder="Search by name, company or city…"
|
||||
hasClear
|
||||
/* The title, the count and the search are the panel's header band now.
|
||||
The search filters THIS table; floating above the card it read as a
|
||||
page-level control that happened to sit nearby, and the count was a
|
||||
note beside a heading rather than the figure you check a filter
|
||||
against. */
|
||||
<Panel
|
||||
footer={
|
||||
<HStack justify="between" align="center" gap={1} wrap="wrap">
|
||||
<Text type="body" size="sm" color="secondary">
|
||||
Page {page}
|
||||
{search ? ` · filtered from ${rows.length} on this page` : ''}
|
||||
</Text>
|
||||
<HStack gap={1}>
|
||||
<Button
|
||||
label="Previous"
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
isDisabled={page === 1}
|
||||
onClick={() => setPage((current) => Math.max(1, current - 1))}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
|
||||
<Card padding={0} elevation="low">
|
||||
<Button
|
||||
label="Next"
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
isDisabled={(data?.length ?? 0) <= PAGE_SIZE}
|
||||
onClick={() => setPage((current) => current + 1)}
|
||||
/>
|
||||
</HStack>
|
||||
</HStack>
|
||||
}
|
||||
title="Tenant directory"
|
||||
count={rows.length}
|
||||
countLabel="tenants"
|
||||
actions={
|
||||
<SearchInput
|
||||
label="Search tenants"
|
||||
value={search}
|
||||
onChange={setSearch}
|
||||
placeholder="Name, company or city…"
|
||||
width={260}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<DataState
|
||||
isLoading={isLoading}
|
||||
error={error}
|
||||
@@ -306,31 +330,7 @@ export function StoresPage() {
|
||||
/>
|
||||
</div>
|
||||
</DataState>
|
||||
</Card>
|
||||
|
||||
<HStack justify="between" align="center" gap={1} wrap="wrap">
|
||||
<Text type="body" size="sm" color="secondary">
|
||||
Page {page}
|
||||
{search ? ` · filtered from ${rows.length} on this page` : ''}
|
||||
</Text>
|
||||
<HStack gap={1}>
|
||||
<Button
|
||||
label="Previous"
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
isDisabled={page === 1}
|
||||
onClick={() => setPage((current) => Math.max(1, current - 1))}
|
||||
/>
|
||||
<Button
|
||||
label="Next"
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
isDisabled={(data?.length ?? 0) <= PAGE_SIZE}
|
||||
onClick={() => setPage((current) => current + 1)}
|
||||
/>
|
||||
</HStack>
|
||||
</HStack>
|
||||
</VStack>
|
||||
</Panel>
|
||||
)}
|
||||
</VStack>
|
||||
);
|
||||
@@ -348,7 +348,7 @@ export function StoresPage() {
|
||||
function PendingPanel({ rows, isLoading }: { rows: TenantInfo[]; isLoading: boolean }) {
|
||||
if (isLoading) {
|
||||
return (
|
||||
<Card padding={0} elevation="low">
|
||||
<Card padding={0}>
|
||||
<VStack padding={3}>
|
||||
<Text type="body" size="sm" color="secondary">
|
||||
Reading the approval queue…
|
||||
@@ -360,7 +360,7 @@ function PendingPanel({ rows, isLoading }: { rows: TenantInfo[]; isLoading: bool
|
||||
|
||||
if (rows.length === 0) {
|
||||
return (
|
||||
<Card padding={0} elevation="low">
|
||||
<Card padding={0}>
|
||||
<VStack gap={0.5} padding={3}>
|
||||
<Text type="label" size="sm" weight="semibold">
|
||||
Nothing waiting
|
||||
@@ -379,7 +379,7 @@ function PendingPanel({ rows, isLoading }: { rows: TenantInfo[]; isLoading: bool
|
||||
These merchants exist but are not approved, so they do not appear in the directory.
|
||||
Approving is a database change today — the backend has no endpoint for it.
|
||||
</Text>
|
||||
<Card padding={0} elevation="low">
|
||||
<Card padding={0}>
|
||||
<div className="table-scroll">
|
||||
<table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 13 }}>
|
||||
<thead>
|
||||
@@ -409,59 +409,7 @@ function PendingPanel({ rows, isLoading }: { rows: TenantInfo[]; isLoading: bool
|
||||
);
|
||||
}
|
||||
|
||||
function TabButton({
|
||||
label,
|
||||
isActive,
|
||||
onClick,
|
||||
badge,
|
||||
}: {
|
||||
label: string;
|
||||
isActive: boolean;
|
||||
onClick: () => void;
|
||||
badge?: number;
|
||||
}) {
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
onClick={onClick}
|
||||
aria-pressed={isActive}
|
||||
style={{
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
gap: 6,
|
||||
height: 32,
|
||||
padding: '0 12px',
|
||||
borderRadius: 12,
|
||||
border: 0,
|
||||
background: isActive ? 'var(--color-brand-tint)' : 'transparent',
|
||||
color: isActive ? 'var(--color-brand)' : 'var(--color-ink-3)',
|
||||
fontSize: 13,
|
||||
fontWeight: isActive ? 600 : 500,
|
||||
cursor: 'pointer',
|
||||
}}
|
||||
>
|
||||
{label}
|
||||
{badge ? (
|
||||
<span
|
||||
style={{
|
||||
minWidth: 18,
|
||||
height: 18,
|
||||
padding: '0 5px',
|
||||
borderRadius: 999,
|
||||
background: 'var(--color-warning, #b7860b)',
|
||||
color: '#fff',
|
||||
fontSize: 11,
|
||||
fontWeight: 700,
|
||||
display: 'grid',
|
||||
placeItems: 'center',
|
||||
}}
|
||||
>
|
||||
{badge}
|
||||
</span>
|
||||
) : null}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
/* The page-local `TabButton` lived here — see `components/TabBar`. */
|
||||
|
||||
function Th({ children }: { children?: React.ReactNode }) {
|
||||
return (
|
||||
|
||||
@@ -2,20 +2,37 @@
|
||||
* The fleet page: a banner, a map beside a gantt, and the gantt itself.
|
||||
*/
|
||||
|
||||
/* The console's small control: a branch picker, a rider-partner picker and the
|
||||
Shifts day input all wear this.
|
||||
|
||||
Its own shape before was 32px at a 7px corner — a seventh radius in an app
|
||||
that has one. It takes the search box's measurements now, which matters most
|
||||
on Inventory, where a `.fleet-select` branch picker sits immediately beside a
|
||||
`SearchInput`: the two were a different height AND a different corner, six
|
||||
pixels apart. */
|
||||
.fleet-select {
|
||||
height: 32px;
|
||||
height: 38px;
|
||||
padding: 0 10px;
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: 7px;
|
||||
background: var(--color-surface);
|
||||
border: var(--card-border);
|
||||
border-radius: var(--card-radius-sm);
|
||||
background: var(--card-bg);
|
||||
box-shadow: var(--card-shadow);
|
||||
font: inherit;
|
||||
font-size: 13px;
|
||||
color: var(--color-ink-1);
|
||||
transition: border-color 160ms ease, box-shadow 160ms ease;
|
||||
}
|
||||
|
||||
.fleet-select:hover { border-color: var(--color-ink-4); }
|
||||
|
||||
/* The same focus treatment as the search box — a brand border and a 3px tint
|
||||
ring, not the global 2px outline, so two controls sitting side by side do
|
||||
not light up in different ways. */
|
||||
.fleet-select:focus,
|
||||
.fleet-select:focus-visible {
|
||||
outline: 2px solid var(--color-brand);
|
||||
outline-offset: 1px;
|
||||
outline: none;
|
||||
border-color: var(--color-brand);
|
||||
box-shadow: 0 0 0 3px var(--color-brand-tint);
|
||||
}
|
||||
|
||||
/* ── The recommendation banner ───────────────────────────────────────────── */
|
||||
@@ -30,8 +47,8 @@
|
||||
padding: 12px 14px;
|
||||
border: 1px solid var(--color-border);
|
||||
border-left-width: 3px;
|
||||
border-radius: 9px;
|
||||
background: var(--color-surface);
|
||||
border-radius: var(--card-radius);
|
||||
background: var(--card-bg);
|
||||
}
|
||||
|
||||
.fleet-banner > svg {
|
||||
|
||||
Reference in New Issue
Block a user