init
This commit was merged in pull request #8.
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
# Design migration matrix
|
||||
|
||||
`design/src-web` is the implementation source for component structure, CSS, assets and visual
|
||||
interaction states. Migration means adapting that implementation to Vue and Reka UI; it does not
|
||||
mean recreating the effect from screenshots.
|
||||
|
||||
## Rules
|
||||
|
||||
- Port the existing DOM anatomy, CSS values and raster assets before optimizing them.
|
||||
- Keep pixel-accurate atomic dimensions, but expose component width and density through props or
|
||||
CSS custom properties.
|
||||
- Move reusable colors and metrics into semantic `--ui-*` tokens after visual parity is established.
|
||||
- Keep page data, routing and stores outside `src/components/ui`.
|
||||
- Delete a legacy `calc-*` component only after all of its call sites have migrated.
|
||||
|
||||
## Matrix
|
||||
|
||||
| Design source | Current target | Status | Migration notes |
|
||||
| ----------------------- | --------------------------------------------------------- | ----------- | -------------------------------------------------------- |
|
||||
| `foundations`, `shared` | `style/tokens`, `style/themes`, shared UI contract | Migrated | Semantic color and overridable geometry contracts |
|
||||
| `button` | `ui/button` | Migrated | Preserved three-slice states; exposed density and width |
|
||||
| `input` | `ui/input`, `ui/number-field` | Migrated | Removed forced inline width; normalized text metrics |
|
||||
| `form-controls` | `ui/checkbox`, `ui/radio-group`, `ui/switch`, `ui/rating` | Migrated | Tokenized state colors and aligned label/control anatomy |
|
||||
| `select` | `ui/select` | Migrated | Preserved popup anatomy and Reka keyboard behavior |
|
||||
| `tabs` | `ui/tabs` | Migrated | Preserved list-owned animated marker |
|
||||
| `slider` | `ui/slider` | Migrated | Preserved the Reka coordinate system |
|
||||
| `data-table` | `ui/data-table` | Migrated | Ported hover, selected and density behavior |
|
||||
| `dialog` | `ui/dialog` | Migrated | Preserved the focused title effect and focus management |
|
||||
| `menu` | `ui/dropdown-menu` | Migrated | Ported source menu spacing and state tokens |
|
||||
| `rarity` | `ui/item-slot` | Migrated | Retained rarity presentation as data-semantic tokens |
|
||||
| `autocomplete` | `ui/autocomplete` | Migrated | Reka Combobox composition with source popup anatomy |
|
||||
| `navigation` | `ui/navigation` | Migrated | Selectable navigation primitive with source assets |
|
||||
| `scrollbar` | `ui/scroll-area` | Migrated | Reusable Reka viewport/scrollbar composition |
|
||||
| `data-section` | `ui/data-section` | Migrated | Collapsible section and vertically centered data rows |
|
||||
| `shop-item-row` | `ui/shop-item-row` | Migrated | Ported source row structure and selectable states |
|
||||
| `complex-dialog` | `ui/dialog` + migrated primitives | Composition | Kept domain-independent by composing existing primitives |
|
||||
| `settings` | `ui/settings` | Migrated | Responsive settings group, section and row primitives |
|
||||
|
||||
## Legacy replacement order
|
||||
|
||||
Deferred: this component-library pass does not change business call sites.
|
||||
|
||||
1. Shared form controls and overlays used by DNF Helper and import dialogs.
|
||||
2. Forge controls (`select`, `checkbox`, `slider`, tabs and panels).
|
||||
3. Equipment dictionary filters, tree, cascader and pagination.
|
||||
4. Skill tree, skill detail and VP controls.
|
||||
5. Result tables and remaining domain-specific components.
|
||||
@@ -0,0 +1,234 @@
|
||||
<script setup lang="ts">
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import {
|
||||
ComboboxAnchor,
|
||||
ComboboxContent,
|
||||
ComboboxEmpty,
|
||||
ComboboxInput,
|
||||
ComboboxItem,
|
||||
ComboboxItemIndicator,
|
||||
ComboboxPortal,
|
||||
ComboboxRoot,
|
||||
ComboboxTrigger,
|
||||
ComboboxViewport,
|
||||
} from 'reka-ui'
|
||||
import selectArrow from '../../../../../design/src-web/shared/img/sprite_interface.NPK/windowcommon_2x.img/0.PNG'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
export interface UiAutocompleteOption {
|
||||
value: string
|
||||
label: string
|
||||
disabled?: boolean
|
||||
tone?: 'normal' | 'rare' | 'artifact' | 'legend' | 'epic'
|
||||
}
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
class?: HTMLAttributes['class']
|
||||
options: UiAutocompleteOption[]
|
||||
placeholder?: string
|
||||
emptyText?: string
|
||||
disabled?: boolean
|
||||
}>(),
|
||||
{ emptyText: '没有匹配项' },
|
||||
)
|
||||
|
||||
const model = defineModel<string>()
|
||||
const open = ref(false)
|
||||
|
||||
function displayValue(value: string | undefined) {
|
||||
return props.options.find((option) => option.value === value)?.label ?? value ?? ''
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ComboboxRoot
|
||||
v-model="model"
|
||||
v-model:open="open"
|
||||
:disabled="disabled"
|
||||
open-on-click
|
||||
open-on-focus
|
||||
:class="cn('ui-autocomplete', props.class)"
|
||||
>
|
||||
<ComboboxAnchor class="ui-autocomplete__anchor">
|
||||
<ComboboxInput
|
||||
class="ui-autocomplete__input"
|
||||
:display-value="displayValue"
|
||||
:placeholder="placeholder"
|
||||
/>
|
||||
<ComboboxTrigger class="ui-autocomplete__trigger" aria-label="展开候选项">
|
||||
<img :src="selectArrow" alt="" />
|
||||
</ComboboxTrigger>
|
||||
</ComboboxAnchor>
|
||||
<ComboboxPortal>
|
||||
<ComboboxContent class="ui-autocomplete__content" position="popper" :side-offset="2">
|
||||
<ComboboxViewport class="ui-autocomplete__viewport">
|
||||
<ComboboxEmpty class="ui-autocomplete__empty">{{ emptyText }}</ComboboxEmpty>
|
||||
<ComboboxItem
|
||||
v-for="option in options"
|
||||
:key="option.value"
|
||||
:value="option.value"
|
||||
:disabled="option.disabled"
|
||||
class="ui-autocomplete__item"
|
||||
:class="option.tone && `quality-${option.tone}`"
|
||||
>
|
||||
<span>{{ option.label }}</span>
|
||||
<ComboboxItemIndicator class="ui-autocomplete__indicator">◆</ComboboxItemIndicator>
|
||||
</ComboboxItem>
|
||||
</ComboboxViewport>
|
||||
</ComboboxContent>
|
||||
</ComboboxPortal>
|
||||
</ComboboxRoot>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.ui-autocomplete {
|
||||
display: block;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.ui-autocomplete__anchor {
|
||||
box-sizing: border-box;
|
||||
display: grid;
|
||||
width: 100%;
|
||||
height: var(--ui-control-height-default);
|
||||
grid-template-columns: minmax(0, 1fr) var(--ui-select-icon-inline-size);
|
||||
align-items: center;
|
||||
gap: var(--ui-autocomplete-trigger-gap);
|
||||
padding: 0 4px 0 var(--ui-field-padding-inline);
|
||||
border: 1px solid var(--ui-input);
|
||||
background: var(--ui-field-background);
|
||||
box-shadow: inset 0 0 0 1px var(--ui-field-inset);
|
||||
|
||||
&:focus-within,
|
||||
&[data-state='open'] {
|
||||
border-color: var(--ui-ring);
|
||||
box-shadow:
|
||||
inset 0 0 0 1px var(--ui-field-focus-inset),
|
||||
0 0 0 1px var(--ui-field-focus-edge);
|
||||
}
|
||||
}
|
||||
|
||||
.ui-autocomplete__input {
|
||||
min-width: 0;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
outline: 0;
|
||||
background: transparent;
|
||||
color: var(--ui-primary-foreground);
|
||||
font: inherit;
|
||||
font-size: var(--ui-control-font-size-default);
|
||||
line-height: var(--ui-control-line-height);
|
||||
|
||||
&::placeholder {
|
||||
color: var(--ui-muted-foreground);
|
||||
}
|
||||
}
|
||||
|
||||
.ui-autocomplete__trigger {
|
||||
display: inline-flex;
|
||||
width: var(--ui-select-icon-inline-size);
|
||||
height: var(--ui-select-icon-block-size);
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0;
|
||||
border: 1px solid var(--ui-control-border);
|
||||
outline: none;
|
||||
background: var(--ui-control-background);
|
||||
box-shadow: 0 0 0 1px var(--ui-select-icon-shadow);
|
||||
cursor: pointer;
|
||||
|
||||
&:hover,
|
||||
&:focus-visible {
|
||||
border-color: var(--ui-control-border-active);
|
||||
background: var(--ui-control-background-hover);
|
||||
}
|
||||
|
||||
&:active img {
|
||||
transform: translateY(1px);
|
||||
}
|
||||
|
||||
img {
|
||||
width: var(--ui-select-glyph-inline-size);
|
||||
height: var(--ui-select-glyph-block-size);
|
||||
image-rendering: pixelated;
|
||||
}
|
||||
}
|
||||
|
||||
.ui-autocomplete__content {
|
||||
z-index: 80;
|
||||
min-width: var(--reka-combobox-trigger-width);
|
||||
max-height: min(
|
||||
var(--ui-autocomplete-max-block-size),
|
||||
var(--reka-combobox-content-available-height)
|
||||
);
|
||||
overflow: hidden;
|
||||
border: 1px solid var(--ui-popup-border);
|
||||
background: var(--ui-popup-background);
|
||||
box-shadow: 0 8px 18px var(--ui-popup-shadow);
|
||||
color: var(--ui-popover-foreground);
|
||||
}
|
||||
|
||||
.ui-autocomplete__viewport {
|
||||
max-height: inherit;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.ui-autocomplete__item,
|
||||
.ui-autocomplete__empty {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
height: var(--ui-option-height);
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 var(--ui-field-padding-inline);
|
||||
border-bottom: 1px solid var(--ui-option-divider);
|
||||
outline: none;
|
||||
color: var(--ui-primary-foreground);
|
||||
font-size: var(--ui-control-font-size-default);
|
||||
line-height: var(--ui-control-line-height);
|
||||
}
|
||||
|
||||
.ui-autocomplete__item {
|
||||
cursor: pointer;
|
||||
|
||||
&[data-highlighted] {
|
||||
outline: 1px solid var(--ui-ring);
|
||||
outline-offset: -2px;
|
||||
background: var(--ui-option-highlight-background);
|
||||
color: var(--ui-option-highlight-foreground);
|
||||
}
|
||||
|
||||
&[data-state='checked'] {
|
||||
background: var(--ui-disclosure-row-selected);
|
||||
color: var(--ui-selected);
|
||||
}
|
||||
|
||||
&[data-disabled] {
|
||||
pointer-events: none;
|
||||
color: var(--ui-control-disabled-foreground);
|
||||
}
|
||||
}
|
||||
|
||||
.ui-autocomplete__empty {
|
||||
color: var(--ui-muted-foreground);
|
||||
}
|
||||
|
||||
.ui-autocomplete__indicator {
|
||||
font-size: var(--ui-autocomplete-indicator-font-size);
|
||||
}
|
||||
|
||||
.quality-rare {
|
||||
color: var(--dcalc-quality-rare);
|
||||
}
|
||||
.quality-artifact {
|
||||
color: var(--dcalc-quality-artifact);
|
||||
}
|
||||
.quality-legend {
|
||||
color: var(--dcalc-quality-legend);
|
||||
}
|
||||
.quality-epic {
|
||||
color: var(--dcalc-quality-epic);
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,2 @@
|
||||
export { default as UiAutocomplete } from './UiAutocomplete.vue'
|
||||
export type { UiAutocompleteOption } from './UiAutocomplete.vue'
|
||||
@@ -1,8 +1,6 @@
|
||||
import { cva, type VariantProps } from 'class-variance-authority'
|
||||
|
||||
export const badgeVariants = cva(
|
||||
'inline-flex h-[18px] items-center rounded-none border px-[7px] text-[10px] font-normal leading-none',
|
||||
{
|
||||
export const badgeVariants = cva('ui-badge', {
|
||||
variants: {
|
||||
variant: {
|
||||
default: 'border-border bg-primary text-primary-foreground',
|
||||
@@ -14,7 +12,6 @@ export const badgeVariants = cva(
|
||||
defaultVariants: {
|
||||
variant: 'default',
|
||||
},
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
export type BadgeVariants = VariantProps<typeof badgeVariants>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { cva, type VariantProps } from 'class-variance-authority'
|
||||
|
||||
export const buttonVariants = cva(
|
||||
'ui-button inline-flex items-center justify-center gap-2 whitespace-nowrap outline-none transition-[color,background,border-color,transform] disabled:pointer-events-none [&_[data-icon]]:pointer-events-none [&_[data-icon]]:shrink-0',
|
||||
'ui-button inline-flex items-center justify-center whitespace-nowrap text-center leading-none outline-none transition-[color,background,border-color,transform] disabled:pointer-events-none [&_[data-icon]]:pointer-events-none [&_[data-icon]]:shrink-0',
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
@@ -12,10 +12,10 @@ export const buttonVariants = cva(
|
||||
ghost: 'ui-button--ghost',
|
||||
},
|
||||
size: {
|
||||
default: 'h-[30px] min-w-[110px] px-[14px] text-[13px]',
|
||||
sm: 'h-6 min-w-20 px-2.5 text-xs',
|
||||
lg: 'h-11 min-w-[168px] px-5 text-base',
|
||||
icon: 'size-[30px] min-w-[30px] p-0',
|
||||
default: 'ui-button--size-default',
|
||||
sm: 'ui-button--size-compact',
|
||||
lg: 'ui-button--size-large',
|
||||
icon: 'ui-button--size-icon',
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
|
||||
@@ -25,7 +25,7 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||
v-bind="forwarded"
|
||||
:class="
|
||||
cn(
|
||||
'ui-checkbox peer inline-flex size-4 shrink-0 items-center justify-center border outline-none disabled:cursor-not-allowed',
|
||||
'ui-checkbox peer inline-flex shrink-0 items-center justify-center border outline-none disabled:cursor-not-allowed',
|
||||
props.class,
|
||||
)
|
||||
"
|
||||
@@ -36,27 +36,29 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||
|
||||
<style scoped>
|
||||
.ui-checkbox {
|
||||
--check-edge-top: #635036;
|
||||
--check-edge-bottom: #3c2e1b;
|
||||
--check-top: #242424;
|
||||
--check-bottom: #0f0f0f;
|
||||
--check-edge-top: var(--ui-check-edge-top);
|
||||
--check-edge-bottom: var(--ui-check-edge-bottom);
|
||||
--check-top: var(--ui-check-surface-top);
|
||||
--check-bottom: var(--ui-check-surface-bottom);
|
||||
position: relative;
|
||||
width: var(--ui-checkbox-size);
|
||||
height: var(--ui-checkbox-size);
|
||||
border-color: transparent;
|
||||
border-radius: 0;
|
||||
background:
|
||||
linear-gradient(180deg, var(--check-top), var(--check-bottom)) padding-box,
|
||||
linear-gradient(180deg, var(--check-edge-top), var(--check-edge-bottom)) border-box;
|
||||
box-shadow:
|
||||
0 0 0 1px rgb(0 0 0 / 30%),
|
||||
inset 0 1px 0 rgb(255 255 255 / 2.5%);
|
||||
0 0 0 1px var(--ui-check-outer-shadow),
|
||||
inset 0 1px 0 var(--ui-control-inner-highlight);
|
||||
color: var(--ui-primary-foreground);
|
||||
}
|
||||
|
||||
.ui-checkbox:hover:not(:disabled) {
|
||||
--check-edge-top: #bf9d6a;
|
||||
--check-edge-bottom: #947853;
|
||||
--check-top: #3a3a3a;
|
||||
--check-bottom: #181818;
|
||||
--check-edge-top: var(--ui-check-hover-edge-top);
|
||||
--check-edge-bottom: var(--ui-check-hover-edge-bottom);
|
||||
--check-top: var(--ui-check-hover-surface-top);
|
||||
--check-bottom: var(--ui-check-hover-surface-bottom);
|
||||
}
|
||||
|
||||
.ui-checkbox:focus-visible {
|
||||
@@ -69,19 +71,19 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||
|
||||
.ui-checkbox__indicator {
|
||||
position: absolute;
|
||||
width: 18px;
|
||||
height: 14px;
|
||||
background: linear-gradient(180deg, #dfb142, #eac75f);
|
||||
width: var(--ui-checkbox-mark-inline-size);
|
||||
height: var(--ui-checkbox-mark-block-size);
|
||||
background: linear-gradient(180deg, var(--ui-check-mark-top), var(--ui-check-mark-bottom));
|
||||
clip-path: polygon(0 42%, 7% 34%, 39% 66%, 94% 4%, 100% 10%, 39% 82%);
|
||||
filter: drop-shadow(0 0 1px rgb(230 192 86 / 45%));
|
||||
filter: drop-shadow(0 0 1px var(--ui-check-mark-shadow));
|
||||
animation: check-in 70ms ease-out;
|
||||
}
|
||||
|
||||
.ui-checkbox:disabled {
|
||||
--check-edge-top: #414141;
|
||||
--check-edge-bottom: #252525;
|
||||
--check-top: #1f1f1f;
|
||||
--check-bottom: #0d0d0d;
|
||||
--check-edge-top: var(--ui-check-disabled-edge-top);
|
||||
--check-edge-bottom: var(--ui-check-disabled-edge-bottom);
|
||||
--check-top: var(--ui-check-disabled-surface-top);
|
||||
--check-bottom: var(--ui-check-disabled-surface-bottom);
|
||||
}
|
||||
@keyframes check-in {
|
||||
from {
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
<script setup lang="ts">
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
class?: HTMLAttributes['class']
|
||||
depth?: number
|
||||
selected?: boolean
|
||||
disabled?: boolean
|
||||
}>(),
|
||||
{ depth: 0 },
|
||||
)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
:class="cn('ui-data-row', selected && 'is-selected', disabled && 'is-disabled', props.class)"
|
||||
:style="{ '--ui-data-row-depth': props.depth }"
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.ui-data-row {
|
||||
display: flex;
|
||||
height: var(--ui-disclosure-row-block-size);
|
||||
min-width: 0;
|
||||
align-items: center;
|
||||
gap: var(--ui-disclosure-row-gap);
|
||||
padding-left: calc(var(--ui-data-row-depth) * var(--ui-disclosure-depth-step));
|
||||
border-bottom: 1px solid var(--ui-disclosure-row-divider);
|
||||
color: var(--ui-disclosure-row-foreground);
|
||||
line-height: var(--ui-control-line-height);
|
||||
}
|
||||
|
||||
.ui-data-row:focus-within {
|
||||
outline: 1px solid var(--ui-ring);
|
||||
outline-offset: -2px;
|
||||
background: var(--ui-disclosure-row-focus);
|
||||
}
|
||||
|
||||
.ui-data-row.is-selected {
|
||||
background: var(--ui-disclosure-row-selected);
|
||||
color: var(--ui-disclosure-row-selected-foreground);
|
||||
}
|
||||
|
||||
.ui-data-row.is-disabled {
|
||||
color: var(--ui-control-disabled-foreground);
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,102 @@
|
||||
<script setup lang="ts">
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { CollapsibleContent, CollapsibleRoot, CollapsibleTrigger } from 'reka-ui'
|
||||
import expandedIcon from '../../../../../design/src-web/data-section/img/sprite_interface.NPK/windowcommon.chn.img/565.PNG'
|
||||
import collapsedIcon from '../../../../../design/src-web/data-section/img/sprite_interface.NPK/windowcommon.chn.img/561.PNG'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
class?: HTMLAttributes['class']
|
||||
title: string
|
||||
disabled?: boolean
|
||||
expandedLabel?: string
|
||||
collapsedLabel?: string
|
||||
}>(),
|
||||
{ expandedLabel: '已展开', collapsedLabel: '未展开' },
|
||||
)
|
||||
|
||||
const open = defineModel<boolean>('open', { default: true })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<CollapsibleRoot
|
||||
v-model:open="open"
|
||||
:disabled="disabled"
|
||||
:class="cn('ui-data-section', props.class)"
|
||||
>
|
||||
<CollapsibleTrigger class="ui-data-section__trigger">
|
||||
<img :src="open ? expandedIcon : collapsedIcon" alt="" aria-hidden="true" />
|
||||
<span class="ui-data-section__title">{{ title }}</span>
|
||||
<span class="ui-data-section__state">{{ open ? expandedLabel : collapsedLabel }}</span>
|
||||
</CollapsibleTrigger>
|
||||
<CollapsibleContent class="ui-data-section__content">
|
||||
<slot />
|
||||
</CollapsibleContent>
|
||||
</CollapsibleRoot>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.ui-data-section {
|
||||
border: 1px solid var(--ui-disclosure-border);
|
||||
background: var(--ui-disclosure-background);
|
||||
color: var(--ui-secondary-foreground);
|
||||
|
||||
&[data-state='closed'] .ui-data-section__trigger {
|
||||
border-bottom-color: transparent;
|
||||
}
|
||||
|
||||
&[data-disabled] {
|
||||
opacity: 0.48;
|
||||
}
|
||||
}
|
||||
|
||||
.ui-data-section__trigger {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
min-height: var(--ui-disclosure-header-min-block-size);
|
||||
align-items: center;
|
||||
gap: var(--ui-control-gap);
|
||||
padding: 0 var(--ui-field-padding-inline);
|
||||
border: 0;
|
||||
border-bottom: 1px solid var(--ui-disclosure-divider);
|
||||
outline: none;
|
||||
background: var(--ui-disclosure-header-background);
|
||||
color: inherit;
|
||||
font: inherit;
|
||||
line-height: var(--ui-control-line-height);
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
|
||||
&:focus-visible {
|
||||
outline: 1px solid var(--ui-ring);
|
||||
outline-offset: -2px;
|
||||
}
|
||||
|
||||
&:active > * {
|
||||
transform: translateY(1px);
|
||||
}
|
||||
|
||||
img {
|
||||
width: var(--ui-disclosure-icon-size);
|
||||
height: var(--ui-disclosure-icon-size);
|
||||
object-fit: contain;
|
||||
image-rendering: pixelated;
|
||||
}
|
||||
}
|
||||
|
||||
.ui-data-section__title {
|
||||
min-width: 0;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.ui-data-section__state {
|
||||
color: var(--ui-disclosure-state);
|
||||
font-size: var(--ui-disclosure-state-font-size);
|
||||
}
|
||||
|
||||
.ui-data-section__content {
|
||||
padding: var(--ui-disclosure-content-padding-block) var(--ui-field-padding-inline);
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,2 @@
|
||||
export { default as UiDataRow } from './UiDataRow.vue'
|
||||
export { default as UiDataSection } from './UiDataSection.vue'
|
||||
@@ -75,26 +75,26 @@ const gridTemplate = computed(() => props.columns.map((column) => column.width ?
|
||||
.ui-data-table {
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
border: 1px solid #4a3c26;
|
||||
border: 1px solid var(--ui-table-border);
|
||||
border-radius: 0;
|
||||
background: #030403;
|
||||
color: #d2c78f;
|
||||
background: var(--ui-table-background);
|
||||
color: var(--ui-table-foreground);
|
||||
}
|
||||
|
||||
.ui-data-table__row {
|
||||
display: grid;
|
||||
width: 100%;
|
||||
min-height: 38px;
|
||||
min-height: var(--ui-table-row-min-block-size);
|
||||
align-items: center;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
border-bottom: 1px solid #2c2b26;
|
||||
border-bottom: 1px solid var(--ui-table-row-divider);
|
||||
border-radius: 0;
|
||||
background: transparent;
|
||||
color: inherit;
|
||||
font: 12px/1 inherit;
|
||||
text-align: left;
|
||||
min-width: 560px;
|
||||
min-width: var(--ui-table-scroll-inline-size);
|
||||
}
|
||||
|
||||
button.ui-data-table__row {
|
||||
@@ -108,43 +108,45 @@ button.ui-data-table__row:nth-child(odd) {
|
||||
background: var(--ui-row-background);
|
||||
}
|
||||
button.ui-data-table__row:hover {
|
||||
background: linear-gradient(90deg, #132b43, #0b1824 58%, #070a0d);
|
||||
outline: 1px solid #3b91bd;
|
||||
background: var(--ui-table-row-hover);
|
||||
outline: 1px solid var(--ui-table-row-hover-outline);
|
||||
outline-offset: -1px;
|
||||
}
|
||||
button.ui-data-table__row.is-selected {
|
||||
background: linear-gradient(90deg, #352b11, #161207 60%, #090a08);
|
||||
outline: 1px solid #d6ad37;
|
||||
background: var(--ui-table-row-selected);
|
||||
outline: 1px solid var(--ui-table-row-selected-outline);
|
||||
outline-offset: -1px;
|
||||
box-shadow: inset 0 0 0 1px #6d5218;
|
||||
box-shadow: inset 0 0 0 1px var(--ui-table-row-selected-inset);
|
||||
}
|
||||
|
||||
.ui-data-table__row > * {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
height: 100%;
|
||||
align-items: center;
|
||||
padding: 0 9px;
|
||||
overflow: hidden;
|
||||
border-right: 1px solid #292720;
|
||||
border-right: 1px solid var(--ui-table-cell-divider);
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.ui-data-table__header {
|
||||
min-height: 30px;
|
||||
height: 30px;
|
||||
min-height: var(--ui-table-header-block-size);
|
||||
height: var(--ui-table-header-block-size);
|
||||
column-gap: 1px;
|
||||
border-bottom: 0;
|
||||
background: #030403;
|
||||
background: var(--ui-table-background);
|
||||
}
|
||||
.ui-data-table__header > * {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border: 1px solid #070806;
|
||||
border: 1px solid var(--ui-table-header-border);
|
||||
background: var(--ui-table-header);
|
||||
box-shadow:
|
||||
inset 0 0 0 1px #4a3c26,
|
||||
inset 0 1px 0 #65502a;
|
||||
inset 0 0 0 1px var(--ui-table-header-inset),
|
||||
inset 0 1px 0 var(--ui-table-header-highlight);
|
||||
color: var(--ui-table-header-foreground);
|
||||
font: 11px/1 inherit;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||
v-bind="forwarded"
|
||||
:class="
|
||||
cn(
|
||||
'ui-dialog-content fixed left-1/2 top-1/2 z-50 grid w-[min(92vw,620px)] -translate-x-1/2 -translate-y-1/2 outline-none data-[state=closed]:animate-[dialog-out_120ms_ease-in] data-[state=open]:animate-[dialog-in_160ms_ease-out]',
|
||||
'ui-dialog-content fixed left-1/2 top-1/2 z-50 grid -translate-x-1/2 -translate-y-1/2 outline-none data-[state=closed]:animate-[dialog-out_120ms_ease-in] data-[state=open]:animate-[dialog-in_160ms_ease-out]',
|
||||
props.class,
|
||||
)
|
||||
"
|
||||
@@ -35,13 +35,14 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||
|
||||
<style scoped>
|
||||
.ui-dialog-content {
|
||||
width: min(var(--ui-dialog-viewport-inline-size), var(--ui-dialog-max-inline-size));
|
||||
overflow: hidden;
|
||||
border: 1px solid #6c5a37;
|
||||
border: 1px solid var(--ui-dialog-border);
|
||||
border-radius: 0;
|
||||
background: #050606;
|
||||
background: var(--ui-dialog-background);
|
||||
box-shadow:
|
||||
0 18px 38px rgb(0 0 0 / 80%),
|
||||
inset 0 0 0 1px #0e1418;
|
||||
0 18px 38px var(--ui-dialog-shadow),
|
||||
inset 0 0 0 1px var(--ui-dialog-inset);
|
||||
color: var(--ui-surface-foreground);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -7,12 +7,12 @@
|
||||
<style scoped>
|
||||
.ui-dialog-footer {
|
||||
display: flex;
|
||||
min-height: 38px;
|
||||
min-height: var(--ui-dialog-footer-min-block-size);
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 8px;
|
||||
padding: 4px 8px;
|
||||
border-top: 1px solid #332c22;
|
||||
background: linear-gradient(#20201d, #11110f);
|
||||
border-top: 1px solid var(--ui-dialog-footer-border);
|
||||
background: var(--ui-dialog-footer-background);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -52,19 +52,19 @@ onBeforeUnmount(() => clearInterval(timer))
|
||||
isolation: isolate;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto 1fr;
|
||||
height: 28px;
|
||||
height: var(--ui-dialog-header-block-size);
|
||||
align-items: center;
|
||||
padding: 0 8px;
|
||||
overflow: hidden;
|
||||
border-bottom: 1px solid #1d2735;
|
||||
background: linear-gradient(#303b50, #263247 56%, #1d2839);
|
||||
border-bottom: 1px solid var(--ui-dialog-titlebar-border);
|
||||
background: var(--ui-dialog-titlebar-background);
|
||||
color: var(--ui-titlebar-foreground);
|
||||
text-shadow: 0 1px 1px #000;
|
||||
text-shadow: 0 1px 1px var(--ui-dialog-titlebar-text-shadow);
|
||||
}
|
||||
|
||||
.ui-dialog-header.is-focused {
|
||||
background: linear-gradient(#6079a5, #435a80 55%, #30425f);
|
||||
color: #f4f6f2;
|
||||
background: var(--ui-dialog-titlebar-focused-background);
|
||||
color: var(--ui-dialog-titlebar-focused-foreground);
|
||||
}
|
||||
|
||||
.ui-dialog-header__effect {
|
||||
@@ -72,7 +72,7 @@ onBeforeUnmount(() => clearInterval(timer))
|
||||
z-index: 1;
|
||||
top: 0;
|
||||
left: 50%;
|
||||
width: 1100px;
|
||||
width: var(--ui-dialog-effect-inline-size);
|
||||
height: 100%;
|
||||
max-width: none;
|
||||
object-fit: fill;
|
||||
@@ -101,8 +101,8 @@ onBeforeUnmount(() => clearInterval(timer))
|
||||
|
||||
.ui-dialog-header__close {
|
||||
appearance: none;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
width: var(--ui-dialog-close-size);
|
||||
height: var(--ui-dialog-close-size);
|
||||
padding: 0;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
@@ -114,8 +114,8 @@ onBeforeUnmount(() => clearInterval(timer))
|
||||
}
|
||||
|
||||
.ui-dialog-header__close img {
|
||||
width: 10px;
|
||||
height: 9px;
|
||||
width: var(--ui-dialog-close-glyph-inline-size);
|
||||
height: var(--ui-dialog-close-glyph-block-size);
|
||||
filter: brightness(1);
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ onBeforeUnmount(() => clearInterval(timer))
|
||||
filter: brightness(1.28);
|
||||
}
|
||||
.ui-dialog-header__close:focus-visible {
|
||||
outline: 1px solid rgb(225 204 135 / 72%);
|
||||
outline: 1px solid var(--ui-dialog-close-ring);
|
||||
outline-offset: -2px;
|
||||
}
|
||||
.ui-dialog-header__close:active img {
|
||||
|
||||
@@ -11,10 +11,16 @@ const delegatedProps = computed(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DialogTitle
|
||||
v-bind="delegatedProps"
|
||||
:class="cn('text-[13px] font-normal text-[#f0f2ef]', props.class)"
|
||||
>
|
||||
<DialogTitle v-bind="delegatedProps" :class="cn('ui-dialog-title', props.class)">
|
||||
<slot />
|
||||
</DialogTitle>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.ui-dialog-title {
|
||||
color: var(--ui-titlebar-foreground);
|
||||
font-size: var(--ui-control-font-size-default);
|
||||
font-weight: 400;
|
||||
line-height: var(--ui-control-line-height);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -37,12 +37,12 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||
.ui-dropdown-content {
|
||||
position: relative;
|
||||
z-index: 80;
|
||||
min-width: 190px;
|
||||
min-width: var(--ui-menu-min-inline-size);
|
||||
padding: 3px 3px 4px;
|
||||
border: 1px solid rgb(19 17 13 / 92%);
|
||||
border: 1px solid var(--ui-menu-border);
|
||||
border-radius: 0;
|
||||
background: rgb(48 46 38 / 72%);
|
||||
box-shadow: 0 10px 20px rgb(0 0 0 / 78%);
|
||||
background: var(--ui-menu-background);
|
||||
box-shadow: 0 10px 20px var(--ui-menu-shadow);
|
||||
backdrop-filter: blur(1px);
|
||||
color: var(--ui-popover-foreground);
|
||||
transform-origin: var(--reka-dropdown-menu-content-transform-origin);
|
||||
|
||||
@@ -31,21 +31,23 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||
<style scoped>
|
||||
.ui-dropdown-item {
|
||||
display: flex;
|
||||
height: 28px;
|
||||
height: var(--ui-menu-item-block-size);
|
||||
align-items: center;
|
||||
padding: 0 7px;
|
||||
border: 1px solid transparent;
|
||||
outline: none;
|
||||
color: var(--ui-primary-foreground);
|
||||
font-size: var(--ui-control-font-size-default);
|
||||
line-height: var(--ui-control-line-height);
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.ui-dropdown-item[data-highlighted] {
|
||||
border-color: #000;
|
||||
background: rgb(15 14 12 / 28%);
|
||||
color: #ffefad;
|
||||
box-shadow: inset 0 0 0 1px rgb(132 113 76 / 13%);
|
||||
border-color: var(--ui-menu-highlight-border);
|
||||
background: var(--ui-menu-highlight-background);
|
||||
color: var(--ui-menu-highlight-foreground);
|
||||
box-shadow: inset 0 0 0 1px var(--ui-menu-highlight-inset);
|
||||
}
|
||||
|
||||
.ui-dropdown-item[data-disabled] {
|
||||
@@ -54,6 +56,6 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||
}
|
||||
|
||||
.ui-dropdown-item--danger {
|
||||
color: #eb7c79;
|
||||
color: var(--ui-menu-danger);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -25,15 +25,18 @@ const model = defineModel<string | number>()
|
||||
.ui-input {
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
padding: 0 9px;
|
||||
min-width: 0;
|
||||
height: var(--ui-control-height-default);
|
||||
padding: 0 var(--ui-field-padding-inline);
|
||||
border: 1px solid var(--ui-input);
|
||||
border-radius: 0;
|
||||
outline: none;
|
||||
background: linear-gradient(#0b0c0d, #000100);
|
||||
box-shadow: inset 0 0 0 1px #050505;
|
||||
background: var(--ui-field-background);
|
||||
box-shadow: inset 0 0 0 1px var(--ui-field-inset);
|
||||
color: var(--ui-foreground);
|
||||
font: inherit;
|
||||
font-size: var(--ui-control-font-size-default);
|
||||
line-height: var(--ui-control-line-height);
|
||||
}
|
||||
|
||||
.ui-input::placeholder {
|
||||
@@ -44,14 +47,14 @@ const model = defineModel<string | number>()
|
||||
.ui-input:focus-visible {
|
||||
border-color: var(--ui-ring);
|
||||
box-shadow:
|
||||
inset 0 0 0 1px #071722,
|
||||
0 0 0 1px #24617c;
|
||||
inset 0 0 0 1px var(--ui-field-focus-inset),
|
||||
0 0 0 1px var(--ui-field-focus-edge);
|
||||
}
|
||||
|
||||
.ui-input:disabled {
|
||||
cursor: not-allowed;
|
||||
border-color: var(--ui-control-disabled-border);
|
||||
background: #101110;
|
||||
background: var(--ui-field-disabled-background);
|
||||
color: var(--ui-control-disabled-foreground);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -42,18 +42,18 @@ const frames: Record<Rarity, string> = {
|
||||
.ui-item-slot {
|
||||
position: relative;
|
||||
display: flex;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
width: var(--ui-item-slot-size);
|
||||
height: var(--ui-item-slot-size);
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 0;
|
||||
background: #030404;
|
||||
background: var(--ui-item-slot-background);
|
||||
}
|
||||
|
||||
.ui-item-slot__item,
|
||||
.ui-item-slot__frame {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
width: var(--ui-item-image-size);
|
||||
height: var(--ui-item-image-size);
|
||||
image-rendering: pixelated;
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ const frames: Record<Rarity, string> = {
|
||||
.ui-item-slot__frame {
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
inset: 5px;
|
||||
inset: var(--ui-item-frame-inset);
|
||||
}
|
||||
|
||||
.ui-item-slot.is-emphasized::before,
|
||||
@@ -76,22 +76,22 @@ const frames: Record<Rarity, string> = {
|
||||
.ui-item-slot.is-emphasized::before {
|
||||
z-index: 0;
|
||||
inset: 4px;
|
||||
border: 1px solid #ffa800;
|
||||
border: 1px solid var(--ui-item-slot-emphasis);
|
||||
box-shadow:
|
||||
0 0 2px 1px rgb(255 168 0 / 88%),
|
||||
0 0 5px 4px rgb(255 168 0 / 46%),
|
||||
inset 0 0 2px rgb(255 168 0 / 70%);
|
||||
0 0 2px 1px var(--ui-item-slot-emphasis-shadow-strong),
|
||||
0 0 5px 4px var(--ui-item-slot-emphasis-shadow),
|
||||
inset 0 0 2px var(--ui-item-slot-emphasis-inset);
|
||||
}
|
||||
.ui-item-slot.is-emphasized::after {
|
||||
z-index: 3;
|
||||
inset: 5px;
|
||||
border: 1px solid #fffc2a;
|
||||
inset: var(--ui-item-frame-inset);
|
||||
border: 1px solid var(--ui-item-slot-emphasis-strong);
|
||||
}
|
||||
.ui-item-slot.is-locked::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
z-index: 4;
|
||||
inset: 0;
|
||||
background: rgb(0 0 0 / 68%);
|
||||
background: var(--ui-item-slot-lock-overlay);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
<script setup lang="ts">
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
export interface UiNavigationItem {
|
||||
value: string
|
||||
label: string
|
||||
icon?: string
|
||||
indicator?: string
|
||||
disabled?: boolean
|
||||
}
|
||||
|
||||
const props = defineProps<{
|
||||
class?: HTMLAttributes['class']
|
||||
items: UiNavigationItem[]
|
||||
label?: string
|
||||
}>()
|
||||
|
||||
const model = defineModel<string>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<nav :class="cn('ui-navigation', props.class)" :aria-label="label">
|
||||
<button
|
||||
v-for="item in items"
|
||||
:key="item.value"
|
||||
type="button"
|
||||
class="ui-navigation__item"
|
||||
:class="{ 'is-selected': model === item.value }"
|
||||
:disabled="item.disabled"
|
||||
:aria-current="model === item.value ? 'page' : undefined"
|
||||
@click="model = item.value"
|
||||
>
|
||||
<img v-if="item.icon" :src="item.icon" alt="" aria-hidden="true" />
|
||||
<span>{{ item.label }}</span>
|
||||
<img v-if="item.indicator" :src="item.indicator" alt="" aria-hidden="true" />
|
||||
<i v-else aria-hidden="true" />
|
||||
</button>
|
||||
</nav>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.ui-navigation {
|
||||
width: var(--ui-navigation-width, min(100%, var(--ui-navigation-inline-size)));
|
||||
overflow: hidden;
|
||||
border: 1px solid var(--ui-navigation-border);
|
||||
background: var(--ui-item-slot-background);
|
||||
}
|
||||
|
||||
.ui-navigation__item {
|
||||
box-sizing: border-box;
|
||||
display: grid;
|
||||
width: 100%;
|
||||
height: var(--ui-navigation-row-block-size);
|
||||
grid-template-columns:
|
||||
var(--ui-navigation-icon-size) minmax(0, 1fr)
|
||||
var(--ui-navigation-indicator-inline-size);
|
||||
align-items: center;
|
||||
gap: var(--ui-disclosure-row-gap);
|
||||
padding: 0 var(--ui-navigation-padding-inline);
|
||||
border: 0;
|
||||
border-bottom: 1px solid var(--ui-navigation-divider);
|
||||
outline: none;
|
||||
background: transparent;
|
||||
color: var(--ui-navigation-foreground);
|
||||
font: inherit;
|
||||
line-height: var(--ui-control-line-height);
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
&:hover:not(:disabled),
|
||||
&:focus-visible:not(:disabled) {
|
||||
background: var(--ui-disclosure-header-background);
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
outline: 1px solid var(--ui-ring);
|
||||
outline-offset: -2px;
|
||||
}
|
||||
|
||||
&:active:not(:disabled) > * {
|
||||
transform: translateY(1px);
|
||||
}
|
||||
|
||||
&.is-selected {
|
||||
background: var(--ui-navigation-selected-background);
|
||||
color: var(--ui-navigation-selected-foreground);
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
cursor: not-allowed;
|
||||
color: var(--ui-control-disabled-foreground);
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: var(--ui-navigation-icon-size);
|
||||
max-height: var(--ui-navigation-icon-size);
|
||||
object-fit: contain;
|
||||
image-rendering: pixelated;
|
||||
}
|
||||
|
||||
span {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,2 @@
|
||||
export { default as UiNavigation } from './UiNavigation.vue'
|
||||
export type { UiNavigationItem } from './UiNavigation.vue'
|
||||
@@ -65,41 +65,45 @@ function fastChange(direction: 1 | -1) {
|
||||
<style scoped>
|
||||
.ui-number-field-shell {
|
||||
display: inline-flex;
|
||||
width: var(--ui-number-field-width, 100%);
|
||||
min-width: 0;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.ui-number-field {
|
||||
box-sizing: border-box;
|
||||
display: grid;
|
||||
width: 210px;
|
||||
height: 30px;
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
height: var(--ui-control-height-default);
|
||||
grid-template-columns: minmax(0, 1fr) 23px;
|
||||
border: 1px solid var(--ui-input);
|
||||
background: linear-gradient(#0b0c0d, #000100);
|
||||
box-shadow: inset 0 0 0 1px #050505;
|
||||
background: var(--ui-field-background);
|
||||
box-shadow: inset 0 0 0 1px var(--ui-field-inset);
|
||||
}
|
||||
|
||||
.ui-number-field:focus-within {
|
||||
border-color: var(--ui-ring);
|
||||
box-shadow:
|
||||
inset 0 0 0 1px #071722,
|
||||
0 0 0 1px #24617c;
|
||||
inset 0 0 0 1px var(--ui-field-focus-inset),
|
||||
0 0 0 1px var(--ui-field-focus-edge);
|
||||
}
|
||||
|
||||
.ui-number-field__input {
|
||||
min-width: 0;
|
||||
padding: 0 9px;
|
||||
padding: 0 var(--ui-field-padding-inline);
|
||||
border: 0;
|
||||
outline: 0;
|
||||
background: transparent;
|
||||
color: var(--ui-primary-foreground);
|
||||
font: 13px/1 inherit;
|
||||
font: var(--ui-control-font-size-default) / var(--ui-control-line-height) inherit;
|
||||
text-align: inherit;
|
||||
}
|
||||
|
||||
.ui-number-field__spinner {
|
||||
display: grid;
|
||||
grid-template-rows: 1fr 1fr;
|
||||
border-left: 1px solid #4b412d;
|
||||
border-left: 1px solid var(--ui-number-spinner-divider);
|
||||
}
|
||||
|
||||
.ui-number-field__step {
|
||||
@@ -114,29 +118,29 @@ function fastChange(direction: 1 | -1) {
|
||||
}
|
||||
|
||||
.ui-number-field__step + .ui-number-field__step {
|
||||
border-top: 1px solid #2e2d28;
|
||||
border-top: 1px solid var(--ui-number-step-divider);
|
||||
}
|
||||
.ui-number-field__step:hover {
|
||||
background: rgb(255 255 255 / 3.5%);
|
||||
background: var(--ui-number-step-hover);
|
||||
}
|
||||
.ui-number-field__step:active {
|
||||
background: rgb(0 0 0 / 35%);
|
||||
background: var(--ui-number-step-active);
|
||||
}
|
||||
.ui-number-field__step i {
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-right: 7px solid transparent;
|
||||
border-bottom: 8px solid #b99550;
|
||||
border-bottom: 8px solid var(--ui-number-step-arrow);
|
||||
border-left: 7px solid transparent;
|
||||
}
|
||||
.ui-number-field__step:last-child i {
|
||||
border-top: 8px solid #b99550;
|
||||
border-top: 8px solid var(--ui-number-step-arrow);
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
.ui-number-field__fast-step {
|
||||
width: 26px;
|
||||
height: 28px;
|
||||
width: var(--ui-number-fast-inline-size);
|
||||
height: var(--ui-number-fast-block-size);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-left: 3px;
|
||||
@@ -148,18 +152,14 @@ function fastChange(direction: 1 | -1) {
|
||||
--fast-b: 0;
|
||||
appearance: none;
|
||||
position: relative;
|
||||
flex: 0 0 14px;
|
||||
width: 26px;
|
||||
height: 14px;
|
||||
flex: 0 0 var(--ui-number-fast-step-block-size);
|
||||
width: var(--ui-number-fast-inline-size);
|
||||
height: var(--ui-number-fast-step-block-size);
|
||||
padding: 0;
|
||||
border: 0;
|
||||
outline: none;
|
||||
background:
|
||||
linear-gradient(90deg, #3c66b4 0 1px, transparent 1px 23px, #3c66b4 23px) 1px 4px / 24px 9px
|
||||
no-repeat,
|
||||
linear-gradient(180deg, #325596, #1d2f53 46% 72%, #2b4378) 1px 4px / 24px 9px no-repeat,
|
||||
linear-gradient(#000, #000) 0 3px / 26px 11px no-repeat;
|
||||
color: #b69260;
|
||||
background: var(--ui-number-fast-up-background);
|
||||
color: var(--ui-number-fast-text);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@@ -170,31 +170,17 @@ function fastChange(direction: 1 | -1) {
|
||||
left: 9px;
|
||||
width: 7px;
|
||||
height: 3px;
|
||||
background:
|
||||
linear-gradient(#000, #000) center 0 / 3px 1px no-repeat,
|
||||
linear-gradient(90deg, #000 0 1px, #080d17 1px 2px, #2f518f 2px 3px, #080d17 3px 4px, #000 4px)
|
||||
center 1px / 5px 1px no-repeat,
|
||||
linear-gradient(90deg, #000 0 1px, #080d17 1px 2px, #2f518f 2px 5px, #080d17 5px 6px, #000 6px)
|
||||
center 2px / 7px 1px no-repeat;
|
||||
background: var(--ui-number-fast-chevron-up);
|
||||
}
|
||||
|
||||
.ui-number-field__fast-step button + button {
|
||||
background:
|
||||
linear-gradient(90deg, #3e6cbe 0 1px, transparent 1px 23px, #3e6cbe 23px) 1px 1px / 24px 9px
|
||||
no-repeat,
|
||||
linear-gradient(180deg, #345a9e, #1d2f53 46% 72%, #2d4782) 1px 1px / 24px 9px no-repeat,
|
||||
linear-gradient(#000, #000) 0 0 / 26px 11px no-repeat;
|
||||
background: var(--ui-number-fast-down-background);
|
||||
}
|
||||
|
||||
.ui-number-field__fast-step button + button::before {
|
||||
top: auto;
|
||||
bottom: 0;
|
||||
background:
|
||||
linear-gradient(90deg, #000 0 1px, #080d17 1px 2px, #2f518f 2px 5px, #080d17 5px 6px, #000 6px)
|
||||
center 0 / 7px 1px no-repeat,
|
||||
linear-gradient(90deg, #000 0 1px, #080d17 1px 2px, #2f518f 2px 3px, #080d17 3px 4px, #000 4px)
|
||||
center 1px / 5px 1px no-repeat,
|
||||
linear-gradient(#000, #000) center 2px / 3px 1px no-repeat;
|
||||
background: var(--ui-number-fast-chevron-down);
|
||||
}
|
||||
|
||||
.ui-number-field__fast-step button:hover {
|
||||
|
||||
@@ -33,7 +33,7 @@ const props = defineProps<{
|
||||
.ui-panel__heading {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
height: 46px;
|
||||
height: var(--ui-panel-heading-block-size);
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: clamp(8px, 1.2cqi, 16px);
|
||||
@@ -65,7 +65,7 @@ const props = defineProps<{
|
||||
.ui-panel__heading {
|
||||
align-items: flex-start;
|
||||
height: auto;
|
||||
min-height: 46px;
|
||||
min-height: var(--ui-panel-heading-block-size);
|
||||
padding-block: 10px;
|
||||
}
|
||||
.ui-panel__heading span {
|
||||
|
||||
@@ -28,16 +28,16 @@ const percentage = computed(() =>
|
||||
.ui-progress {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 14px;
|
||||
height: var(--ui-progress-block-size);
|
||||
overflow: hidden;
|
||||
border: 1px solid #3c3425;
|
||||
background: #0a0b0a;
|
||||
border: 1px solid var(--ui-progress-border);
|
||||
background: var(--ui-progress-background);
|
||||
}
|
||||
|
||||
.ui-progress__indicator {
|
||||
height: 100%;
|
||||
background: linear-gradient(180deg, #9abe23, #63820a);
|
||||
box-shadow: inset 0 0 0 1px #cce43c;
|
||||
background: var(--ui-progress-fill);
|
||||
box-shadow: inset 0 0 0 1px var(--ui-progress-fill-inset);
|
||||
transition: width 180ms ease-out;
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ const percentage = computed(() =>
|
||||
top: -5px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-top: 5px solid #d7bd61;
|
||||
border-top: 5px solid var(--ui-progress-marker);
|
||||
border-right: 4px solid transparent;
|
||||
border-left: 4px solid transparent;
|
||||
transform: translateX(-50%);
|
||||
|
||||
@@ -27,20 +27,20 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||
<style scoped>
|
||||
.ui-radio-item {
|
||||
box-sizing: border-box;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
width: var(--ui-radio-size);
|
||||
height: var(--ui-radio-size);
|
||||
padding: 0;
|
||||
border: 1px solid #614f36;
|
||||
border: 1px solid var(--ui-radio-border);
|
||||
border-radius: 50%;
|
||||
outline: none;
|
||||
background: linear-gradient(#2e2e2e, #171717);
|
||||
box-shadow: inset 0 1px 0 rgb(255 255 255 / 4%);
|
||||
background: var(--ui-radio-surface);
|
||||
box-shadow: inset 0 1px 0 var(--ui-control-inner-highlight);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.ui-radio-item:hover:not(:disabled) {
|
||||
border-color: #d6c889;
|
||||
background: linear-gradient(#4a4a4a, #252525);
|
||||
border-color: var(--ui-radio-hover-border);
|
||||
background: var(--ui-radio-hover-surface);
|
||||
}
|
||||
|
||||
.ui-radio-item:focus-visible {
|
||||
@@ -55,10 +55,15 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||
|
||||
.ui-radio-item:disabled {
|
||||
cursor: not-allowed;
|
||||
border-color: #3b3b3b;
|
||||
border-color: var(--ui-radio-disabled-border);
|
||||
background:
|
||||
linear-gradient(135deg, transparent 43%, #313131 46% 54%, transparent 57%),
|
||||
linear-gradient(#252525, #121212);
|
||||
linear-gradient(
|
||||
135deg,
|
||||
transparent 43%,
|
||||
var(--ui-radio-disabled-mark) 46% 54%,
|
||||
transparent 57%
|
||||
),
|
||||
var(--ui-radio-disabled-surface);
|
||||
opacity: 0.45;
|
||||
}
|
||||
|
||||
@@ -69,8 +74,8 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||
border: 1px solid transparent;
|
||||
border-radius: inherit;
|
||||
background:
|
||||
linear-gradient(#dbaa3a, #edd067) padding-box,
|
||||
linear-gradient(#f0dfa0, #a17e50) border-box;
|
||||
box-shadow: inset 0 0 0 1px #272727;
|
||||
var(--ui-radio-mark) padding-box,
|
||||
var(--ui-radio-mark-border) border-box;
|
||||
box-shadow: inset 0 0 0 1px var(--ui-radio-mark-inset);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -39,14 +39,14 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||
.ui-rating {
|
||||
display: flex;
|
||||
width: max-content;
|
||||
min-height: 46px;
|
||||
min-height: var(--ui-rating-min-block-size);
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
padding: 8px 12px;
|
||||
border-radius: 22px;
|
||||
outline: none;
|
||||
background: #1a1917;
|
||||
box-shadow: inset 0 1px 0 rgb(255 255 255 / 3%);
|
||||
background: var(--ui-rating-background);
|
||||
box-shadow: inset 0 1px 0 var(--ui-rating-highlight);
|
||||
}
|
||||
|
||||
.ui-rating:focus-visible {
|
||||
@@ -54,8 +54,8 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||
}
|
||||
.ui-rating__item {
|
||||
position: relative;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
width: var(--ui-rating-item-size);
|
||||
height: var(--ui-rating-item-size);
|
||||
padding: 0;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
@@ -63,15 +63,15 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||
}
|
||||
.ui-rating__item > img,
|
||||
.ui-rating :deep(.ui-rating__indicator img) {
|
||||
width: 24px;
|
||||
width: var(--ui-rating-item-size);
|
||||
height: auto;
|
||||
image-rendering: pixelated;
|
||||
}
|
||||
.ui-rating :deep(.ui-rating__indicator) {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
width: var(--ui-rating-item-size);
|
||||
height: var(--ui-rating-item-size);
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
border: 0;
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
<script setup lang="ts">
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import {
|
||||
ScrollAreaCorner,
|
||||
ScrollAreaRoot,
|
||||
ScrollAreaScrollbar,
|
||||
ScrollAreaThumb,
|
||||
ScrollAreaViewport,
|
||||
} from 'reka-ui'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
class?: HTMLAttributes['class']
|
||||
type?: 'auto' | 'always' | 'scroll' | 'hover'
|
||||
}>(),
|
||||
{ type: 'auto' },
|
||||
)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ScrollAreaRoot :type="type" :class="cn('ui-scroll-area', props.class)">
|
||||
<ScrollAreaViewport class="ui-scroll-area__viewport">
|
||||
<slot />
|
||||
</ScrollAreaViewport>
|
||||
<ScrollAreaScrollbar class="ui-scroll-area__scrollbar" orientation="vertical">
|
||||
<span class="ui-scroll-area__arrow ui-scroll-area__arrow--up" aria-hidden="true" />
|
||||
<span class="ui-scroll-area__track"><ScrollAreaThumb class="ui-scroll-area__thumb" /></span>
|
||||
<span class="ui-scroll-area__arrow ui-scroll-area__arrow--down" aria-hidden="true" />
|
||||
</ScrollAreaScrollbar>
|
||||
<ScrollAreaCorner />
|
||||
</ScrollAreaRoot>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.ui-scroll-area {
|
||||
position: relative;
|
||||
height: var(--ui-scroll-area-height, var(--ui-scroll-area-block-size));
|
||||
overflow: hidden;
|
||||
background: var(--ui-composition-background);
|
||||
}
|
||||
|
||||
.ui-scroll-area__viewport {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.ui-scroll-area__scrollbar {
|
||||
display: grid;
|
||||
width: var(--ui-scrollbar-inline-size);
|
||||
grid-template-rows: var(--ui-scrollbar-arrow-block-size) 1fr var(--ui-scrollbar-arrow-block-size);
|
||||
border: 1px solid var(--ui-scrollbar-border);
|
||||
background: var(--ui-scrollbar-background);
|
||||
user-select: none;
|
||||
touch-action: none;
|
||||
}
|
||||
|
||||
.ui-scroll-area__arrow {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: var(--ui-scrollbar-arrow-background);
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-right: var(--ui-scrollbar-arrow-inline-size) solid transparent;
|
||||
border-bottom: var(--ui-scrollbar-arrow-glyph-block-size) solid var(--ui-scrollbar-arrow);
|
||||
border-left: var(--ui-scrollbar-arrow-inline-size) solid transparent;
|
||||
filter: drop-shadow(0 1px 0 var(--ui-tooltip-shadow));
|
||||
}
|
||||
|
||||
&--down::before {
|
||||
border-top: var(--ui-scrollbar-arrow-glyph-block-size) solid var(--ui-scrollbar-arrow);
|
||||
border-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.ui-scroll-area__track {
|
||||
position: relative;
|
||||
background: var(--ui-scrollbar-track);
|
||||
}
|
||||
|
||||
.ui-scroll-area__thumb {
|
||||
position: relative;
|
||||
width: calc(100% - var(--ui-scrollbar-thumb-gutter) * 2);
|
||||
margin-inline: var(--ui-scrollbar-thumb-gutter);
|
||||
border: 1px solid var(--ui-scrollbar-thumb-border);
|
||||
background: var(--ui-scrollbar-thumb);
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: -8px 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1 @@
|
||||
export { default as UiScrollArea } from './UiScrollArea.vue'
|
||||
@@ -46,10 +46,10 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||
z-index: 80;
|
||||
max-height: min(18rem, var(--reka-select-content-available-height));
|
||||
overflow: hidden;
|
||||
border: 1px solid #5a4828;
|
||||
border: 1px solid var(--ui-popup-border);
|
||||
border-radius: 0;
|
||||
background: #050606;
|
||||
box-shadow: 0 8px 18px #000;
|
||||
background: var(--ui-popup-background);
|
||||
box-shadow: 0 8px 18px var(--ui-popup-shadow);
|
||||
color: var(--ui-popover-foreground);
|
||||
transform-origin: var(--reka-select-content-transform-origin);
|
||||
}
|
||||
|
||||
@@ -30,12 +30,14 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||
.ui-select-item {
|
||||
position: relative;
|
||||
display: flex;
|
||||
height: 27px;
|
||||
height: var(--ui-option-height);
|
||||
align-items: center;
|
||||
padding: 0 10px;
|
||||
border-bottom: 1px solid #25231f;
|
||||
border-bottom: 1px solid var(--ui-option-divider);
|
||||
outline: none;
|
||||
color: var(--ui-primary-foreground);
|
||||
font-size: var(--ui-control-font-size-default);
|
||||
line-height: var(--ui-control-line-height);
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
@@ -43,8 +45,8 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||
.ui-select-item[data-highlighted] {
|
||||
outline: 1px solid var(--ui-ring);
|
||||
outline-offset: -2px;
|
||||
background: #091731;
|
||||
color: #f3d777;
|
||||
background: var(--ui-option-highlight-background);
|
||||
color: var(--ui-option-highlight-foreground);
|
||||
}
|
||||
|
||||
.ui-select-item[data-state='checked'] {
|
||||
@@ -57,8 +59,8 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||
}
|
||||
|
||||
.ui-select-item:active {
|
||||
background: #07121b;
|
||||
color: #fff0a4;
|
||||
background: var(--ui-option-active-background);
|
||||
color: var(--ui-option-active-foreground);
|
||||
}
|
||||
.ui-select-item__indicator {
|
||||
display: none;
|
||||
|
||||
@@ -25,18 +25,20 @@ const delegatedProps = computed(() => {
|
||||
box-sizing: border-box;
|
||||
display: inline-flex;
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
height: var(--ui-control-height-default);
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 8px;
|
||||
padding: 0 4px 0 9px;
|
||||
padding: 0 4px 0 var(--ui-field-padding-inline);
|
||||
border: 1px solid var(--ui-input);
|
||||
border-radius: 0;
|
||||
outline: none;
|
||||
background: linear-gradient(#0b0c0d, #000100);
|
||||
box-shadow: inset 0 0 0 1px #050505;
|
||||
background: var(--ui-field-background);
|
||||
box-shadow: inset 0 0 0 1px var(--ui-field-inset);
|
||||
color: var(--ui-primary-foreground);
|
||||
font: inherit;
|
||||
font-size: var(--ui-control-font-size-default);
|
||||
line-height: var(--ui-control-line-height);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@@ -44,8 +46,8 @@ const delegatedProps = computed(() => {
|
||||
.ui-select-trigger[data-state='open'] {
|
||||
border-color: var(--ui-ring);
|
||||
box-shadow:
|
||||
inset 0 0 0 1px #071722,
|
||||
0 0 0 1px #24617c;
|
||||
inset 0 0 0 1px var(--ui-field-focus-inset),
|
||||
0 0 0 1px var(--ui-field-focus-edge);
|
||||
}
|
||||
|
||||
.ui-select-trigger:disabled {
|
||||
@@ -55,25 +57,25 @@ const delegatedProps = computed(() => {
|
||||
|
||||
.ui-select-trigger__icon {
|
||||
display: inline-flex;
|
||||
width: 21px;
|
||||
height: 18px;
|
||||
width: var(--ui-select-icon-inline-size);
|
||||
height: var(--ui-select-icon-block-size);
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 1px solid var(--ui-control-border);
|
||||
background: var(--ui-control-background);
|
||||
box-shadow: 0 0 0 1px rgb(0 0 0 / 60%);
|
||||
box-shadow: 0 0 0 1px var(--ui-select-icon-shadow);
|
||||
}
|
||||
|
||||
.ui-select-trigger__icon img {
|
||||
width: 11px;
|
||||
height: 6px;
|
||||
width: var(--ui-select-glyph-inline-size);
|
||||
height: var(--ui-select-glyph-block-size);
|
||||
image-rendering: pixelated;
|
||||
}
|
||||
|
||||
.ui-select-trigger:hover .ui-select-trigger__icon,
|
||||
.ui-select-trigger:focus-visible .ui-select-trigger__icon {
|
||||
border-color: #725f4e;
|
||||
background: linear-gradient(180deg, #29457f, #24386a);
|
||||
border-color: var(--ui-control-border-active);
|
||||
background: var(--ui-control-background-hover);
|
||||
}
|
||||
|
||||
.ui-select-trigger:active .ui-select-trigger__icon,
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
<script setup lang="ts">
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
class?: HTMLAttributes['class']
|
||||
label: string
|
||||
alt?: boolean
|
||||
focused?: boolean
|
||||
disabled?: boolean
|
||||
indent?: 0 | 1 | 2
|
||||
}>(),
|
||||
{ indent: 0 },
|
||||
)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
:class="
|
||||
cn(
|
||||
'ui-setting-row',
|
||||
alt && 'is-alt',
|
||||
focused && 'is-focused',
|
||||
disabled && 'is-disabled',
|
||||
props.class,
|
||||
)
|
||||
"
|
||||
>
|
||||
<div class="ui-setting-row__label" :style="{ '--ui-setting-indent': props.indent }">
|
||||
<slot name="label">{{ label }}</slot>
|
||||
</div>
|
||||
<div class="ui-setting-row__control"><slot /></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.ui-setting-row {
|
||||
box-sizing: border-box;
|
||||
display: grid;
|
||||
min-height: var(--ui-settings-row-min-block-size);
|
||||
grid-template-columns:
|
||||
minmax(var(--ui-settings-label-min-inline-size), 1fr)
|
||||
minmax(var(--ui-settings-control-min-inline-size), 1.1fr);
|
||||
align-items: center;
|
||||
padding: var(--ui-settings-row-padding-block) var(--ui-settings-row-padding-inline);
|
||||
border-bottom: 1px solid var(--ui-settings-row-divider);
|
||||
color: var(--ui-settings-row-foreground);
|
||||
line-height: var(--ui-control-line-height);
|
||||
|
||||
&.is-alt {
|
||||
background: var(--ui-settings-row-alt);
|
||||
}
|
||||
|
||||
&.is-focused,
|
||||
&:focus-within {
|
||||
outline: 1px solid var(--ui-ring);
|
||||
outline-offset: -2px;
|
||||
background: var(--ui-settings-row-focus);
|
||||
}
|
||||
|
||||
&.is-disabled {
|
||||
color: var(--ui-control-disabled-foreground);
|
||||
}
|
||||
}
|
||||
|
||||
.ui-setting-row__label {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
align-items: center;
|
||||
gap: var(--ui-disclosure-row-gap);
|
||||
padding-left: calc(var(--ui-setting-indent) * var(--ui-settings-indent-step));
|
||||
}
|
||||
|
||||
.ui-setting-row__control {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
@container (max-width: 520px) {
|
||||
.ui-setting-row {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.ui-setting-row__control {
|
||||
justify-content: stretch;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,17 @@
|
||||
<script setup lang="ts">
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const props = defineProps<{ class?: HTMLAttributes['class'] }>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section :class="cn('ui-settings-group', props.class)"><slot /></section>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.ui-settings-group {
|
||||
border: 1px solid var(--ui-settings-border);
|
||||
background: var(--ui-settings-background);
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,27 @@
|
||||
<script setup lang="ts">
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const props = defineProps<{ class?: HTMLAttributes['class'] }>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h3 :class="cn('ui-settings-section', props.class)"><slot /></h3>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.ui-settings-section {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
height: var(--ui-settings-section-block-size);
|
||||
align-items: center;
|
||||
margin: 0;
|
||||
padding: 0 10px;
|
||||
border: 1px solid var(--ui-settings-section-border);
|
||||
background: var(--ui-settings-section-background);
|
||||
color: var(--ui-settings-section-foreground);
|
||||
font-size: var(--ui-control-font-size-default);
|
||||
font-weight: 400;
|
||||
line-height: var(--ui-control-line-height);
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,3 @@
|
||||
export { default as UiSettingRow } from './UiSettingRow.vue'
|
||||
export { default as UiSettingsGroup } from './UiSettingsGroup.vue'
|
||||
export { default as UiSettingsSection } from './UiSettingsSection.vue'
|
||||
@@ -0,0 +1,310 @@
|
||||
<script setup lang="ts">
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import inspectIcon from '../../../../../design/src-web/shop-item-row/img/sprite_interface.NPK/windowcommon.chn.img/652.PNG'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
export interface UiShopItem {
|
||||
id: string
|
||||
image: string
|
||||
reinforce: string
|
||||
amplify: string
|
||||
name: string
|
||||
status: string
|
||||
owner: string
|
||||
rarity?: 'normal' | 'rare' | 'artifact' | 'legend' | 'epic'
|
||||
statusTone?: 'default' | 'info' | 'success' | 'danger'
|
||||
disabled?: boolean
|
||||
}
|
||||
|
||||
const props = defineProps<{
|
||||
class?: HTMLAttributes['class']
|
||||
rows: UiShopItem[]
|
||||
inspectLabel?: string
|
||||
}>()
|
||||
|
||||
const selected = defineModel<string>('selected')
|
||||
const emits = defineEmits<{ inspect: [row: UiShopItem] }>()
|
||||
|
||||
function selectRow(row: UiShopItem) {
|
||||
if (!row.disabled) selected.value = row.id
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div :class="cn('ui-shop-list', props.class)" role="listbox" aria-label="物品列表">
|
||||
<div class="ui-shop-list__surface">
|
||||
<div
|
||||
v-for="(row, index) in rows"
|
||||
:key="row.id"
|
||||
class="ui-shop-row"
|
||||
:class="{
|
||||
'is-alt': index % 2 === 1,
|
||||
'is-selected': selected === row.id,
|
||||
'is-disabled': row.disabled,
|
||||
}"
|
||||
role="option"
|
||||
:aria-selected="selected === row.id"
|
||||
:aria-disabled="row.disabled || undefined"
|
||||
:tabindex="row.disabled ? -1 : 0"
|
||||
@click="selectRow(row)"
|
||||
@keydown.enter.prevent="selectRow(row)"
|
||||
@keydown.space.prevent="selectRow(row)"
|
||||
>
|
||||
<i class="ui-shop-row__frame" aria-hidden="true" />
|
||||
<div class="ui-shop-row__icon"><img :src="row.image" alt="" /></div>
|
||||
<div>{{ row.reinforce }}</div>
|
||||
<div>{{ row.amplify }}</div>
|
||||
<div :class="row.rarity && `quality-${row.rarity}`">{{ row.name }}</div>
|
||||
<div>
|
||||
<button
|
||||
type="button"
|
||||
class="ui-shop-row__inspect"
|
||||
:aria-label="inspectLabel ?? `查看${row.name}`"
|
||||
@click.stop="emits('inspect', row)"
|
||||
>
|
||||
<img :src="inspectIcon" alt="" />
|
||||
</button>
|
||||
</div>
|
||||
<div :class="row.statusTone && `status-${row.statusTone}`">{{ row.status }}</div>
|
||||
<div class="ui-shop-row__owner">{{ row.owner }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.ui-shop-list {
|
||||
width: 100%;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
.ui-shop-list__surface {
|
||||
display: flex;
|
||||
min-width: var(--ui-shop-row-scroll-inline-size);
|
||||
flex-direction: column;
|
||||
gap: var(--ui-shop-row-gap);
|
||||
}
|
||||
|
||||
.ui-shop-row {
|
||||
--shop-frame-inset: 5px;
|
||||
--shop-frame-corner: 7px;
|
||||
--shop-surface-inset: 8px;
|
||||
--shop-surface-corner: 5px;
|
||||
--shop-outer: var(--ui-shop-frame-rest-outer);
|
||||
--shop-middle: var(--ui-shop-frame-rest-middle);
|
||||
--shop-accent: var(--ui-shop-frame-rest-accent);
|
||||
--shop-inner: transparent;
|
||||
--shop-surface: var(--ui-shop-frame-rest-surface);
|
||||
--shop-shadow: transparent;
|
||||
--shop-frame-filter: drop-shadow(0 0 4px var(--ui-shop-frame-shadow));
|
||||
--shop-surface-filter: none;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
isolation: isolate;
|
||||
display: grid;
|
||||
min-height: var(--ui-shop-row-min-block-size);
|
||||
grid-template-columns: var(--ui-shop-row-grid);
|
||||
align-items: center;
|
||||
padding-inline: var(--ui-shop-row-padding-inline);
|
||||
outline: none;
|
||||
color: var(--ui-shop-foreground);
|
||||
font-size: var(--ui-shop-font-size);
|
||||
line-height: 1.25;
|
||||
cursor: pointer;
|
||||
|
||||
&.is-alt {
|
||||
--shop-outer: var(--ui-shop-frame-alt-outer);
|
||||
--shop-middle: var(--ui-shop-frame-alt-middle);
|
||||
--shop-surface: var(--ui-shop-frame-alt-surface);
|
||||
}
|
||||
|
||||
&:hover:not(.is-disabled),
|
||||
&:focus-visible:not(.is-disabled) {
|
||||
--shop-frame-inset: 3px;
|
||||
--shop-frame-corner: 9px;
|
||||
--shop-surface-inset: 7px;
|
||||
--shop-outer: var(--ui-shop-frame-hover-outer);
|
||||
--shop-middle: var(--ui-shop-frame-hover-middle);
|
||||
--shop-accent: var(--ui-shop-frame-hover-accent);
|
||||
--shop-inner: var(--ui-shop-frame-hover-inner);
|
||||
--shop-surface: var(--ui-shop-frame-hover-surface);
|
||||
--shop-shadow: var(--ui-tooltip-shadow);
|
||||
--shop-frame-filter: none;
|
||||
--shop-surface-filter: drop-shadow(1px 0 0 var(--shop-inner))
|
||||
drop-shadow(-1px 0 0 var(--shop-inner)) drop-shadow(0 1px 0 var(--shop-inner))
|
||||
drop-shadow(0 -1px 0 var(--shop-inner));
|
||||
}
|
||||
|
||||
&.is-selected {
|
||||
--shop-frame-inset: 3px;
|
||||
--shop-frame-corner: 9px;
|
||||
--shop-surface-inset: 7px;
|
||||
--shop-outer: var(--ui-shop-frame-selected-outer);
|
||||
--shop-middle: var(--ui-shop-frame-selected-middle);
|
||||
--shop-accent: var(--ui-shop-frame-selected-accent);
|
||||
--shop-inner: var(--ui-shop-frame-selected-inner);
|
||||
--shop-surface: var(--ui-shop-frame-selected-surface);
|
||||
--shop-shadow: var(--ui-tooltip-shadow);
|
||||
--shop-frame-filter: none;
|
||||
--shop-surface-filter: drop-shadow(1px 0 0 var(--shop-inner))
|
||||
drop-shadow(-1px 0 0 var(--shop-inner)) drop-shadow(0 1px 0 var(--shop-inner))
|
||||
drop-shadow(0 -1px 0 var(--shop-inner));
|
||||
}
|
||||
|
||||
&.is-disabled {
|
||||
color: var(--ui-control-disabled-foreground);
|
||||
cursor: not-allowed;
|
||||
opacity: 0.58;
|
||||
}
|
||||
|
||||
> *:not(.ui-shop-row__frame) {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
height: 100%;
|
||||
align-items: center;
|
||||
padding: 0 var(--ui-shop-cell-padding-inline);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
&::before,
|
||||
&::after,
|
||||
.ui-shop-row__frame,
|
||||
.ui-shop-row__frame::before,
|
||||
.ui-shop-row__frame::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
&::before {
|
||||
z-index: -3;
|
||||
inset: 0;
|
||||
background: var(--shop-shadow);
|
||||
}
|
||||
|
||||
&::after {
|
||||
z-index: -1;
|
||||
inset: var(--shop-surface-inset);
|
||||
background: var(--shop-surface);
|
||||
clip-path: polygon(
|
||||
var(--shop-surface-corner) 0,
|
||||
calc(100% - var(--shop-surface-corner)) 0,
|
||||
100% var(--shop-surface-corner),
|
||||
100% calc(100% - var(--shop-surface-corner)),
|
||||
calc(100% - var(--shop-surface-corner)) 100%,
|
||||
var(--shop-surface-corner) 100%,
|
||||
0 calc(100% - var(--shop-surface-corner)),
|
||||
0 var(--shop-surface-corner)
|
||||
);
|
||||
filter: var(--shop-surface-filter);
|
||||
}
|
||||
}
|
||||
|
||||
.ui-shop-row__frame {
|
||||
z-index: -2;
|
||||
inset: var(--shop-frame-inset);
|
||||
background: var(--shop-outer);
|
||||
clip-path: polygon(
|
||||
var(--shop-frame-corner) 0,
|
||||
calc(100% - var(--shop-frame-corner)) 0,
|
||||
100% var(--shop-frame-corner),
|
||||
100% calc(100% - var(--shop-frame-corner)),
|
||||
calc(100% - var(--shop-frame-corner)) 100%,
|
||||
var(--shop-frame-corner) 100%,
|
||||
0 calc(100% - var(--shop-frame-corner)),
|
||||
0 var(--shop-frame-corner)
|
||||
);
|
||||
filter: var(--shop-frame-filter);
|
||||
|
||||
&::before {
|
||||
inset: 1px;
|
||||
background: var(--shop-middle);
|
||||
}
|
||||
|
||||
&::after {
|
||||
inset: 2px;
|
||||
background: var(--shop-accent);
|
||||
}
|
||||
|
||||
&::before,
|
||||
&::after {
|
||||
clip-path: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
.ui-shop-row__icon {
|
||||
width: var(--ui-shop-icon-inline-size);
|
||||
height: var(--ui-shop-icon-block-size);
|
||||
justify-content: center;
|
||||
padding: 0 !important;
|
||||
|
||||
img {
|
||||
max-width: var(--ui-item-image-size);
|
||||
max-height: var(--ui-item-image-size);
|
||||
image-rendering: pixelated;
|
||||
}
|
||||
}
|
||||
|
||||
.ui-shop-row__inspect {
|
||||
appearance: none;
|
||||
display: inline-flex;
|
||||
width: var(--ui-shop-action-inline-size);
|
||||
height: var(--ui-shop-action-block-size);
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0;
|
||||
border: 2px solid var(--ui-input);
|
||||
border-radius: 0;
|
||||
background: var(--ui-shop-action-background);
|
||||
box-shadow:
|
||||
0 0 0 1px var(--ui-check-outer-shadow),
|
||||
inset 0 0 0 1px var(--ui-shop-action-inset);
|
||||
cursor: pointer;
|
||||
|
||||
&:hover,
|
||||
&:focus-visible {
|
||||
border-color: var(--ui-control-border-active);
|
||||
outline: none;
|
||||
background: var(--ui-shop-action-hover-background);
|
||||
}
|
||||
|
||||
&:active {
|
||||
transform: translateY(1px);
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: var(--ui-shop-action-icon-size);
|
||||
max-height: var(--ui-shop-action-icon-size);
|
||||
image-rendering: pixelated;
|
||||
}
|
||||
}
|
||||
|
||||
.ui-shop-row__owner {
|
||||
white-space: pre-line !important;
|
||||
}
|
||||
|
||||
.quality-rare {
|
||||
color: var(--dcalc-quality-rare);
|
||||
}
|
||||
.quality-artifact {
|
||||
color: var(--dcalc-quality-artifact);
|
||||
}
|
||||
.quality-legend {
|
||||
color: var(--dcalc-quality-legend);
|
||||
}
|
||||
.quality-epic {
|
||||
color: var(--dcalc-quality-epic);
|
||||
}
|
||||
.status-info {
|
||||
color: var(--ui-info);
|
||||
}
|
||||
.status-success {
|
||||
color: var(--ui-success);
|
||||
}
|
||||
.status-danger {
|
||||
color: var(--ui-destructive);
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,2 @@
|
||||
export { default as UiShopItemList } from './UiShopItemList.vue'
|
||||
export type { UiShopItem } from './UiShopItemList.vue'
|
||||
@@ -53,8 +53,8 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||
position: relative;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
min-width: 160px;
|
||||
height: 34px;
|
||||
min-width: var(--ui-slider-min-inline-size);
|
||||
height: var(--ui-slider-block-size);
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
@@ -64,7 +64,7 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
flex: 1;
|
||||
height: 17px;
|
||||
height: var(--ui-slider-control-size);
|
||||
align-items: center;
|
||||
touch-action: none;
|
||||
user-select: none;
|
||||
@@ -82,28 +82,28 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||
.ui-slider__track {
|
||||
position: relative;
|
||||
flex: 1;
|
||||
height: 3px;
|
||||
height: var(--ui-slider-track-size);
|
||||
overflow: visible;
|
||||
background: #515351;
|
||||
box-shadow: 0 1px 0 #020202;
|
||||
background: var(--ui-slider-track);
|
||||
box-shadow: 0 1px 0 var(--ui-slider-track-shadow);
|
||||
}
|
||||
|
||||
.ui-slider__range {
|
||||
position: absolute;
|
||||
inset-block: 0;
|
||||
background: #f3d367;
|
||||
box-shadow: 0 0 3px rgb(243 211 103 / 25%);
|
||||
background: var(--ui-slider-range);
|
||||
box-shadow: 0 0 3px var(--ui-slider-range-shadow);
|
||||
}
|
||||
|
||||
.ui-slider__thumb {
|
||||
--thumb-edge-top: #86693f;
|
||||
--thumb-edge-bottom: #76593a;
|
||||
--thumb-top: #21365e;
|
||||
--thumb-bottom: #1b2b4d;
|
||||
--thumb-edge-top: var(--ui-slider-thumb-edge-top);
|
||||
--thumb-edge-bottom: var(--ui-slider-thumb-edge-bottom);
|
||||
--thumb-top: var(--ui-slider-thumb-top);
|
||||
--thumb-bottom: var(--ui-slider-thumb-bottom);
|
||||
box-sizing: border-box;
|
||||
display: block;
|
||||
width: 17px;
|
||||
height: 17px;
|
||||
width: var(--ui-slider-control-size);
|
||||
height: var(--ui-slider-control-size);
|
||||
border: 1px solid transparent;
|
||||
border-radius: 50%;
|
||||
outline: none;
|
||||
@@ -111,37 +111,37 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||
radial-gradient(circle at 50% 28%, var(--thumb-top), var(--thumb-bottom) 78%) padding-box,
|
||||
linear-gradient(180deg, var(--thumb-edge-top), var(--thumb-edge-bottom)) border-box;
|
||||
box-shadow:
|
||||
0 0 0 1px rgb(0 0 0 / 40%),
|
||||
inset 0 1px 0 rgb(255 255 255 / 2.5%);
|
||||
0 0 0 1px var(--ui-control-outer-shadow),
|
||||
inset 0 1px 0 var(--ui-control-inner-highlight);
|
||||
}
|
||||
|
||||
.ui-slider__control:hover .ui-slider__thumb,
|
||||
.ui-slider__control:active .ui-slider__thumb,
|
||||
.ui-slider__thumb:hover,
|
||||
.ui-slider__thumb:focus-visible {
|
||||
--thumb-edge-top: #907960;
|
||||
--thumb-edge-bottom: #80695b;
|
||||
--thumb-top: #2b467f;
|
||||
--thumb-bottom: #253b6e;
|
||||
box-shadow: 0 0 0 1px rgb(0 0 0 / 40%);
|
||||
--thumb-edge-top: var(--ui-slider-thumb-hover-edge-top);
|
||||
--thumb-edge-bottom: var(--ui-slider-thumb-hover-edge-bottom);
|
||||
--thumb-top: var(--ui-slider-thumb-hover-top);
|
||||
--thumb-bottom: var(--ui-slider-thumb-hover-bottom);
|
||||
box-shadow: 0 0 0 1px var(--ui-control-outer-shadow);
|
||||
}
|
||||
|
||||
.ui-slider__control[data-disabled] .ui-slider__range {
|
||||
background: #686868;
|
||||
background: var(--ui-slider-disabled-range);
|
||||
box-shadow: none;
|
||||
}
|
||||
.ui-slider__control[data-disabled] .ui-slider__thumb {
|
||||
--thumb-edge-top: #454545;
|
||||
--thumb-edge-bottom: #3e3e3e;
|
||||
--thumb-top: #2c2c2c;
|
||||
--thumb-bottom: #242424;
|
||||
--thumb-edge-top: var(--ui-slider-disabled-thumb-edge-top);
|
||||
--thumb-edge-bottom: var(--ui-slider-disabled-thumb-edge-bottom);
|
||||
--thumb-top: var(--ui-slider-disabled-thumb-top);
|
||||
--thumb-bottom: var(--ui-slider-disabled-thumb-bottom);
|
||||
}
|
||||
.ui-slider:has(.ui-slider__control[data-disabled]) .ui-slider__value {
|
||||
color: var(--ui-control-disabled-foreground);
|
||||
}
|
||||
|
||||
.ui-slider__value {
|
||||
min-width: 40px;
|
||||
min-width: var(--ui-slider-value-min-inline-size);
|
||||
color: var(--ui-primary-foreground);
|
||||
font-size: 12px;
|
||||
text-align: right;
|
||||
|
||||
@@ -29,16 +29,16 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||
.ui-switch {
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
width: 28px;
|
||||
height: 16px;
|
||||
width: var(--ui-switch-inline-size);
|
||||
height: var(--ui-switch-block-size);
|
||||
padding: 0;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 8px / 50%;
|
||||
outline: none;
|
||||
background:
|
||||
linear-gradient(#141414, #0f0f0f) padding-box,
|
||||
linear-gradient(#846a48, #453520) border-box;
|
||||
box-shadow: inset 0 1px 3px #090909;
|
||||
var(--ui-switch-surface) padding-box,
|
||||
var(--ui-switch-border) border-box;
|
||||
box-shadow: inset 0 1px 3px var(--ui-switch-inset);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@@ -54,14 +54,14 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||
transform: translate(1px, 1px);
|
||||
}
|
||||
.ui-switch[data-state='checked']:active:not(:disabled) .ui-switch__thumb {
|
||||
transform: translate(13px, 1px);
|
||||
transform: translate(var(--ui-switch-thumb-travel), 1px);
|
||||
}
|
||||
|
||||
.ui-switch[data-state='checked'] {
|
||||
background:
|
||||
linear-gradient(#eccb65, #eccb65) padding-box,
|
||||
linear-gradient(#846a48, #453520) border-box;
|
||||
box-shadow: inset 0 0 0 1px #0d0d0d;
|
||||
var(--ui-switch-checked-surface) padding-box,
|
||||
var(--ui-switch-border) border-box;
|
||||
box-shadow: inset 0 0 0 1px var(--ui-switch-checked-inset);
|
||||
}
|
||||
|
||||
.ui-switch:disabled {
|
||||
@@ -77,16 +77,16 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||
|
||||
.ui-switch__thumb {
|
||||
display: block;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
width: var(--ui-switch-thumb-size);
|
||||
height: var(--ui-switch-thumb-size);
|
||||
border-radius: 50%;
|
||||
background: var(--ui-control-background);
|
||||
box-shadow: inset 0 1px 0 rgb(255 255 255 / 4%);
|
||||
box-shadow: inset 0 1px 0 var(--ui-control-inner-highlight);
|
||||
transition: transform 90ms ease-out;
|
||||
transform: translateX(1px);
|
||||
}
|
||||
|
||||
.ui-switch__thumb[data-state='checked'] {
|
||||
transform: translateX(13px);
|
||||
transform: translateX(var(--ui-switch-thumb-travel));
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -22,7 +22,7 @@ const delegatedProps = computed(() => {
|
||||
border: 1px solid var(--ui-border);
|
||||
border-top: 0;
|
||||
outline: none;
|
||||
background: rgb(0 0 0 / 22%);
|
||||
background: var(--ui-tabs-content-background);
|
||||
color: var(--ui-foreground);
|
||||
}
|
||||
|
||||
|
||||
@@ -85,10 +85,10 @@ onBeforeUnmount(() => {
|
||||
position: relative;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
align-items: flex-start;
|
||||
height: var(--ui-tabs-height);
|
||||
align-items: center;
|
||||
padding: 5px 7px;
|
||||
background: #090709;
|
||||
background: var(--ui-tab-list-background);
|
||||
}
|
||||
|
||||
.ui-tabs-list::after {
|
||||
@@ -98,15 +98,15 @@ onBeforeUnmount(() => {
|
||||
top: 35px;
|
||||
left: 7px;
|
||||
height: 1px;
|
||||
background: #584840;
|
||||
background: var(--ui-tab-divider);
|
||||
}
|
||||
|
||||
.ui-tabs-list__marker {
|
||||
position: absolute;
|
||||
z-index: 4;
|
||||
bottom: 0;
|
||||
width: 39px;
|
||||
height: 5px;
|
||||
width: var(--ui-tab-marker-inline-size);
|
||||
height: var(--ui-tab-marker-block-size);
|
||||
opacity: 0;
|
||||
transform: translateX(-50%);
|
||||
pointer-events: none;
|
||||
@@ -117,7 +117,7 @@ onBeforeUnmount(() => {
|
||||
position: absolute;
|
||||
inset: 0 0 auto;
|
||||
height: 1px;
|
||||
background: linear-gradient(90deg, transparent, #d0a56a 50%, transparent);
|
||||
background: linear-gradient(90deg, transparent, var(--ui-tab-marker) 50%, transparent);
|
||||
}
|
||||
|
||||
.ui-tabs-list__marker::after {
|
||||
@@ -125,9 +125,14 @@ onBeforeUnmount(() => {
|
||||
position: absolute;
|
||||
top: 1px;
|
||||
left: 50%;
|
||||
width: 9px;
|
||||
height: 4px;
|
||||
background: linear-gradient(180deg, #9d7a35, #a7823f 46%, #d0a56a);
|
||||
width: var(--ui-tab-marker-arrow-inline-size);
|
||||
height: var(--ui-tab-marker-arrow-block-size);
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
var(--ui-tab-marker-start),
|
||||
var(--ui-tab-marker-middle) 46%,
|
||||
var(--ui-tab-marker)
|
||||
);
|
||||
clip-path: polygon(0 0, 100% 0, 50% 100%);
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
@@ -18,38 +18,26 @@ const delegatedProps = computed(() => {
|
||||
|
||||
<style scoped>
|
||||
.ui-tabs-trigger {
|
||||
--tab-hover-glow: linear-gradient(
|
||||
90deg,
|
||||
transparent,
|
||||
rgb(48 24 8 / 18%) 10%,
|
||||
rgb(48 24 8 / 72%) 28%,
|
||||
#301808 50%,
|
||||
rgb(48 24 8 / 72%) 72%,
|
||||
rgb(48 24 8 / 18%) 90%,
|
||||
transparent
|
||||
);
|
||||
--tab-selected-glow: radial-gradient(
|
||||
ellipse 58% 46% at 50% 100%,
|
||||
rgb(114 97 30 / 94%),
|
||||
rgb(88 74 23 / 74%) 34%,
|
||||
rgb(52 44 14 / 38%) 66%,
|
||||
transparent
|
||||
);
|
||||
--tab-hover-glow: var(--ui-tab-hover-glow);
|
||||
--tab-selected-glow: var(--ui-tab-selected-glow);
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
height: 30px;
|
||||
display: inline-flex;
|
||||
height: var(--ui-tab-height);
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-width: 0;
|
||||
flex: 1 1 0;
|
||||
padding: 0 12px;
|
||||
border: 0;
|
||||
outline: none;
|
||||
background: #080808;
|
||||
color: #9c815a;
|
||||
background: var(--ui-tab-background);
|
||||
color: var(--ui-tab-foreground);
|
||||
font:
|
||||
16px/1 'DCalc',
|
||||
16px / var(--ui-control-line-height) 'DCalc',
|
||||
SimSun,
|
||||
sans-serif;
|
||||
text-shadow: 1px 1px 0 #000;
|
||||
text-shadow: 1px 1px 0 var(--ui-dialog-titlebar-text-shadow);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@@ -60,17 +48,17 @@ const delegatedProps = computed(() => {
|
||||
right: 0;
|
||||
width: 1px;
|
||||
height: 19px;
|
||||
background: linear-gradient(180deg, transparent, #342f2a 22% 78%, transparent);
|
||||
background: linear-gradient(180deg, transparent, var(--ui-tab-separator) 22% 78%, transparent);
|
||||
}
|
||||
|
||||
.ui-tabs-trigger:hover,
|
||||
.ui-tabs-trigger:focus-visible {
|
||||
color: #e4ca90;
|
||||
color: var(--ui-tab-active-foreground);
|
||||
background-image: var(--tab-hover-glow);
|
||||
}
|
||||
|
||||
.ui-tabs-trigger[data-state='active'] {
|
||||
color: #e4ca90;
|
||||
color: var(--ui-tab-active-foreground);
|
||||
background-image: var(--tab-selected-glow), var(--tab-hover-glow);
|
||||
}
|
||||
|
||||
@@ -84,5 +72,7 @@ const delegatedProps = computed(() => {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
display: inline-block;
|
||||
line-height: var(--ui-control-line-height);
|
||||
transform: translateY(var(--ui-control-text-offset-y));
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -37,13 +37,13 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||
.ui-tooltip-content {
|
||||
position: relative;
|
||||
z-index: 90;
|
||||
max-width: 260px;
|
||||
max-width: var(--ui-tooltip-max-inline-size);
|
||||
padding: 5px 7px;
|
||||
border: 1px solid #6c5c3d;
|
||||
border: 1px solid var(--ui-tooltip-border);
|
||||
border-radius: 0;
|
||||
background: #020302;
|
||||
box-shadow: 0 6px 14px #000;
|
||||
color: #f5f5ef;
|
||||
background: var(--ui-tooltip-background);
|
||||
box-shadow: 0 6px 14px var(--ui-tooltip-shadow);
|
||||
color: var(--ui-tooltip-foreground);
|
||||
font-size: 12px;
|
||||
line-height: 1.5;
|
||||
transform-origin: var(--reka-tooltip-content-transform-origin);
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue'
|
||||
import { UiAutocomplete, type UiAutocompleteOption } from '@/components/ui/autocomplete'
|
||||
import { UiBadge } from '@/components/ui/badge'
|
||||
import { buttonVariants, UiButton } from '@/components/ui/button'
|
||||
import { UiCheckbox } from '@/components/ui/checkbox'
|
||||
import { UiDataRow, UiDataSection } from '@/components/ui/data-section'
|
||||
import {
|
||||
UiDataTable,
|
||||
type UiDataTableColumn,
|
||||
@@ -29,10 +31,12 @@ import {
|
||||
import { UiInput } from '@/components/ui/input'
|
||||
import { UiItemSlot } from '@/components/ui/item-slot'
|
||||
import { UiNumberField } from '@/components/ui/number-field'
|
||||
import { UiNavigation, type UiNavigationItem } from '@/components/ui/navigation'
|
||||
import { UiPanel } from '@/components/ui/panel'
|
||||
import { UiProgress } from '@/components/ui/progress'
|
||||
import { UiRadioGroup, UiRadioGroupItem } from '@/components/ui/radio-group'
|
||||
import { UiRating } from '@/components/ui/rating'
|
||||
import { UiScrollArea } from '@/components/ui/scroll-area'
|
||||
import {
|
||||
SelectRoot,
|
||||
SelectValue,
|
||||
@@ -41,6 +45,8 @@ import {
|
||||
UiSelectTrigger,
|
||||
} from '@/components/ui/select'
|
||||
import { UiSlider } from '@/components/ui/slider'
|
||||
import { UiSettingRow, UiSettingsGroup, UiSettingsSection } from '@/components/ui/settings'
|
||||
import { UiShopItemList, type UiShopItem } from '@/components/ui/shop-item-row'
|
||||
import { UiSwitch } from '@/components/ui/switch'
|
||||
import { TabsRoot, UiTabsContent, UiTabsList, UiTabsTrigger } from '@/components/ui/tabs'
|
||||
import {
|
||||
@@ -55,6 +61,10 @@ import itemArtifact from '../../../../design/src-web/rarity/img/sprite_item.NPK/
|
||||
import itemLegend from '../../../../design/src-web/rarity/img/sprite_item.NPK/equipmentskill.img/2.PNG'
|
||||
import itemEpic from '../../../../design/src-web/rarity/img/sprite_item.NPK/equipmentskill.img/3.PNG'
|
||||
import itemPrimeval from '../../../../design/src-web/rarity/img/sprite_item.NPK/equipmentskill.img/4.PNG'
|
||||
import navHome from '../../../../design/src-web/navigation/img/sprite_interface2_option.NPK/option.img/82.PNG'
|
||||
import navDisplay from '../../../../design/src-web/navigation/img/sprite_interface2_option.NPK/option.img/85.PNG'
|
||||
import navEffect from '../../../../design/src-web/navigation/img/sprite_interface2_option.NPK/option.img/91.PNG'
|
||||
import navArrow from '../../../../design/src-web/navigation/img/sprite_interface2_option.NPK/option.img/103.PNG'
|
||||
|
||||
const { activeTheme, themes, setTheme } = useTheme()
|
||||
|
||||
@@ -71,6 +81,10 @@ const activeTab = ref('equipment')
|
||||
const activeLineTab = ref('detail')
|
||||
const lastAction = ref('尚未执行菜单操作')
|
||||
const selectedRow = ref('sword')
|
||||
const autocompleteValue = ref('dnf-one')
|
||||
const navigationValue = ref('effects')
|
||||
const dataSectionOpen = ref(true)
|
||||
const shopSelected = ref('shop-rare')
|
||||
const sortKey = ref('reinforce')
|
||||
const sortDirection = ref<'ascending' | 'descending'>('ascending')
|
||||
|
||||
@@ -95,6 +109,62 @@ const componentNames = [
|
||||
'Tooltip',
|
||||
'DropdownMenu',
|
||||
'Dialog',
|
||||
'Autocomplete',
|
||||
'Navigation',
|
||||
'DataSection',
|
||||
'ScrollArea',
|
||||
'Settings',
|
||||
'ShopItemRow',
|
||||
]
|
||||
|
||||
const autocompleteOptions: UiAutocompleteOption[] = [
|
||||
{ value: 'dnf-one', label: 'DNF Toonies(1天)' },
|
||||
{ value: 'dnf-three', label: 'DNF Toonies(3天)' },
|
||||
{ value: 'poison', label: 'DNF毒战者', tone: 'epic' },
|
||||
{ value: 'sage', label: 'DNF智者', tone: 'rare' },
|
||||
{ value: 'warrior', label: '闪耀之DNF勇士', tone: 'artifact' },
|
||||
]
|
||||
|
||||
const navigationItems: UiNavigationItem[] = [
|
||||
{ value: 'home', label: '首页', icon: navHome },
|
||||
{ value: 'display', label: '画面', icon: navDisplay, indicator: navArrow },
|
||||
{ value: 'effects', label: '特效', icon: navEffect, indicator: navArrow },
|
||||
]
|
||||
|
||||
const shopRows: UiShopItem[] = [
|
||||
{
|
||||
id: 'shop-artifact',
|
||||
image: itemArtifact,
|
||||
reinforce: '+0',
|
||||
amplify: '+0',
|
||||
name: '人造神 3 号纳波尔宝珠',
|
||||
status: '购买完成',
|
||||
statusTone: 'info',
|
||||
owner: '湖北 4\n绝唱',
|
||||
rarity: 'artifact',
|
||||
},
|
||||
{
|
||||
id: 'shop-epic',
|
||||
image: itemEpic,
|
||||
reinforce: '+0',
|
||||
amplify: '+0',
|
||||
name: '果味整夏收集箱宝珠自选',
|
||||
status: '出售完成',
|
||||
statusTone: 'success',
|
||||
owner: '湖北 4\n绝唱',
|
||||
rarity: 'epic',
|
||||
},
|
||||
{
|
||||
id: 'shop-rare',
|
||||
image: itemRare,
|
||||
reinforce: '+2',
|
||||
amplify: '+0',
|
||||
name: '魔法封印转换灵魂',
|
||||
status: '购买完成',
|
||||
statusTone: 'info',
|
||||
owner: '湖北 4\n蛋猪超人',
|
||||
rarity: 'rare',
|
||||
},
|
||||
]
|
||||
|
||||
const raritySamples = [
|
||||
@@ -385,8 +455,62 @@ function handleSort(key: string) {
|
||||
</UiPanel>
|
||||
</div>
|
||||
|
||||
<div class="two-column migrated-row">
|
||||
<UiPanel title="Autocomplete / DataSection" note="Reka Combobox · Collapsible">
|
||||
<div class="migration-stack">
|
||||
<label class="field-stack">
|
||||
<span>Autocomplete · keyboard filtering</span>
|
||||
<UiAutocomplete
|
||||
v-model="autocompleteValue"
|
||||
:options="autocompleteOptions"
|
||||
placeholder="搜索物品名称"
|
||||
/>
|
||||
</label>
|
||||
<UiDataSection v-model:open="dataSectionOpen" title="基本信息">
|
||||
<UiDataRow><span class="grow">魔法暴击</span><b>+113.5%</b></UiDataRow>
|
||||
<UiDataRow><span class="grow">技能等级</span><b>46</b></UiDataRow>
|
||||
<UiDataRow disabled><span class="grow">精神</span><span>不可用</span></UiDataRow>
|
||||
</UiDataSection>
|
||||
</div>
|
||||
</UiPanel>
|
||||
|
||||
<UiPanel title="Navigation / SettingsRow" note="Source composition · responsive rows">
|
||||
<div class="navigation-settings-demo">
|
||||
<UiNavigation v-model="navigationValue" :items="navigationItems" label="设置分类" />
|
||||
<UiSettingsGroup>
|
||||
<UiSettingsSection>显示特效</UiSettingsSection>
|
||||
<UiSettingRow label="阴影效果">
|
||||
<label class="ui-control-row"><UiCheckbox v-model="accepted" />开启</label>
|
||||
</UiSettingRow>
|
||||
<UiSettingRow label="角色轮廓" alt focused>
|
||||
<UiSlider v-model="volume" label="角色轮廓" />
|
||||
</UiSettingRow>
|
||||
<UiSettingRow label="自动同步" :indent="1">
|
||||
<label class="ui-control-row"><UiSwitch v-model="syncEnabled" />开启</label>
|
||||
</UiSettingRow>
|
||||
</UiSettingsGroup>
|
||||
</div>
|
||||
</UiPanel>
|
||||
</div>
|
||||
|
||||
<UiPanel title="ShopItemRow / ScrollArea" note="Source frame layers · real scrolling">
|
||||
<div class="shop-scroll-demo">
|
||||
<UiShopItemList
|
||||
v-model:selected="shopSelected"
|
||||
:rows="shopRows"
|
||||
@inspect="lastAction = `查看 ${$event.name}`"
|
||||
/>
|
||||
<UiScrollArea class="catalog-scroll-area">
|
||||
<div class="scroll-demo-content">
|
||||
<b>SCROLLABLE SOURCE CONTENT</b>
|
||||
<span v-for="index in 12" :key="index">设置记录 {{ index }}</span>
|
||||
</div>
|
||||
</UiScrollArea>
|
||||
</div>
|
||||
</UiPanel>
|
||||
|
||||
<UiPanel
|
||||
title="Tooltip / DropdownMenu / WindowDialog"
|
||||
title="Tooltip / DropdownMenu / WindowDialog / ComplexDialog"
|
||||
note="Portal · Escape · focus restoration"
|
||||
>
|
||||
<div class="overlay-showcase">
|
||||
@@ -434,6 +558,59 @@ function handleSort(key: string) {
|
||||
></DialogPortal
|
||||
></DialogRoot
|
||||
>
|
||||
<DialogRoot
|
||||
><DialogTrigger as-child
|
||||
><UiButton variant="outline">打开组合设置窗口</UiButton></DialogTrigger
|
||||
><DialogPortal
|
||||
><UiDialogOverlay /><UiDialogContent class="complex-dialog-demo"
|
||||
><UiDialogHeader
|
||||
><UiDialogTitle>管理设置</UiDialogTitle>
|
||||
<UiDialogDescription
|
||||
>组合展示已迁移的导航、设置行、滚动区与表单控件。</UiDialogDescription
|
||||
></UiDialogHeader
|
||||
>
|
||||
<div class="complex-dialog-body">
|
||||
<p>※ 直接组合迁移后的 Navigation、SettingsRow、ScrollArea 与表单控件。</p>
|
||||
<div class="complex-dialog-main">
|
||||
<UiNavigation
|
||||
v-model="navigationValue"
|
||||
:items="navigationItems"
|
||||
label="设置分类"
|
||||
/>
|
||||
<UiScrollArea class="complex-dialog-scroll">
|
||||
<UiSettingsGroup>
|
||||
<UiSettingsSection>当前预设差异</UiSettingsSection>
|
||||
<UiSettingRow label="装备信息对比">
|
||||
<label class="ui-control-row"
|
||||
><UiCheckbox v-model="accepted" />开启</label
|
||||
>
|
||||
</UiSettingRow>
|
||||
<UiSettingRow label="角色技能效果透明" alt>
|
||||
<UiSlider v-model="volume" label="技能透明度" />
|
||||
</UiSettingRow>
|
||||
<UiSettingRow label="自动同步">
|
||||
<label class="ui-control-row"
|
||||
><UiSwitch v-model="syncEnabled" />开启</label
|
||||
>
|
||||
</UiSettingRow>
|
||||
<UiSettingRow label="界面分类" alt>
|
||||
<UiAutocomplete
|
||||
v-model="autocompleteValue"
|
||||
:options="autocompleteOptions"
|
||||
/>
|
||||
</UiSettingRow>
|
||||
</UiSettingsGroup>
|
||||
</UiScrollArea>
|
||||
</div>
|
||||
</div>
|
||||
<UiDialogFooter
|
||||
><DialogClose :class="buttonVariants({ variant: 'outline' })"
|
||||
>返回</DialogClose
|
||||
><DialogClose :class="buttonVariants()">应用</DialogClose></UiDialogFooter
|
||||
></UiDialogContent
|
||||
></DialogPortal
|
||||
></DialogRoot
|
||||
>
|
||||
<output>{{ lastAction }}</output>
|
||||
</div>
|
||||
</UiPanel>
|
||||
@@ -750,6 +927,67 @@ label > span,
|
||||
margin-top: 10px;
|
||||
color: var(--ui-primary-foreground);
|
||||
}
|
||||
.migration-stack {
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
}
|
||||
.navigation-settings-demo {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(150px, 0.42fr) minmax(0, 1fr);
|
||||
gap: 12px;
|
||||
}
|
||||
.navigation-settings-demo :deep(.ui-navigation) {
|
||||
--ui-navigation-width: 100%;
|
||||
}
|
||||
.shop-scroll-demo {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) minmax(150px, 0.22fr);
|
||||
gap: 12px;
|
||||
}
|
||||
.catalog-scroll-area {
|
||||
--ui-scroll-area-height: 158px;
|
||||
border: 1px solid var(--ui-composition-border);
|
||||
}
|
||||
.scroll-demo-content {
|
||||
display: grid;
|
||||
padding: 8px 20px 8px 8px;
|
||||
gap: 7px;
|
||||
color: var(--ui-muted-foreground);
|
||||
}
|
||||
.scroll-demo-content b {
|
||||
color: var(--ui-primary-foreground);
|
||||
font-size: 10px;
|
||||
font-weight: 400;
|
||||
}
|
||||
.complex-dialog-demo {
|
||||
--ui-dialog-max-inline-size: 980px;
|
||||
}
|
||||
.complex-dialog-body {
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
padding: 10px;
|
||||
background: var(--ui-dialog-background);
|
||||
}
|
||||
.complex-dialog-body p {
|
||||
margin: 0;
|
||||
padding: 10px;
|
||||
border: 1px solid var(--ui-composition-border);
|
||||
color: var(--ui-muted-foreground);
|
||||
text-align: center;
|
||||
}
|
||||
.complex-dialog-main {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(160px, 0.32fr) minmax(0, 1fr);
|
||||
gap: 10px;
|
||||
min-height: 0;
|
||||
}
|
||||
.complex-dialog-main :deep(.ui-navigation) {
|
||||
--ui-navigation-width: 100%;
|
||||
}
|
||||
.complex-dialog-scroll {
|
||||
--ui-scroll-area-height: 270px;
|
||||
border: 1px solid var(--ui-composition-border);
|
||||
}
|
||||
.overlay-showcase {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
@@ -816,6 +1054,10 @@ footer {
|
||||
.control-grid {
|
||||
grid-template-columns: 1fr 1fr;
|
||||
}
|
||||
.navigation-settings-demo,
|
||||
.shop-scroll-demo {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 520px) {
|
||||
@@ -838,6 +1080,21 @@ footer {
|
||||
.slider-line {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
.complex-dialog-main {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
.complex-dialog-main :deep(.ui-navigation) {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
}
|
||||
.complex-dialog-main :deep(.ui-navigation__item) {
|
||||
height: var(--ui-control-height-large);
|
||||
grid-template-columns: 18px minmax(0, 1fr);
|
||||
padding-inline: 7px;
|
||||
}
|
||||
.complex-dialog-main :deep(.ui-navigation__item > :last-child) {
|
||||
display: none;
|
||||
}
|
||||
.overlay-showcase output {
|
||||
width: 100%;
|
||||
margin-left: 0;
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
@use 'sass:map';
|
||||
|
||||
/*
|
||||
* Static component recipes belong in SCSS; runtime theme values remain CSS custom properties.
|
||||
* Add a density here only when it changes component anatomy rather than a single page layout.
|
||||
*/
|
||||
$badge-density: (
|
||||
height: var(--ui-badge-height),
|
||||
padding-inline: var(--ui-badge-padding-inline),
|
||||
font-size: var(--ui-badge-font-size),
|
||||
);
|
||||
|
||||
@layer components {
|
||||
.ui-badge {
|
||||
display: inline-flex;
|
||||
height: map.get($badge-density, height);
|
||||
align-items: center;
|
||||
padding-inline: map.get($badge-density, padding-inline);
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-radius: 0;
|
||||
font-size: map.get($badge-density, font-size);
|
||||
font-weight: 400;
|
||||
line-height: var(--ui-control-line-height);
|
||||
}
|
||||
|
||||
/* Shared composition helper for a control and its visible label. */
|
||||
.ui-control-row {
|
||||
display: inline-flex;
|
||||
min-width: 0;
|
||||
align-items: center;
|
||||
gap: var(--ui-control-gap);
|
||||
line-height: var(--ui-control-line-height);
|
||||
}
|
||||
}
|
||||
@@ -1,21 +1,21 @@
|
||||
.ui-button {
|
||||
gap: var(--ui-control-gap);
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-radius: 0;
|
||||
color: var(--ui-primary-foreground);
|
||||
font-family: inherit;
|
||||
font-weight: 400;
|
||||
line-height: var(--ui-control-line-height);
|
||||
text-decoration: none;
|
||||
text-shadow:
|
||||
1px 1px 0 #000,
|
||||
0 0 2px #000;
|
||||
text-shadow: var(--ui-control-text-shadow);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.ui-button:focus-visible {
|
||||
outline: 1px solid var(--ui-ring);
|
||||
outline-offset: 1px;
|
||||
color: #eee2aa;
|
||||
color: var(--ui-control-focus-foreground);
|
||||
}
|
||||
|
||||
.ui-button:active:not(:disabled) {
|
||||
@@ -44,14 +44,14 @@
|
||||
}
|
||||
|
||||
.ui-button--secondary {
|
||||
border-color: #4f5128;
|
||||
background: linear-gradient(180deg, #014f22, #013f1b);
|
||||
color: #b7d895;
|
||||
border-color: var(--ui-control-secondary-border);
|
||||
background: var(--ui-control-secondary-background);
|
||||
color: var(--ui-control-secondary-foreground);
|
||||
}
|
||||
|
||||
.ui-button--outline {
|
||||
border-color: var(--ui-border);
|
||||
background: #101211;
|
||||
background: var(--ui-control-outline-background);
|
||||
color: var(--ui-foreground);
|
||||
}
|
||||
|
||||
@@ -62,9 +62,9 @@
|
||||
}
|
||||
|
||||
.ui-button--destructive {
|
||||
border-color: #6a4829;
|
||||
background: linear-gradient(180deg, #522d01, #412401);
|
||||
color: #e2b46e;
|
||||
border-color: var(--ui-control-destructive-border);
|
||||
background: var(--ui-control-destructive-background);
|
||||
color: var(--ui-control-destructive-foreground);
|
||||
}
|
||||
|
||||
.ui-button--ghost {
|
||||
@@ -83,3 +83,31 @@
|
||||
color: var(--ui-control-disabled-foreground);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.ui-button--size-compact {
|
||||
height: var(--ui-control-height-compact);
|
||||
min-width: var(--ui-button-min-inline-size, 80px);
|
||||
padding-inline: var(--ui-control-padding-inline-compact);
|
||||
font-size: var(--ui-control-font-size-compact);
|
||||
}
|
||||
|
||||
.ui-button--size-default {
|
||||
height: var(--ui-control-height-default);
|
||||
min-width: var(--ui-button-min-inline-size, 110px);
|
||||
padding-inline: var(--ui-control-padding-inline-default);
|
||||
font-size: var(--ui-control-font-size-default);
|
||||
}
|
||||
|
||||
.ui-button--size-large {
|
||||
height: var(--ui-control-height-large);
|
||||
min-width: var(--ui-button-min-inline-size, 168px);
|
||||
padding-inline: var(--ui-control-padding-inline-large);
|
||||
font-size: var(--ui-control-font-size-large);
|
||||
}
|
||||
|
||||
.ui-button--size-icon {
|
||||
width: var(--ui-control-height-default);
|
||||
min-width: var(--ui-control-height-default);
|
||||
height: var(--ui-control-height-default);
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
@use './app.scss';
|
||||
@use './icon.scss';
|
||||
@use './char-img.scss';
|
||||
@use './components/control';
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
[data-theme='dcalc'] {
|
||||
color-scheme: dark;
|
||||
|
||||
/* Global surfaces and readable foreground hierarchy. */
|
||||
--ui-background: var(--dcalc-black-950);
|
||||
--ui-foreground: var(--dcalc-text-secondary);
|
||||
--ui-surface: var(--dcalc-panel);
|
||||
@@ -22,11 +23,17 @@
|
||||
--ui-input: #5b472a;
|
||||
--ui-ring: var(--dcalc-focus);
|
||||
--ui-overlay: rgb(0 0 0 / 66%);
|
||||
--ui-info: var(--dcalc-info); /* Informational status text. */
|
||||
--ui-success: var(--dcalc-success); /* Successful operation status text. */
|
||||
--ui-warning: var(--dcalc-warning); /* Recoverable warning status text. */
|
||||
--ui-selected: var(--dcalc-selected); /* Selected item text/marker, independent of focus. */
|
||||
|
||||
/* DNF controls intentionally keep near-square corners. */
|
||||
--ui-radius-sm: 2px;
|
||||
--ui-radius-md: 2px;
|
||||
--ui-radius-lg: 2px;
|
||||
|
||||
/* Application chrome: panels, title bars, rows and data headers. */
|
||||
--ui-titlebar-background: linear-gradient(180deg, #5a7099, #415272 55%, #313e58);
|
||||
--ui-titlebar-foreground: #f0f2ef;
|
||||
--ui-panel-heading: #111313;
|
||||
@@ -36,6 +43,7 @@
|
||||
--ui-table-header: linear-gradient(180deg, #352817 0%, #1b170d 48%, #090a07 100%);
|
||||
--ui-table-header-foreground: #bc9e58;
|
||||
|
||||
/* Shared button/control state contract ported from design/src-web/button. */
|
||||
--ui-control-background: linear-gradient(180deg, #223768, #122438);
|
||||
--ui-control-background-hover: linear-gradient(180deg, #2b477f, #213766);
|
||||
--ui-control-background-active: linear-gradient(180deg, #2b477f, #213766);
|
||||
@@ -44,6 +52,259 @@
|
||||
--ui-control-disabled-background: linear-gradient(180deg, #2c2c2c, #222);
|
||||
--ui-control-disabled-border: #343434;
|
||||
--ui-control-disabled-foreground: #4d4b4d;
|
||||
--ui-control-text-shadow: 1px 1px 0 #000, 0 0 2px #000;
|
||||
--ui-control-focus-foreground: #eee2aa;
|
||||
--ui-control-secondary-background: linear-gradient(180deg, #014f22, #013f1b);
|
||||
--ui-control-secondary-border: #4f5128;
|
||||
--ui-control-secondary-foreground: #b7d895;
|
||||
--ui-control-outline-background: #101211;
|
||||
--ui-control-destructive-background: linear-gradient(180deg, #522d01, #412401);
|
||||
--ui-control-destructive-border: #6a4829;
|
||||
--ui-control-destructive-foreground: #e2b46e;
|
||||
/* Text fields, number fields and select triggers. */
|
||||
--ui-field-background: linear-gradient(#0b0c0d, #000100);
|
||||
--ui-field-inset: #050505;
|
||||
--ui-field-focus-inset: #071722;
|
||||
--ui-field-focus-edge: #24617c;
|
||||
--ui-field-disabled-background: #101110;
|
||||
/* Select/list option states. */
|
||||
--ui-option-divider: #25231f;
|
||||
--ui-option-highlight-background: #091731;
|
||||
--ui-option-highlight-foreground: #f3d777;
|
||||
--ui-option-active-background: #07121b;
|
||||
--ui-option-active-foreground: #fff0a4;
|
||||
/* Tabs, including the list-owned animated arrow/line marker. */
|
||||
--ui-tab-list-background: #090709;
|
||||
--ui-tab-divider: #584840;
|
||||
--ui-tab-background: #080808;
|
||||
--ui-tab-foreground: #9c815a;
|
||||
--ui-tab-active-foreground: #e4ca90;
|
||||
--ui-tab-separator: #342f2a;
|
||||
--ui-tab-marker: #d0a56a;
|
||||
--ui-tab-marker-start: #9d7a35;
|
||||
--ui-tab-marker-middle: #a7823f;
|
||||
--ui-tab-hover-glow: linear-gradient(
|
||||
90deg,
|
||||
transparent,
|
||||
rgb(48 24 8 / 18%) 10%,
|
||||
rgb(48 24 8 / 72%) 28%,
|
||||
#301808 50%,
|
||||
rgb(48 24 8 / 72%) 72%,
|
||||
rgb(48 24 8 / 18%) 90%,
|
||||
transparent
|
||||
);
|
||||
--ui-tab-selected-glow: radial-gradient(
|
||||
ellipse 58% 46% at 50% 100%,
|
||||
rgb(114 97 30 / 94%),
|
||||
rgb(88 74 23 / 74%) 34%,
|
||||
rgb(52 44 14 / 38%) 66%,
|
||||
transparent
|
||||
);
|
||||
/* Checkbox visual layers and state transitions. */
|
||||
--ui-check-edge-top: #635036;
|
||||
--ui-check-edge-bottom: #3c2e1b;
|
||||
--ui-check-surface-top: #242424;
|
||||
--ui-check-surface-bottom: #0f0f0f;
|
||||
--ui-check-hover-edge-top: #bf9d6a;
|
||||
--ui-check-hover-edge-bottom: #947853;
|
||||
--ui-check-hover-surface-top: #3a3a3a;
|
||||
--ui-check-hover-surface-bottom: #181818;
|
||||
--ui-check-mark-top: #dfb142;
|
||||
--ui-check-mark-bottom: #eac75f;
|
||||
--ui-check-disabled-edge-top: #414141;
|
||||
--ui-check-disabled-edge-bottom: #252525;
|
||||
--ui-check-disabled-surface-top: #1f1f1f;
|
||||
--ui-check-disabled-surface-bottom: #0d0d0d;
|
||||
/* Radio control shell, disabled slash and selected indicator. */
|
||||
--ui-radio-border: #614f36;
|
||||
--ui-radio-surface: linear-gradient(#2e2e2e, #171717);
|
||||
--ui-radio-hover-border: #d6c889;
|
||||
--ui-radio-hover-surface: linear-gradient(#4a4a4a, #252525);
|
||||
--ui-radio-disabled-border: #3b3b3b;
|
||||
--ui-radio-disabled-mark: #313131;
|
||||
--ui-radio-disabled-surface: linear-gradient(#252525, #121212);
|
||||
--ui-radio-mark: linear-gradient(#dbaa3a, #edd067);
|
||||
--ui-radio-mark-border: linear-gradient(#f0dfa0, #a17e50);
|
||||
--ui-radio-mark-inset: #272727;
|
||||
/* Switch track and checked state. Thumb reuses the generic control surface. */
|
||||
--ui-switch-surface: linear-gradient(#141414, #0f0f0f);
|
||||
--ui-switch-border: linear-gradient(#846a48, #453520);
|
||||
--ui-switch-inset: #090909;
|
||||
--ui-switch-checked-surface: linear-gradient(#eccb65, #eccb65);
|
||||
--ui-switch-checked-inset: #0d0d0d;
|
||||
/* Slider coordinate visuals. Geometry stays in the component because Reka owns the track. */
|
||||
--ui-slider-track: #515351;
|
||||
--ui-slider-track-shadow: #020202;
|
||||
--ui-slider-range: #f3d367;
|
||||
--ui-slider-range-shadow: rgb(243 211 103 / 25%);
|
||||
--ui-slider-thumb-edge-top: #86693f;
|
||||
--ui-slider-thumb-edge-bottom: #76593a;
|
||||
--ui-slider-thumb-top: #21365e;
|
||||
--ui-slider-thumb-bottom: #1b2b4d;
|
||||
--ui-slider-thumb-hover-edge-top: #907960;
|
||||
--ui-slider-thumb-hover-edge-bottom: #80695b;
|
||||
--ui-slider-thumb-hover-top: #2b467f;
|
||||
--ui-slider-thumb-hover-bottom: #253b6e;
|
||||
--ui-slider-disabled-range: #686868;
|
||||
--ui-slider-disabled-thumb-edge-top: #454545;
|
||||
--ui-slider-disabled-thumb-edge-bottom: #3e3e3e;
|
||||
--ui-slider-disabled-thumb-top: #2c2c2c;
|
||||
--ui-slider-disabled-thumb-bottom: #242424;
|
||||
/* Reusable one-pixel control depth; kept separate from panel elevation. */
|
||||
--ui-control-outer-shadow: rgb(0 0 0 / 40%);
|
||||
--ui-control-inner-highlight: rgb(255 255 255 / 2.5%);
|
||||
--ui-select-icon-shadow: rgb(0 0 0 / 60%); /* Outer pixel edge around the raster arrow button. */
|
||||
--ui-check-outer-shadow: rgb(0 0 0 / 30%);
|
||||
--ui-check-mark-shadow: rgb(230 192 86 / 45%);
|
||||
/* NumberField spinner and the source-derived +/-10 raster-like surfaces. */
|
||||
--ui-number-spinner-divider: #4b412d;
|
||||
--ui-number-step-divider: #2e2d28;
|
||||
--ui-number-step-hover: rgb(255 255 255 / 3.5%);
|
||||
--ui-number-step-active: rgb(0 0 0 / 35%);
|
||||
--ui-number-step-arrow: #b99550;
|
||||
--ui-number-fast-text: #b69260;
|
||||
--ui-number-fast-up-background:
|
||||
linear-gradient(90deg, #3c66b4 0 1px, transparent 1px 23px, #3c66b4 23px) 1px 4px / 24px 9px
|
||||
no-repeat,
|
||||
linear-gradient(180deg, #325596, #1d2f53 46% 72%, #2b4378) 1px 4px / 24px 9px no-repeat,
|
||||
linear-gradient(#000, #000) 0 3px / 26px 11px no-repeat;
|
||||
--ui-number-fast-down-background:
|
||||
linear-gradient(90deg, #3e6cbe 0 1px, transparent 1px 23px, #3e6cbe 23px) 1px 1px / 24px 9px
|
||||
no-repeat,
|
||||
linear-gradient(180deg, #345a9e, #1d2f53 46% 72%, #2d4782) 1px 1px / 24px 9px no-repeat,
|
||||
linear-gradient(#000, #000) 0 0 / 26px 11px no-repeat;
|
||||
--ui-number-fast-chevron-up:
|
||||
linear-gradient(#000, #000) center 0 / 3px 1px no-repeat,
|
||||
linear-gradient(90deg, #000 0 1px, #080d17 1px 2px, #2f518f 2px 3px, #080d17 3px 4px, #000 4px)
|
||||
center 1px / 5px 1px no-repeat,
|
||||
linear-gradient(90deg, #000 0 1px, #080d17 1px 2px, #2f518f 2px 5px, #080d17 5px 6px, #000 6px)
|
||||
center 2px / 7px 1px no-repeat;
|
||||
--ui-number-fast-chevron-down:
|
||||
linear-gradient(90deg, #000 0 1px, #080d17 1px 2px, #2f518f 2px 5px, #080d17 5px 6px, #000 6px)
|
||||
center 0 / 7px 1px no-repeat,
|
||||
linear-gradient(90deg, #000 0 1px, #080d17 1px 2px, #2f518f 2px 3px, #080d17 3px 4px, #000 4px)
|
||||
center 1px / 5px 1px no-repeat,
|
||||
linear-gradient(#000, #000) center 2px / 3px 1px no-repeat;
|
||||
/* Progress and rating feedback surfaces. */
|
||||
--ui-progress-border: #3c3425;
|
||||
--ui-progress-background: #0a0b0a;
|
||||
--ui-progress-fill: linear-gradient(180deg, #9abe23, #63820a);
|
||||
--ui-progress-fill-inset: #cce43c;
|
||||
--ui-progress-marker: #d7bd61;
|
||||
--ui-rating-background: #1a1917;
|
||||
--ui-rating-highlight: rgb(255 255 255 / 3%);
|
||||
/* Tooltip, select popup and menu layers. */
|
||||
--ui-tooltip-border: #6c5c3d;
|
||||
--ui-tooltip-background: #020302;
|
||||
--ui-tooltip-shadow: #000;
|
||||
--ui-tooltip-foreground: #f5f5ef;
|
||||
--ui-popup-border: #5a4828;
|
||||
--ui-popup-background: #050606;
|
||||
--ui-popup-shadow: #000;
|
||||
--ui-menu-border: rgb(19 17 13 / 92%);
|
||||
--ui-menu-background: rgb(48 46 38 / 72%);
|
||||
--ui-menu-shadow: rgb(0 0 0 / 78%);
|
||||
--ui-menu-highlight-border: #000;
|
||||
--ui-menu-highlight-background: rgb(15 14 12 / 28%);
|
||||
--ui-menu-highlight-foreground: #ffefad;
|
||||
--ui-menu-highlight-inset: rgb(132 113 76 / 13%);
|
||||
--ui-menu-danger: #eb7c79;
|
||||
/* Dialog window chrome. The focused frame animation remains an original raster asset. */
|
||||
--ui-dialog-border: #6c5a37;
|
||||
--ui-dialog-background: #050606;
|
||||
--ui-dialog-shadow: rgb(0 0 0 / 80%);
|
||||
--ui-dialog-inset: #0e1418;
|
||||
--ui-dialog-titlebar-border: #1d2735;
|
||||
--ui-dialog-titlebar-background: linear-gradient(#303b50, #263247 56%, #1d2839);
|
||||
--ui-dialog-titlebar-focused-background: linear-gradient(#6079a5, #435a80 55%, #30425f);
|
||||
--ui-dialog-titlebar-focused-foreground: #f4f6f2;
|
||||
--ui-dialog-titlebar-text-shadow: #000;
|
||||
--ui-dialog-close-ring: rgb(225 204 135 / 72%);
|
||||
--ui-dialog-footer-border: #332c22;
|
||||
--ui-dialog-footer-background: linear-gradient(#20201d, #11110f);
|
||||
--ui-tabs-content-background: rgb(0 0 0 / 22%);
|
||||
/* Item-slot emphasis and lock overlays. Rarity frame colors remain asset/data semantics. */
|
||||
--ui-item-slot-background: #030404;
|
||||
--ui-item-slot-emphasis: #ffa800;
|
||||
--ui-item-slot-emphasis-strong: #fffc2a;
|
||||
--ui-item-slot-emphasis-shadow-strong: rgb(255 168 0 / 88%);
|
||||
--ui-item-slot-emphasis-shadow: rgb(255 168 0 / 46%);
|
||||
--ui-item-slot-emphasis-inset: rgb(255 168 0 / 70%);
|
||||
--ui-item-slot-lock-overlay: rgb(0 0 0 / 68%);
|
||||
/* Dense table anatomy and selectable-row state colors. */
|
||||
--ui-table-border: #4a3c26;
|
||||
--ui-table-background: #030403;
|
||||
--ui-table-foreground: #d2c78f;
|
||||
--ui-table-row-divider: #2c2b26;
|
||||
--ui-table-cell-divider: #292720;
|
||||
--ui-table-row-hover: linear-gradient(90deg, #132b43, #0b1824 58%, #070a0d);
|
||||
--ui-table-row-hover-outline: #3b91bd;
|
||||
--ui-table-row-selected: linear-gradient(90deg, #352b11, #161207 60%, #090a08);
|
||||
--ui-table-row-selected-outline: #d6ad37;
|
||||
--ui-table-row-selected-inset: #6d5218;
|
||||
--ui-table-header-border: #070806;
|
||||
--ui-table-header-inset: #4a3c26;
|
||||
--ui-table-header-highlight: #65502a;
|
||||
/* Autocomplete, navigation and collapsible data-section compositions. */
|
||||
--ui-composition-border: #292b27;
|
||||
--ui-composition-background: #070807;
|
||||
--ui-navigation-border: #20251f;
|
||||
--ui-navigation-divider: #25221a;
|
||||
--ui-navigation-foreground: #c5b573;
|
||||
--ui-navigation-selected-background: linear-gradient(90deg, #80601b, #1b160b 72%);
|
||||
--ui-navigation-selected-foreground: #f1d66e;
|
||||
--ui-disclosure-border: #4b3d26;
|
||||
--ui-disclosure-background: #070807;
|
||||
--ui-disclosure-header-background: linear-gradient(#2a2925, #10110f);
|
||||
--ui-disclosure-divider: #25221b;
|
||||
--ui-disclosure-row-foreground: #c9bb7e;
|
||||
--ui-disclosure-row-divider: #24231f;
|
||||
--ui-disclosure-row-focus: #07131b;
|
||||
--ui-disclosure-row-selected: #302711;
|
||||
--ui-disclosure-row-selected-foreground: #f1d667;
|
||||
--ui-disclosure-state: #857a57;
|
||||
/* Reka ScrollArea skin ported from design/src-web/scrollbar. */
|
||||
--ui-scrollbar-border: #2b2924;
|
||||
--ui-scrollbar-background: #050606;
|
||||
--ui-scrollbar-arrow-background: linear-gradient(#24241f, #10110f);
|
||||
--ui-scrollbar-arrow: #a98b46;
|
||||
--ui-scrollbar-track: linear-gradient(90deg, #080908, #151513, #070807);
|
||||
--ui-scrollbar-thumb-border: #68532d;
|
||||
--ui-scrollbar-thumb: linear-gradient(90deg, #1b1d1c, #363530, #161817);
|
||||
/* Settings group and row states. */
|
||||
--ui-settings-border: #2c2c28;
|
||||
--ui-settings-background: #050606;
|
||||
--ui-settings-section-border: #4c402a;
|
||||
--ui-settings-section-background: linear-gradient(#22231f, #0e0f0e);
|
||||
--ui-settings-section-foreground: #e4cc7c;
|
||||
--ui-settings-row-divider: #23231f;
|
||||
--ui-settings-row-foreground: #bcae73;
|
||||
--ui-settings-row-alt: #171817;
|
||||
--ui-settings-row-focus: #071017;
|
||||
/* ShopItemRow frame layers. Values are a direct port of the source component. */
|
||||
--ui-shop-foreground: #cabd82;
|
||||
--ui-shop-frame-rest-outer: #2e2e2e;
|
||||
--ui-shop-frame-rest-middle: #191919;
|
||||
--ui-shop-frame-rest-accent: #050505;
|
||||
--ui-shop-frame-rest-surface: linear-gradient(180deg, #070707 0%, #080808 100%);
|
||||
--ui-shop-frame-alt-outer: #60503a;
|
||||
--ui-shop-frame-alt-middle: #342b1f;
|
||||
--ui-shop-frame-alt-surface: linear-gradient(180deg, #0b0b0b 0%, #0e0e0e 100%);
|
||||
--ui-shop-frame-hover-outer: #000820;
|
||||
--ui-shop-frame-hover-middle: #082068;
|
||||
--ui-shop-frame-hover-accent: #1888b8;
|
||||
--ui-shop-frame-hover-inner: #082040;
|
||||
--ui-shop-frame-hover-surface: #000810;
|
||||
--ui-shop-frame-selected-outer: #201808;
|
||||
--ui-shop-frame-selected-middle: #604818;
|
||||
--ui-shop-frame-selected-accent: #e8a828;
|
||||
--ui-shop-frame-selected-inner: #302008;
|
||||
--ui-shop-frame-selected-surface: #100800;
|
||||
--ui-shop-frame-shadow: rgb(0 0 0 / 42%);
|
||||
--ui-shop-action-background: linear-gradient(180deg, #1261a4, #071f3b);
|
||||
--ui-shop-action-hover-background: linear-gradient(180deg, #1d9bdb, #0b325e);
|
||||
--ui-shop-action-inset: #0f0f0f;
|
||||
/* Panel elevation, intentionally separate from popup and dialog elevation. */
|
||||
--ui-panel-background: linear-gradient(180deg, rgb(20 22 22 / 98%), rgb(7 8 8 / 98%));
|
||||
--ui-panel-shadow: inset 0 1px 0 rgb(214 196 135 / 6%), 0 12px 28px rgb(0 0 0 / 32%);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
[data-theme='midnight'] {
|
||||
color-scheme: dark;
|
||||
|
||||
/* Midnight implements the same semantic contract as dcalc; components must not branch by theme. */
|
||||
/* Global surfaces and readable foreground hierarchy. */
|
||||
--ui-background: #080b12;
|
||||
--ui-foreground: #d9e3f2;
|
||||
--ui-surface: #111827;
|
||||
@@ -21,7 +23,12 @@
|
||||
--ui-input: #354b6e;
|
||||
--ui-ring: #6fb5e6;
|
||||
--ui-overlay: rgb(2 6 14 / 72%);
|
||||
--ui-info: #79c7f2; /* Informational status text. */
|
||||
--ui-success: #6fc58a; /* Successful operation status text. */
|
||||
--ui-warning: #d4a66d; /* Recoverable warning status text. */
|
||||
--ui-selected: #9ac8ef; /* Selected item text/marker, independent of focus. */
|
||||
|
||||
/* Shared button/control states. */
|
||||
--ui-control-background: linear-gradient(180deg, #294d80, #172b4b);
|
||||
--ui-control-background-hover: linear-gradient(180deg, #376aa7, #1e3b64);
|
||||
--ui-control-background-active: linear-gradient(180deg, #244e82, #142b4a);
|
||||
@@ -30,6 +37,280 @@
|
||||
--ui-control-disabled-background: linear-gradient(180deg, #303846, #202733);
|
||||
--ui-control-disabled-border: #3f4958;
|
||||
--ui-control-disabled-foreground: #748094;
|
||||
--ui-control-text-shadow: 1px 1px 0 #020611, 0 0 2px #020611;
|
||||
--ui-control-focus-foreground: #ffffff;
|
||||
--ui-control-secondary-background: linear-gradient(180deg, #185d55, #10433e);
|
||||
--ui-control-secondary-border: #3f817b;
|
||||
--ui-control-secondary-foreground: #d4fff8;
|
||||
--ui-control-outline-background: #101827;
|
||||
--ui-control-destructive-background: linear-gradient(180deg, #733f49, #4d2830);
|
||||
--ui-control-destructive-border: #9c5c68;
|
||||
--ui-control-destructive-foreground: #ffe2e7;
|
||||
/* Fields and option states. */
|
||||
--ui-field-background: linear-gradient(#0b1220, #070b13);
|
||||
--ui-field-inset: #050914;
|
||||
--ui-field-focus-inset: #101e33;
|
||||
--ui-field-focus-edge: #6fb5e6;
|
||||
--ui-field-disabled-background: #151b26;
|
||||
--ui-option-divider: #26364f;
|
||||
--ui-option-highlight-background: #19365d;
|
||||
--ui-option-highlight-foreground: #e4f2ff;
|
||||
--ui-option-active-background: #102845;
|
||||
--ui-option-active-foreground: #ffffff;
|
||||
/* Tabs and animated marker. */
|
||||
--ui-tab-list-background: #0b111d;
|
||||
--ui-tab-divider: #40577a;
|
||||
--ui-tab-background: #0a101b;
|
||||
--ui-tab-foreground: #8da0bc;
|
||||
--ui-tab-active-foreground: #dcecff;
|
||||
--ui-tab-separator: #2b3b55;
|
||||
--ui-tab-marker: #6fb5e6;
|
||||
--ui-tab-marker-start: #315c97;
|
||||
--ui-tab-marker-middle: #6fb5e6;
|
||||
--ui-tab-hover-glow: linear-gradient(
|
||||
90deg,
|
||||
transparent,
|
||||
rgb(31 67 111 / 18%) 10%,
|
||||
rgb(31 67 111 / 72%) 28%,
|
||||
#16375f 50%,
|
||||
rgb(31 67 111 / 72%) 72%,
|
||||
rgb(31 67 111 / 18%) 90%,
|
||||
transparent
|
||||
);
|
||||
--ui-tab-selected-glow: radial-gradient(
|
||||
ellipse 58% 46% at 50% 100%,
|
||||
rgb(69 120 176 / 94%),
|
||||
rgb(49 92 151 / 74%) 34%,
|
||||
rgb(31 63 105 / 38%) 66%,
|
||||
transparent
|
||||
);
|
||||
/* Checkbox, radio and switch state layers. */
|
||||
--ui-check-edge-top: #526f98;
|
||||
--ui-check-edge-bottom: #354b6e;
|
||||
--ui-check-surface-top: #202b3b;
|
||||
--ui-check-surface-bottom: #101722;
|
||||
--ui-check-hover-edge-top: #9ac8ef;
|
||||
--ui-check-hover-edge-bottom: #658db8;
|
||||
--ui-check-hover-surface-top: #34475f;
|
||||
--ui-check-hover-surface-bottom: #1b2a3e;
|
||||
--ui-check-mark-top: #8dc9f0;
|
||||
--ui-check-mark-bottom: #dcecff;
|
||||
--ui-check-disabled-edge-top: #465163;
|
||||
--ui-check-disabled-edge-bottom: #303846;
|
||||
--ui-check-disabled-surface-top: #29313d;
|
||||
--ui-check-disabled-surface-bottom: #1b222d;
|
||||
--ui-radio-border: #526f98;
|
||||
--ui-radio-surface: linear-gradient(#29384d, #151f2e);
|
||||
--ui-radio-hover-border: #9ac8ef;
|
||||
--ui-radio-hover-surface: linear-gradient(#405b7b, #263b57);
|
||||
--ui-radio-disabled-border: #3f4958;
|
||||
--ui-radio-disabled-mark: #465163;
|
||||
--ui-radio-disabled-surface: linear-gradient(#303846, #202733);
|
||||
--ui-radio-mark: linear-gradient(#6fb5e6, #dcecff);
|
||||
--ui-radio-mark-border: linear-gradient(#c5e7ff, #526f98);
|
||||
--ui-radio-mark-inset: #17243a;
|
||||
--ui-switch-surface: linear-gradient(#1a2435, #101722);
|
||||
--ui-switch-border: linear-gradient(#526f98, #354b6e);
|
||||
--ui-switch-inset: #080d16;
|
||||
--ui-switch-checked-surface: linear-gradient(#6fb5e6, #6fb5e6);
|
||||
--ui-switch-checked-inset: #17243a;
|
||||
/* Slider, number-field, progress and rating feedback. */
|
||||
--ui-slider-track: #40516a;
|
||||
--ui-slider-track-shadow: #050914;
|
||||
--ui-slider-range: #86c8f2;
|
||||
--ui-slider-range-shadow: rgb(111 181 230 / 28%);
|
||||
--ui-slider-thumb-edge-top: #6686ad;
|
||||
--ui-slider-thumb-edge-bottom: #456487;
|
||||
--ui-slider-thumb-top: #315c97;
|
||||
--ui-slider-thumb-bottom: #1d3d68;
|
||||
--ui-slider-thumb-hover-edge-top: #9ac8ef;
|
||||
--ui-slider-thumb-hover-edge-bottom: #658db8;
|
||||
--ui-slider-thumb-hover-top: #477cb5;
|
||||
--ui-slider-thumb-hover-bottom: #295987;
|
||||
--ui-slider-disabled-range: #596474;
|
||||
--ui-slider-disabled-thumb-edge-top: #505b6b;
|
||||
--ui-slider-disabled-thumb-edge-bottom: #3f4958;
|
||||
--ui-slider-disabled-thumb-top: #384352;
|
||||
--ui-slider-disabled-thumb-bottom: #29313d;
|
||||
--ui-control-outer-shadow: rgb(0 0 0 / 42%);
|
||||
--ui-control-inner-highlight: rgb(255 255 255 / 4%);
|
||||
--ui-select-icon-shadow: rgb(0 0 0 / 60%); /* Keeps the arrow button legible on blue fields. */
|
||||
--ui-check-outer-shadow: rgb(0 0 0 / 34%);
|
||||
--ui-check-mark-shadow: rgb(111 181 230 / 42%);
|
||||
--ui-number-spinner-divider: #40577a;
|
||||
--ui-number-step-divider: #2b3b55;
|
||||
--ui-number-step-hover: rgb(255 255 255 / 5%);
|
||||
--ui-number-step-active: rgb(0 0 0 / 38%);
|
||||
--ui-number-step-arrow: #9ac8ef;
|
||||
--ui-number-fast-text: #c9d8ef;
|
||||
--ui-number-fast-up-background:
|
||||
linear-gradient(90deg, #5786bd 0 1px, transparent 1px 23px, #5786bd 23px) 1px 4px / 24px 9px
|
||||
no-repeat,
|
||||
linear-gradient(180deg, #376aa7, #1e3b64 46% 72%, #294e80) 1px 4px / 24px 9px no-repeat,
|
||||
linear-gradient(#050914, #050914) 0 3px / 26px 11px no-repeat;
|
||||
--ui-number-fast-down-background:
|
||||
linear-gradient(90deg, #6b9ace 0 1px, transparent 1px 23px, #6b9ace 23px) 1px 1px / 24px 9px
|
||||
no-repeat,
|
||||
linear-gradient(180deg, #477cb5, #1e3b64 46% 72%, #315c97) 1px 1px / 24px 9px no-repeat,
|
||||
linear-gradient(#050914, #050914) 0 0 / 26px 11px no-repeat;
|
||||
--ui-number-fast-chevron-up:
|
||||
linear-gradient(#050914, #050914) center 0 / 3px 1px no-repeat,
|
||||
linear-gradient(
|
||||
90deg,
|
||||
#050914 0 1px,
|
||||
#101b2d 1px 2px,
|
||||
#5786bd 2px 3px,
|
||||
#101b2d 3px 4px,
|
||||
#050914 4px
|
||||
)
|
||||
center 1px / 5px 1px no-repeat,
|
||||
linear-gradient(
|
||||
90deg,
|
||||
#050914 0 1px,
|
||||
#101b2d 1px 2px,
|
||||
#5786bd 2px 5px,
|
||||
#101b2d 5px 6px,
|
||||
#050914 6px
|
||||
)
|
||||
center 2px / 7px 1px no-repeat;
|
||||
--ui-number-fast-chevron-down:
|
||||
linear-gradient(
|
||||
90deg,
|
||||
#050914 0 1px,
|
||||
#101b2d 1px 2px,
|
||||
#5786bd 2px 5px,
|
||||
#101b2d 5px 6px,
|
||||
#050914 6px
|
||||
)
|
||||
center 0 / 7px 1px no-repeat,
|
||||
linear-gradient(
|
||||
90deg,
|
||||
#050914 0 1px,
|
||||
#101b2d 1px 2px,
|
||||
#5786bd 2px 3px,
|
||||
#101b2d 3px 4px,
|
||||
#050914 4px
|
||||
)
|
||||
center 1px / 5px 1px no-repeat,
|
||||
linear-gradient(#050914, #050914) center 2px / 3px 1px no-repeat;
|
||||
--ui-progress-border: #40577a;
|
||||
--ui-progress-background: #0b111d;
|
||||
--ui-progress-fill: linear-gradient(180deg, #4d9ac6, #315c97);
|
||||
--ui-progress-fill-inset: #9ac8ef;
|
||||
--ui-progress-marker: #dcecff;
|
||||
--ui-rating-background: #151d2a;
|
||||
--ui-rating-highlight: rgb(255 255 255 / 4%);
|
||||
/* Tooltip, select popup and dropdown menu layers. */
|
||||
--ui-tooltip-border: #526f98;
|
||||
--ui-tooltip-background: #080d16;
|
||||
--ui-tooltip-shadow: #020611;
|
||||
--ui-tooltip-foreground: #edf5ff;
|
||||
--ui-popup-border: #40577a;
|
||||
--ui-popup-background: #0c1220;
|
||||
--ui-popup-shadow: #020611;
|
||||
--ui-menu-border: rgb(34 49 72 / 94%);
|
||||
--ui-menu-background: rgb(20 31 48 / 90%);
|
||||
--ui-menu-shadow: rgb(0 0 0 / 76%);
|
||||
--ui-menu-highlight-border: #40577a;
|
||||
--ui-menu-highlight-background: rgb(49 92 151 / 34%);
|
||||
--ui-menu-highlight-foreground: #ffffff;
|
||||
--ui-menu-highlight-inset: rgb(143 196 241 / 14%);
|
||||
--ui-menu-danger: #f08b94;
|
||||
/* Dialog window chrome and focused title bar. */
|
||||
--ui-dialog-border: #526f98;
|
||||
--ui-dialog-background: #080d16;
|
||||
--ui-dialog-shadow: rgb(0 0 0 / 82%);
|
||||
--ui-dialog-inset: #17243a;
|
||||
--ui-dialog-titlebar-border: #263b57;
|
||||
--ui-dialog-titlebar-background: linear-gradient(#34475f, #263b57 56%, #1b2a3e);
|
||||
--ui-dialog-titlebar-focused-background: linear-gradient(#5e83ad, #405f86 55%, #2d4869);
|
||||
--ui-dialog-titlebar-focused-foreground: #f2f8ff;
|
||||
--ui-dialog-titlebar-text-shadow: #020611;
|
||||
--ui-dialog-close-ring: rgb(154 200 239 / 78%);
|
||||
--ui-dialog-footer-border: #2b3b55;
|
||||
--ui-dialog-footer-background: linear-gradient(#1a2435, #101722);
|
||||
--ui-tabs-content-background: rgb(2 6 14 / 30%);
|
||||
/* Item and dense data-display states. */
|
||||
--ui-item-slot-background: #080d16;
|
||||
--ui-item-slot-emphasis: #6fb5e6;
|
||||
--ui-item-slot-emphasis-strong: #dcecff;
|
||||
--ui-item-slot-emphasis-shadow-strong: rgb(111 181 230 / 84%);
|
||||
--ui-item-slot-emphasis-shadow: rgb(111 181 230 / 44%);
|
||||
--ui-item-slot-emphasis-inset: rgb(154 200 239 / 68%);
|
||||
--ui-item-slot-lock-overlay: rgb(2 6 14 / 72%);
|
||||
--ui-table-border: #40577a;
|
||||
--ui-table-background: #080d16;
|
||||
--ui-table-foreground: #c9d8ef;
|
||||
--ui-table-row-divider: #26364f;
|
||||
--ui-table-cell-divider: #26364f;
|
||||
--ui-table-row-hover: linear-gradient(90deg, #19365d, #102845 58%, #0a1524);
|
||||
--ui-table-row-hover-outline: #6fb5e6;
|
||||
--ui-table-row-selected: linear-gradient(90deg, #294d80, #172b4b 60%, #0d1929);
|
||||
--ui-table-row-selected-outline: #9ac8ef;
|
||||
--ui-table-row-selected-inset: #315c97;
|
||||
--ui-table-header-border: #111c2c;
|
||||
--ui-table-header-inset: #40577a;
|
||||
--ui-table-header-highlight: #658db8;
|
||||
/* Autocomplete, navigation and collapsible data-section compositions. */
|
||||
--ui-composition-border: #26364f;
|
||||
--ui-composition-background: #0b111d;
|
||||
--ui-navigation-border: #26364f;
|
||||
--ui-navigation-divider: #26364f;
|
||||
--ui-navigation-foreground: #c9d8ef;
|
||||
--ui-navigation-selected-background: linear-gradient(90deg, #315c97, #172b4b 72%);
|
||||
--ui-navigation-selected-foreground: #ffffff;
|
||||
--ui-disclosure-border: #40577a;
|
||||
--ui-disclosure-background: #0b111d;
|
||||
--ui-disclosure-header-background: linear-gradient(#29384d, #151f2e);
|
||||
--ui-disclosure-divider: #26364f;
|
||||
--ui-disclosure-row-foreground: #c9d8ef;
|
||||
--ui-disclosure-row-divider: #26364f;
|
||||
--ui-disclosure-row-focus: #102845;
|
||||
--ui-disclosure-row-selected: #19365d;
|
||||
--ui-disclosure-row-selected-foreground: #ffffff;
|
||||
--ui-disclosure-state: #8da0bc;
|
||||
/* Reka ScrollArea skin. */
|
||||
--ui-scrollbar-border: #26364f;
|
||||
--ui-scrollbar-background: #080d16;
|
||||
--ui-scrollbar-arrow-background: linear-gradient(#29384d, #151f2e);
|
||||
--ui-scrollbar-arrow: #9ac8ef;
|
||||
--ui-scrollbar-track: linear-gradient(90deg, #080d16, #172131, #080d16);
|
||||
--ui-scrollbar-thumb-border: #526f98;
|
||||
--ui-scrollbar-thumb: linear-gradient(90deg, #1b2a3e, #405b7b, #17243a);
|
||||
/* Settings group and row states. */
|
||||
--ui-settings-border: #26364f;
|
||||
--ui-settings-background: #080d16;
|
||||
--ui-settings-section-border: #40577a;
|
||||
--ui-settings-section-background: linear-gradient(#29384d, #151f2e);
|
||||
--ui-settings-section-foreground: #dcecff;
|
||||
--ui-settings-row-divider: #26364f;
|
||||
--ui-settings-row-foreground: #c9d8ef;
|
||||
--ui-settings-row-alt: #111827;
|
||||
--ui-settings-row-focus: #102845;
|
||||
/* ShopItemRow frame layers. */
|
||||
--ui-shop-foreground: #c9d8ef;
|
||||
--ui-shop-frame-rest-outer: #303846;
|
||||
--ui-shop-frame-rest-middle: #202733;
|
||||
--ui-shop-frame-rest-accent: #080d16;
|
||||
--ui-shop-frame-rest-surface: linear-gradient(180deg, #0b111d 0%, #0d1420 100%);
|
||||
--ui-shop-frame-alt-outer: #526f98;
|
||||
--ui-shop-frame-alt-middle: #29384d;
|
||||
--ui-shop-frame-alt-surface: linear-gradient(180deg, #111827 0%, #151d2a 100%);
|
||||
--ui-shop-frame-hover-outer: #0a1c34;
|
||||
--ui-shop-frame-hover-middle: #1f4b7b;
|
||||
--ui-shop-frame-hover-accent: #6fb5e6;
|
||||
--ui-shop-frame-hover-inner: #234e79;
|
||||
--ui-shop-frame-hover-surface: #08182b;
|
||||
--ui-shop-frame-selected-outer: #172b4b;
|
||||
--ui-shop-frame-selected-middle: #315c97;
|
||||
--ui-shop-frame-selected-accent: #9ac8ef;
|
||||
--ui-shop-frame-selected-inner: #1d3d68;
|
||||
--ui-shop-frame-selected-surface: #0d1929;
|
||||
--ui-shop-frame-shadow: rgb(0 0 0 / 44%);
|
||||
--ui-shop-action-background: linear-gradient(180deg, #315c97, #172b4b);
|
||||
--ui-shop-action-hover-background: linear-gradient(180deg, #477cb5, #295987);
|
||||
--ui-shop-action-inset: #080d16;
|
||||
/* Panel elevation. */
|
||||
--ui-panel-background: linear-gradient(180deg, rgb(17 24 39 / 98%), rgb(7 12 22 / 98%));
|
||||
--ui-panel-shadow: inset 0 1px 0 rgb(143 196 241 / 8%), 0 12px 30px rgb(0 0 0 / 40%);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
:root {
|
||||
/* Captured DCalc palette. Theme files map these physical colors to semantic roles. */
|
||||
--dcalc-black-950: #050505;
|
||||
--dcalc-black-900: #090808;
|
||||
--dcalc-panel: #131515;
|
||||
@@ -24,6 +25,7 @@
|
||||
--dcalc-warning: #c28954;
|
||||
--dcalc-danger: #bb3331;
|
||||
|
||||
/* Item rarity colors are data semantics, not generic foreground colors. */
|
||||
--dcalc-quality-normal: #ffffff;
|
||||
--dcalc-quality-advanced: #68d5ed;
|
||||
--dcalc-quality-rare: #9879da;
|
||||
@@ -31,4 +33,119 @@
|
||||
--dcalc-quality-legend: #ff7700;
|
||||
--dcalc-quality-epic: #fcb600;
|
||||
--dcalc-quality-chronicle: #ff6666;
|
||||
|
||||
/*
|
||||
* Shared component metrics.
|
||||
* Heights keep the source pixel grid; callers control inline width through normal layout or
|
||||
* component-specific CSS variables instead of overriding internal selectors.
|
||||
*/
|
||||
--ui-control-height-compact: 24px;
|
||||
--ui-control-height-default: 30px;
|
||||
--ui-control-height-large: 44px;
|
||||
--ui-control-padding-inline-compact: 10px;
|
||||
--ui-control-padding-inline-default: 14px;
|
||||
--ui-control-padding-inline-large: 20px;
|
||||
--ui-control-font-size-compact: 12px;
|
||||
--ui-control-font-size-default: 13px;
|
||||
--ui-control-font-size-large: 16px;
|
||||
--ui-control-line-height: 1;
|
||||
--ui-control-gap: 7px;
|
||||
--ui-control-text-offset-y: 0px; /* Optical font correction only; never use for layout. */
|
||||
--ui-field-padding-inline: 9px;
|
||||
--ui-option-height: 27px;
|
||||
--ui-tabs-height: 40px;
|
||||
--ui-tab-height: 30px;
|
||||
|
||||
/*
|
||||
* Component geometry defaults. Every value is consumed through var(), so a component instance
|
||||
* can opt into a different density without reaching into scoped internals.
|
||||
*/
|
||||
--ui-badge-height: 18px;
|
||||
--ui-badge-padding-inline: 7px;
|
||||
--ui-badge-font-size: 10px;
|
||||
--ui-checkbox-size: 16px;
|
||||
--ui-checkbox-mark-inline-size: 18px;
|
||||
--ui-checkbox-mark-block-size: 14px;
|
||||
--ui-radio-size: 14px;
|
||||
--ui-switch-inline-size: 28px;
|
||||
--ui-switch-block-size: 16px;
|
||||
--ui-switch-thumb-size: 12px;
|
||||
--ui-switch-thumb-travel: 13px;
|
||||
--ui-rating-min-block-size: 46px;
|
||||
--ui-rating-item-size: 24px;
|
||||
--ui-slider-min-inline-size: 160px;
|
||||
--ui-slider-block-size: 34px;
|
||||
--ui-slider-control-size: 17px;
|
||||
--ui-slider-track-size: 3px;
|
||||
--ui-slider-value-min-inline-size: 40px;
|
||||
--ui-progress-block-size: 14px;
|
||||
--ui-tooltip-max-inline-size: 260px;
|
||||
--ui-menu-min-inline-size: 190px;
|
||||
--ui-menu-item-block-size: 28px;
|
||||
--ui-select-icon-inline-size: 21px;
|
||||
--ui-select-icon-block-size: 18px;
|
||||
--ui-select-glyph-inline-size: 11px;
|
||||
--ui-select-glyph-block-size: 6px;
|
||||
--ui-item-slot-size: 40px;
|
||||
--ui-item-image-size: 28px;
|
||||
--ui-item-frame-inset: 5px;
|
||||
--ui-table-row-min-block-size: 38px;
|
||||
--ui-table-header-block-size: 30px;
|
||||
--ui-table-scroll-inline-size: 560px;
|
||||
--ui-panel-heading-block-size: 46px;
|
||||
--ui-dialog-viewport-inline-size: 92vw;
|
||||
--ui-dialog-max-inline-size: 620px;
|
||||
--ui-dialog-header-block-size: 28px;
|
||||
--ui-dialog-footer-min-block-size: 38px;
|
||||
--ui-dialog-effect-inline-size: 1100px;
|
||||
--ui-dialog-close-size: 20px;
|
||||
--ui-dialog-close-glyph-inline-size: 10px;
|
||||
--ui-dialog-close-glyph-block-size: 9px;
|
||||
--ui-tab-marker-inline-size: 39px;
|
||||
--ui-tab-marker-block-size: 5px;
|
||||
--ui-tab-marker-arrow-inline-size: 9px;
|
||||
--ui-tab-marker-arrow-block-size: 4px;
|
||||
--ui-number-fast-inline-size: 26px;
|
||||
--ui-number-fast-block-size: 28px;
|
||||
--ui-number-fast-step-block-size: 14px;
|
||||
--ui-autocomplete-max-block-size: 240px;
|
||||
--ui-autocomplete-trigger-gap: 4px;
|
||||
--ui-autocomplete-indicator-font-size: 8px;
|
||||
--ui-navigation-inline-size: 250px;
|
||||
--ui-navigation-row-block-size: 48px;
|
||||
--ui-navigation-icon-size: 24px;
|
||||
--ui-navigation-indicator-inline-size: 12px;
|
||||
--ui-navigation-padding-inline: 13px;
|
||||
--ui-disclosure-header-min-block-size: 32px;
|
||||
--ui-disclosure-row-block-size: 25px;
|
||||
--ui-disclosure-icon-size: 13px;
|
||||
--ui-disclosure-state-font-size: 10px;
|
||||
--ui-disclosure-content-padding-block: 7px;
|
||||
--ui-disclosure-row-gap: 6px;
|
||||
--ui-disclosure-depth-step: 16px;
|
||||
--ui-scrollbar-inline-size: 15px;
|
||||
--ui-scrollbar-arrow-block-size: 18px;
|
||||
--ui-scroll-area-block-size: 250px;
|
||||
--ui-scrollbar-arrow-inline-size: 4px;
|
||||
--ui-scrollbar-arrow-glyph-block-size: 5px;
|
||||
--ui-scrollbar-thumb-gutter: 2px;
|
||||
--ui-settings-section-block-size: 34px;
|
||||
--ui-settings-row-min-block-size: 38px;
|
||||
--ui-settings-label-min-inline-size: 190px;
|
||||
--ui-settings-control-min-inline-size: 210px;
|
||||
--ui-settings-row-padding-block: 5px;
|
||||
--ui-settings-row-padding-inline: 10px;
|
||||
--ui-settings-indent-step: 14px;
|
||||
--ui-shop-row-min-block-size: 48px;
|
||||
--ui-shop-row-scroll-inline-size: 760px;
|
||||
--ui-shop-row-gap: 4px;
|
||||
--ui-shop-row-grid: 42px 36px 48px minmax(130px, 1.55fr) 72px 0.92fr 1.1fr;
|
||||
--ui-shop-row-padding-inline: 18px;
|
||||
--ui-shop-cell-padding-inline: 7px;
|
||||
--ui-shop-font-size: 11px;
|
||||
--ui-shop-icon-inline-size: 36px;
|
||||
--ui-shop-icon-block-size: 38px;
|
||||
--ui-shop-action-inline-size: 28px;
|
||||
--ui-shop-action-block-size: 24px;
|
||||
--ui-shop-action-icon-size: 16px;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user