Merge branch 'main' into rd-hn-.create-DeviceHealthPage

This commit is contained in:
Hristo Nedelkov 2023-08-14 09:53:14 +03:00
commit 1fe342f9fe
18 changed files with 509 additions and 15 deletions

View File

@ -8,7 +8,23 @@
}
}
span {
/* span {
display: inline-block;
vertical-align: middle;
line-height: 1;
} */
.mb-1 {
margin-bottom: 1em;
}
.mt-1 {
margin-top: 1em;
}
.my-1 {
margin-top: 1em;
margin-bottom: 1em;
}
.py-05 {
padding-top: 0.5em;
padding-bottom: 0.5em;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

3
src/assets/chevron.svg Normal file
View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="none">
<path d="M7.75006 14.5L12.2503 9.99994L7.75 5.50002" stroke="#09101C" stroke-width="1.2"/>
</svg>

After

Width:  |  Height:  |  Size: 201 B

View File

@ -0,0 +1,15 @@
import './breadcrumbbar.css'
function BreadcrumbBar() {
return (
<nav className="breadcrumb-bar-nav">
<ul className="breadcrumb-bar-ul">
<li className="breadcrumb-bar-li">Nodes</li>
<li className="breadcrumb-bar-li">Nimbus</li>
<li className="breadcrumb-bar-li">Connect Device</li>
</ul>
</nav>
)
}
export default BreadcrumbBar

View File

@ -0,0 +1,18 @@
function ConnectIcon() {
return (
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="20/connection">
<path
id="body"
fillRule="evenodd"
clipRule="evenodd"
d="M9.99978 1.8999C8.21669 1.8999 6.48343 2.48826 5.06881 3.57374C3.6542 4.65921 2.63728 6.18114 2.17578 7.90347L3.33489 8.21405C3.72802 6.74688 4.59428 5.45043 5.79933 4.52576C7.00437 3.6011 8.48086 3.0999 9.99978 3.0999C11.5187 3.0999 12.9952 3.6011 14.2002 4.52577C15.4053 5.45043 16.2715 6.74688 16.6647 8.21405L17.8238 7.90347C17.3623 6.18114 16.3454 4.65922 14.9307 3.57374C13.5161 2.48827 11.7829 1.8999 9.99978 1.8999ZM9.99988 4.9C8.87719 4.9 7.78588 5.27045 6.8952 5.9539C6.00451 6.63734 5.36423 7.59559 5.07366 8.68002L6.23277 8.9906C6.45497 8.16133 6.9446 7.42856 7.62571 6.90592C8.30682 6.38329 9.14136 6.1 9.99988 6.1C10.8584 6.1 11.6929 6.38329 12.374 6.90592C13.0552 7.42856 13.5448 8.16134 13.767 8.99061L14.9261 8.68002C14.6355 7.59559 13.9952 6.63735 13.1046 5.9539C12.2139 5.27045 11.1226 4.9 9.99988 4.9ZM9.99988 10.1C8.95054 10.1 8.09988 10.9507 8.09988 12C8.09988 13.0493 8.95054 13.9 9.99988 13.9C11.0492 13.9 11.8999 13.0493 11.8999 12C11.8999 10.9507 11.0492 10.1 9.99988 10.1ZM6.89988 12C6.89988 10.2879 8.2878 8.9 9.99988 8.9C11.712 8.9 13.0999 10.2879 13.0999 12C13.0999 13.5068 12.0248 14.7625 10.5999 15.042V17.5H9.39988V15.042C7.97494 14.7625 6.89988 13.5068 6.89988 12Z"
fill="#1B273D"
fillOpacity="0.7"
/>
</g>
</svg>
)
}
export default ConnectIcon

View File

@ -0,0 +1,112 @@
import { useState } from 'react'
import BreadcrumbBar from './BreadcrumbBar'
import { Button as StatusButton, Tag, Text, Avatar, Checkbox } from '@status-im/components'
import { Label, Separator, XStack, YStack } from 'tamagui'
import LayoutComponent from './LayoutComponent'
import NimbusLogo from './NimbusLogo'
import Titles from './Titles'
import NodeIcon from './NodeIcon'
import ConnectIcon from './ConnectIcon'
import PairIcon from './PairIcon'
import CreateIcon from './CreateIcon'
import LabelInputField from './LabelInputField'
function ContentPage() {
return <LayoutComponent breadcrumbBar={<BreadcrumbBar />} content={<Content />} />
}
function Content() {
const [autoConnectChecked, setAutoConnectChecked] = useState(false)
const [portChecked, setPortChecked] = useState(false)
return (
<div className="container-inner connection-page">
<header>
<NimbusLogo />
<XStack space={'$2'} alignItems="center">
<Tag icon={ConnectIcon} label="Connect" size={32} selected />
<Tag icon={PairIcon} label="Pair" size={32} />
<Tag icon={CreateIcon} label="Create" size={32} />
</XStack>
</header>
<article className="content">
<section className="mb-1">
<Titles
title="Connect Device"
subtitle="Configure your device to connect to the Nimbus Node Manager"
/>
</section>
<section className="mb-1">
<XStack
width={'100%'}
alignItems="center"
justifyContent="space-between"
// media query
$lg={{
flexDirection: 'column',
flexWrap: 'nowrap',
}}
>
<XStack width={'40%'}>
<LabelInputField labelText="Beacon Address" placeholderText="something" />
</XStack>
<XStack width={'25%'}>
<LabelInputField labelText="Beacon Node Port" placeholderText="5052" />
</XStack>
<XStack width={'25%'}>
<LabelInputField labelText="Client Validator Port" placeholderText="5052" />
</XStack>
<YStack width={20}>
<Checkbox
id="port-checkbox"
variant="outline"
selected={portChecked}
onCheckedChange={v => setPortChecked(v)}
/>
</YStack>
</XStack>
<XStack width={'100%'} alignItems="center">
<LabelInputField labelText="API Token" placeholderText="****_*****_*****" />
</XStack>
</section>
<section className="mb-1">
<YStack>
<Text size={13} weight="regular" color={'#647084'}>
Device Avatar
</Text>
<XStack my={10}>
<Avatar type="user" size={80} name="Device Avatar" />
</XStack>
<XStack space>
<LabelInputField labelText="Device Name" placeholderText="Stake and chips" />
<LabelInputField labelText="Device Color" placeholderText="#011892" />
</XStack>
</YStack>
</section>
<Separator alignSelf="stretch" borderColor={'#F0F2F5'} />
<section className="my-1">
<YStack>
<Text size={19} weight="semibold">
Settings
</Text>
</YStack>
<XStack my={8} space={'$2'}>
<Checkbox
id="auto-connect"
selected={autoConnectChecked}
onCheckedChange={v => setAutoConnectChecked(v)}
variant="outline"
/>
<Label htmlFor="auto-connect">
<Text size={15} weight="regular">
Auto Connect Device
</Text>
</Label>
</XStack>
<Separator alignSelf="stretch" borderColor={'#F0F2F5'} />
</section>
<StatusButton icon={<NodeIcon />}>Connect Device</StatusButton>
</article>
</div>
)
}
export default ContentPage

View File

@ -0,0 +1,16 @@
function CreateIcon() {
return (
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="none">
<circle cx="10" cy="10" r="7.5" stroke="#1B273D" strokeOpacity="0.7" strokeWidth="1.2" />
<path
fillRule="evenodd"
clipRule="evenodd"
d="M10.6 9.4V6.5H9.4V9.4L6.5 9.4V10.6L9.4 10.6V13.5H10.6V10.6L13.5 10.6L13.5 9.4L10.6 9.4Z"
fill="#1B273D"
fillOpacity="0.7"
/>
</svg>
)
}
export default CreateIcon

View File

@ -0,0 +1,74 @@
import StandartLineChart from './StandardLineChart'
import IconText from './IconText'
import { Paragraph, Separator, XStack, YStack } from 'tamagui'
import { Shadow as ShadowBox } from '@status-im/components'
type DataPoint = {
x: number
y: number
}
type ChartData = {
id: string
color: string
data: DataPoint[]
maxValue?: number
}
type DeviceMemoryProps = {
currentMemory: number[]
maxMemory?: number
}
const DeviceMemory = ({ currentMemory, maxMemory }: DeviceMemoryProps) => {
const chartData: ChartData[] = [
{
id: 'cpu',
color: '#8DC6BC',
data: currentMemory.map((yValue, index: number) => ({
x: index + 1,
y: yValue,
})),
maxValue: maxMemory,
},
]
const currentLoad =
chartData[0].data.length > 0 ? chartData[0].data[chartData[0].data.length - 1].y : 0
const message = currentLoad < 80 ? 'Good' : 'Poor'
return (
<ShadowBox style={{ width: '284px', height: '136px' }}>
<YStack>
<XStack
justifyContent="space-between"
style={{
padding: '8px 16px',
position: 'relative', // Make XStack a positioning context
}}
>
<div style={{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0 }}>
<StandartLineChart data={chartData} />
</div>
<YStack space={'$3'}>
<Paragraph color={'#09101C'} size={'$6'} fontWeight={'600'}>
Memory
</Paragraph>
<Paragraph color={'#09101C'} size={'$8'} fontWeight={'700'}>
{currentLoad} GB
</Paragraph>
</YStack>
</XStack>
<Separator borderColor={'#e3e3e3'} />
<XStack space={'$4'} style={{ padding: '10px 16px 10px 16px' }}>
<IconText icon={message === 'Good' ? '/icons/check-circle.png' : '/icons/alert.png'}>
{message}
</IconText>
{/* <Text color={'#E95460'}>This is additional text</Text> */}
</XStack>
</YStack>
</ShadowBox>
)
}
export default DeviceMemory

View File

@ -0,0 +1,79 @@
import StandartLineChart from './StandardLineChart'
import IconText from './IconText'
import { Paragraph, Separator, XStack, YStack } from 'tamagui'
import { Shadow as ShadowBox } from '@status-im/components'
type DataPoint = {
x: number
y: number
}
type ChartData = {
id: string
color: string
data: DataPoint[]
}
type DeviceNetworkHealthProps = {
uploadRate: number[]
downloadRate: number[]
}
const DeviceNetworkHealth = ({ uploadRate, downloadRate }: DeviceNetworkHealthProps) => {
const chartData: ChartData[] = [
{
id: 'uploadRate',
color: '#8DC6BC',
data: uploadRate.map((yValue, index: number) => ({
x: index + 1,
y: yValue,
})),
},
{
id: 'downloadRate',
color: '#D92344',
data: downloadRate.map((yValue, index: number) => ({
x: index + 1,
y: yValue,
})),
},
]
const currentLoad =
chartData[0].data.length > 0 ? chartData[0].data[chartData[0].data.length - 1].y : 0
const message = currentLoad < 80 ? 'Good' : 'Poor'
return (
<ShadowBox style={{ width: '284px', height: '136px' }}>
<YStack>
<XStack
justifyContent="space-between"
style={{
padding: '8px 16px',
position: 'relative', // Make XStack a positioning context
}}
>
<div style={{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0 }}>
<StandartLineChart data={chartData} />
</div>
<YStack space={'$3'}>
<Paragraph color={'#09101C'} size={'$6'} fontWeight={'600'}>
Network
</Paragraph>
<Paragraph color={'#09101C'} size={'$8'} fontWeight={'700'}>
{currentLoad} GB
</Paragraph>
</YStack>
</XStack>
<Separator borderColor={'#e3e3e3'} />
<XStack space={'$4'} style={{ padding: '10px 16px 10px 16px' }}>
<IconText icon={message === 'Good' ? '/icons/check-circle.png' : '/icons/alert.png'}>
{message}
</IconText>
{/* <Text color={'#E95460'}>This is additional text</Text> */}
</XStack>
</YStack>
</ShadowBox>
)
}
export default DeviceNetworkHealth

View File

@ -0,0 +1,20 @@
import { Input as StatusInput, Text } from '@status-im/components'
import { Label } from 'tamagui'
type LabelInputProps = {
labelText: string
placeholderText: string
}
function LabelInputField({ labelText, placeholderText }: LabelInputProps) {
return (
<Label flexDirection="column" alignItems="flex-start" my={10} width={'100%'}>
<Text size={13} weight="regular" color={'#647084'}>
{labelText}
</Text>
<StatusInput placeholder={placeholderText} width={'100%'} />
</Label>
)
}
export default LabelInputField

View File

@ -101,4 +101,5 @@ function Content() {
</div>
)
}
export default LandingPage

View File

@ -0,0 +1,34 @@
function NodeIcon() {
return (
<span>
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
viewBox="0 0 20 20"
fill="none"
>
<g clipPath="url(#clip0_760_1602)">
<path
fillRule="evenodd"
clipRule="evenodd"
d="M4.9999 2.60002C3.67442 2.60002 2.5999 3.67454 2.5999 5.00002C2.5999 6.32551 3.67442 7.40002 4.9999 7.40002C6.32539 7.40002 7.3999 6.32551 7.3999 5.00002C7.3999 3.67454 6.32539 2.60002 4.9999 2.60002ZM1.3999 5.00002C1.3999 3.0118 3.01168 1.40002 4.9999 1.40002C6.98813 1.40002 8.5999 3.0118 8.5999 5.00002C8.5999 5.77749 8.35345 6.4974 7.9344 7.08587L9.48712 8.63859C10.4478 7.86383 11.6697 7.4 13 7.4C16.0928 7.4 18.6 9.90721 18.6 13C18.6 16.0928 16.0928 18.6 13 18.6C9.9072 18.6 7.4 16.0928 7.4 13C7.4 11.6697 7.86383 10.4478 8.63859 9.48712L7.08589 7.93442C6.49739 8.35353 5.77743 8.60002 4.9999 8.60002C3.01168 8.60002 1.3999 6.98825 1.3999 5.00002ZM8.6 13C8.6 10.5699 10.5699 8.6 13 8.6C15.4301 8.6 17.4 10.5699 17.4 13C17.4 15.4301 15.4301 17.4 13 17.4C10.5699 17.4 8.6 15.4301 8.6 13Z"
fill="white"
fillOpacity="0.7"
/>
<path
d="M7.9344 7.08587L7.52711 6.79585C7.3855 6.99472 7.40821 7.26679 7.58085 7.43943L7.9344 7.08587ZM9.48712 8.63859L9.13357 8.99215C9.31425 9.17283 9.6021 9.18821 9.801 9.0278L9.48712 8.63859ZM8.63859 9.48712L9.0278 9.801C9.18821 9.6021 9.17283 9.31425 8.99215 9.13357L8.63859 9.48712ZM7.08589 7.93442L7.43945 7.58087C7.26681 7.40823 6.99472 7.38552 6.79585 7.52715L7.08589 7.93442ZM3.0999 5.00002C3.0999 3.95068 3.95056 3.10002 4.9999 3.10002V2.10002C3.39828 2.10002 2.0999 3.3984 2.0999 5.00002H3.0999ZM4.9999 6.90002C3.95056 6.90002 3.0999 6.04937 3.0999 5.00002H2.0999C2.0999 6.60165 3.39828 7.90002 4.9999 7.90002V6.90002ZM6.8999 5.00002C6.8999 6.04937 6.04924 6.90002 4.9999 6.90002V7.90002C6.60153 7.90002 7.8999 6.60165 7.8999 5.00002H6.8999ZM4.9999 3.10002C6.04924 3.10002 6.8999 3.95068 6.8999 5.00002H7.8999C7.8999 3.3984 6.60153 2.10002 4.9999 2.10002V3.10002ZM4.9999 0.900024C2.73553 0.900024 0.899902 2.73566 0.899902 5.00002H1.8999C1.8999 3.28794 3.28782 1.90002 4.9999 1.90002V0.900024ZM9.0999 5.00002C9.0999 2.73566 7.26427 0.900024 4.9999 0.900024V1.90002C6.71198 1.90002 8.0999 3.28794 8.0999 5.00002H9.0999ZM8.34169 7.3759C8.81905 6.70553 9.0999 5.88483 9.0999 5.00002H8.0999C8.0999 5.67015 7.88784 6.28926 7.52711 6.79585L8.34169 7.3759ZM9.84068 8.28504L8.28795 6.73232L7.58085 7.43943L9.13357 8.99215L9.84068 8.28504ZM9.801 9.0278C10.676 8.32213 11.788 7.9 13 7.9V6.9C11.5514 6.9 10.2196 7.40554 9.17324 8.24939L9.801 9.0278ZM13 7.9C15.8167 7.9 18.1 10.1833 18.1 13H19.1C19.1 9.63106 16.3689 6.9 13 6.9V7.9ZM18.1 13C18.1 15.8167 15.8167 18.1 13 18.1V19.1C16.3689 19.1 19.1 16.3689 19.1 13H18.1ZM13 18.1C10.1833 18.1 7.9 15.8167 7.9 13H6.9C6.9 16.3689 9.63106 19.1 13 19.1V18.1ZM7.9 13C7.9 11.788 8.32213 10.676 9.0278 9.801L8.24939 9.17324C7.40554 10.2196 6.9 11.5514 6.9 13H7.9ZM6.73234 8.28798L8.28504 9.84068L8.99215 9.13357L7.43945 7.58087L6.73234 8.28798ZM4.9999 9.10002C5.88478 9.10002 6.70554 8.81913 7.37594 8.3417L6.79585 7.52715C6.28924 7.88793 5.67008 8.10002 4.9999 8.10002V9.10002ZM0.899902 5.00002C0.899902 7.26439 2.73553 9.10002 4.9999 9.10002V8.10002C3.28782 8.10002 1.8999 6.71211 1.8999 5.00002H0.899902ZM13 8.1C10.2938 8.1 8.1 10.2938 8.1 13H9.1C9.1 10.8461 10.8461 9.1 13 9.1V8.1ZM17.9 13C17.9 10.2938 15.7062 8.1 13 8.1V9.1C15.1539 9.1 16.9 10.8461 16.9 13H17.9ZM13 17.9C15.7062 17.9 17.9 15.7062 17.9 13H16.9C16.9 15.1539 15.1539 16.9 13 16.9V17.9ZM8.1 13C8.1 15.7062 10.2938 17.9 13 17.9V16.9C10.8461 16.9 9.1 15.1539 9.1 13H8.1Z"
fill="white"
/>
</g>
<defs>
<clipPath id="clip0_760_1602">
<rect width="20" height="20" fill="white" />
</clipPath>
</defs>
</svg>
</span>
)
}
export default NodeIcon

View File

@ -0,0 +1,61 @@
function PairIcon() {
return (
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fillRule="evenodd"
clipRule="evenodd"
d="M13.4517 10.8951L16.952 6.89508L17.2978 6.49996L16.952 6.10484L13.4517 2.10489L12.5486 2.89514L15.7032 6.49997L12.5486 10.1049L13.4517 10.8951ZM6.5487 9.10488L3.0484 13.1049L2.70264 13.5001L3.0484 13.8952L6.5487 17.8951L7.45176 17.1049L4.29722 13.5L7.45176 9.89512L6.5487 9.10488Z"
fill="#1B273D"
fillOpacity="0.7"
/>
<rect
x="4"
y="7.5"
width="2"
height="12"
transform="rotate(-90 4 7.5)"
fill="url(#paint0_linear_760_2959)"
/>
<g mask="url(#mask0_760_2959)">
<path d="M4.5 6.50006L16 6.50006" stroke="#1B273D" strokeOpacity="0.7" strokeWidth="1.2" />
</g>
<rect
x="16"
y="12.5"
width="2"
height="12"
transform="rotate(90 16 12.5)"
fill="url(#paint1_linear_760_2959)"
/>
<g mask="url(#mask1_760_2959)">
<path d="M15.5 13.4999L4 13.4999" stroke="#1B273D" strokeOpacity="0.7" strokeWidth="1.2" />
</g>
<defs>
<linearGradient
id="paint0_linear_760_2959"
x1="5"
y1="8"
x2="5"
y2="13.5"
gradientUnits="userSpaceOnUse"
>
<stop stopColor="#09101C" stopOpacity="0" />
<stop offset="1" stopColor="#09101C" />
</linearGradient>
<linearGradient
id="paint1_linear_760_2959"
x1="17"
y1="13"
x2="17"
y2="18.5"
gradientUnits="userSpaceOnUse"
>
<stop stopColor="#09101C" stopOpacity="0" />
<stop offset="1" stopColor="#09101C" />
</linearGradient>
</defs>
</svg>
)
}
export default PairIcon

View File

@ -6,13 +6,18 @@ interface DataPoint {
interface ChartData {
id: string
color: string
data: DataPoint[]
maxValue?: number
}
interface StandartLineChartProps {
data: ChartData[]
}
const StandartLineChart = ({ data }: StandartLineChartProps) => {
const maxMemory = data[0].maxValue || 'auto'
const colors = data.map(dataset => dataset.color)
return (
<ResponsiveLine
data={data}
@ -20,8 +25,8 @@ const StandartLineChart = ({ data }: StandartLineChartProps) => {
xScale={{ type: 'linear', min: 0, max: data[0].data.length }}
yScale={{
type: 'linear',
min: 'auto',
max: 'auto',
min: 0,
max: maxMemory,
stacked: true,
reverse: false,
}}
@ -32,14 +37,11 @@ const StandartLineChart = ({ data }: StandartLineChartProps) => {
enableGridX={false}
enableGridY={false}
enablePoints={false}
pointSize={1}
pointColor={{ theme: 'background' }}
pointBorderWidth={2}
pointBorderColor={{ from: 'serieColor' }}
pointLabelYOffset={-12}
useMesh={true}
legends={[]}
colors={['#8DC6BC']}
colors={colors}
/>
)
}

View File

@ -1,8 +1,7 @@
import { XStack, YStack } from 'tamagui'
import Title from './Title'
import SubTitle from './SubTitle'
import { Button } from '@status-im/components'
import { Button, Text } from '@status-im/components'
import Icon from './Icon'
import Title from './Title'
type TitlesProps = {
title: string
@ -21,7 +20,9 @@ const Titles = ({ title, subtitle, isAdvancedSettings }: TitlesProps) => {
</Button>
)}
</XStack>
<SubTitle color={'#09101C'}>{subtitle}</SubTitle>
<Text size={15} weight="regular">
{subtitle}
</Text>
</YStack>
)
}

View File

@ -0,0 +1,35 @@
.breadcrumb-bar-nav {
width: 100%;
flex: 1 1 100%;
padding: 1rem 2rem;
margin: 0.5rem;
}
.breadcrumb-bar-ul {
list-style-type: none;
display: flex;
padding: 0;
margin: 0;
}
.breadcrumb-bar-li {
padding: 0 1em;
color: #647084;
font-size: 15px;
font-weight: 500;
position: relative;
}
.breadcrumb-bar-li::after {
display: inline-block;
content: url("../assets/chevron.svg");
color: #09101C;
position: absolute;
top: -2px;
left: 100%;
transform: translateX(-50%);
}
.breadcrumb-bar-li:last-child {
color: #09101C;
}
.breadcrumb-bar-li:last-child::after {
display: none;
}

View File

@ -9,10 +9,11 @@
.layout-left {
flex: 0 0 55%;
max-width: 55%;
z-index: 2;
}
.container {
display: flex;
flex-wrap: wrap;
flex-wrap: wrap;
justify-content: end;
height: 100%;
margin: 0 auto;
@ -21,13 +22,14 @@
max-width: 70%;
flex: 1 0 70%;
display: flex;
flex-wrap: wrap;
/* flex-wrap: wrap; */
flex-direction: column;
}
header {
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
padding: 1.5rem 0;
}
header > div {
display: flex;
@ -49,8 +51,12 @@ header > div {
padding: 4px 6px;
margin-left: 10px;
}
.content {
flex-grow: 1;
}
.content .title {
font-size: 27px;
font-weight: 600;
margin-bottom: 0.25em;
}
.content .subtitle {
@ -75,6 +81,7 @@ header > div {
.layout-right {
flex: 0 0 45%;
max-width: 45%;
z-index: 0;
}
.image-container {

View File

@ -46,7 +46,7 @@ a:hover {
button {
border-radius: 12px;
border: 1px solid transparent;
padding: 0.6em 1.2em;
/* padding: 0.6em 1.2em; */
font-size: 15px;
font-weight: 500;
font-family: inherit;