Skip to content

Commit 1cb1ea0

Browse files
committed
feat(app): polish shell and inventory views
- ✨ Refresh shell navigation, buttons, cards, and shared status pills - ✨ Refine catalog ownership and inventory-facing page interactions - ✅ Align inventory API typings and Playwright/unit tests with the updated UI flow - 📦 nuxt: 4.4.2 -> 4.4.4 - 📦 wrangler: 4.86.0 -> 4.87.0 - 📦 pnpm: 10.33.2 -> 11.0.2
1 parent 53539dc commit 1cb1ea0

53 files changed

Lines changed: 1018 additions & 1540 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

app/assets/styles/sizes.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
--border-radius-12: 0.625rem;
33
--border-radius-16: 0.875rem;
44
--border-radius-24: 1.25rem;
5+
--border-radius-pill: 999px;
56

67
--layout-content-max-width: 72rem;
78
--layout-sidebar-width: 15.5rem;

app/assets/styles/transitions.css

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,10 @@
33
--transition-duration-base: 0.22s;
44
--transition-easing-out: cubic-bezier(.22, 1, .36, 1);
55
}
6+
7+
@media (prefers-reduced-motion: reduce) {
8+
:root {
9+
--transition-duration-quick: 0s;
10+
--transition-duration-base: 0s;
11+
}
12+
}

app/assets/styles/typography.css

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
:root {
2-
--font-size-12: clamp(0.75rem, 0.72rem + 0.08vw, 0.8125rem);
3-
--font-size-14: clamp(0.8125rem, 0.79rem + 0.12vw, 0.875rem);
4-
--font-size-16: clamp(0.9375rem, 0.9rem + 0.22vw, 1rem);
5-
--font-size-20: clamp(1.125rem, 1.03rem + 0.36vw, 1.375rem);
6-
--font-size-24: clamp(1.5rem, 1.28rem + 0.72vw, 2rem);
7-
--font-size-32: clamp(2rem, 1.7rem + 1.2vw, 3rem);
2+
--font-size-12: 0.75rem;
3+
--font-size-14: 0.875rem;
4+
--font-size-16: 1rem;
5+
--font-size-20: 1.25rem;
6+
--font-size-24: 1.5rem;
7+
--font-size-32: 2rem;
88
--font-weight-medium: 500;
9-
--font-weight-semibold: 600;
109
--font-weight-bold: 700;
1110
--line-height-tight: 1.05;
1211
--line-height-snug: 1.2;
1312
--line-height-body: 1.5;
13+
--letter-spacing-label: 0.14em;
1414
}
1515

1616
strong {

app/components/FidgetSpinner.vue

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,10 @@
1919
.component {
2020
animation: spin 1s linear infinite;
2121
}
22+
23+
@media (prefers-reduced-motion: reduce) {
24+
.component {
25+
animation: none;
26+
}
27+
}
2228
</style>

app/components/IconTitle.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@
3535
display: flex;
3636
align-items: center;
3737
justify-content: center;
38-
width: 40px;
39-
height: 40px;
38+
inline-size: 2.5rem;
39+
block-size: 2.5rem;
4040
border-radius: var(--border-radius-12);
4141
background: var(--color-accent-subtle);
4242
color: var(--color-accent-base);

app/components/PageLoadingState.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929

3030
<style module>
3131
.component {
32-
min-height: min(60vh, 32rem);
32+
min-block-size: min(60vh, 32rem);
3333
display: grid;
3434
place-items: center;
3535
}
@@ -47,7 +47,7 @@
4747
4848
.text {
4949
margin: 0;
50-
max-width: 28rem;
50+
max-inline-size: 28rem;
5151
color: var(--color-text-tertiary);
5252
}
5353
</style>

app/components/PagePlaceholder.vue

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,12 @@
3636

3737
<style module>
3838
.component {
39-
width: 100%;
39+
inline-size: 100%;
4040
}
4141
4242
.card {
43-
width: 100%;
44-
max-width: 42rem;
43+
inline-size: 100%;
44+
max-inline-size: 42rem;
4545
box-sizing: border-box;
4646
margin: 0 auto;
4747
background:
@@ -63,7 +63,7 @@
6363
6464
.content {
6565
margin: 0;
66-
max-width: 32rem;
66+
max-inline-size: 32rem;
6767
color: var(--color-text-tertiary);
6868
line-height: var(--line-height-body);
6969
}

app/components/PerdButton.vue

Lines changed: 33 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,9 @@
33
:type="type"
44
:disabled="isButtonDisabled"
55
:aria-busy="ariaBusy"
6-
:class="[$style.button, {
6+
:class="[$style.component, {
77
small: isSmallSize,
8-
iconOnly: isIconOnlySize,
9-
iconSmall: isIconSmallSize,
108
secondary: isSecondaryVariant,
11-
ghost: isGhostVariant,
129
danger: isDangerVariant
1310
}]"
1411
>
@@ -42,9 +39,9 @@
4239
icon?: string;
4340
iconRight?: string;
4441
loading?: boolean;
45-
size?: 'medium' | 'small' | 'icon-only' | 'icon-small';
42+
size?: 'medium' | 'small';
4643
type?: 'button' | 'reset' | 'submit';
47-
variant?: 'primary' | 'secondary' | 'ghost' | 'danger';
44+
variant?: 'primary' | 'secondary' | 'danger';
4845
}
4946
5047
const {
@@ -59,30 +56,28 @@
5956
const ariaBusy = computed(() => loading || undefined)
6057
const isButtonDisabled = computed(() => disabled || loading)
6158
const isSmallSize = computed(() => size === 'small')
62-
const isIconOnlySize = computed(() => size === 'icon-only')
63-
const isIconSmallSize = computed(() => size === 'icon-small')
6459
const isSecondaryVariant = computed(() => variant === 'secondary')
65-
const isGhostVariant = computed(() => variant === 'ghost')
6660
const isDangerVariant = computed(() => variant === 'danger')
6761
const rightIconName = computed(() => iconRight ?? '')
6862
const showRightIcon = computed(() => iconRight !== undefined && iconRight !== '' && loading === false)
6963
</script>
7064

7165
<style module>
72-
.button {
66+
.component {
7367
appearance: none;
7468
border: 1px solid transparent;
7569
cursor: pointer;
7670
display: inline-flex;
7771
align-items: center;
7872
justify-content: center;
7973
gap: var(--spacing-8);
80-
height: 2.5rem;
81-
padding: 0 var(--spacing-16);
74+
block-size: 2.5rem;
75+
padding-inline: var(--spacing-16);
8276
border-radius: var(--border-radius-16);
8377
background: var(--color-accent-base);
8478
color: var(--color-accent-contrast);
85-
outline: none;
79+
outline: 2px solid transparent;
80+
outline-offset: 3px;
8681
user-select: none;
8782
white-space: nowrap;
8883
font-weight: var(--font-weight-medium);
@@ -93,62 +88,41 @@
9388
color var(--transition-duration-quick) var(--transition-easing-out),
9489
transform var(--transition-duration-quick) var(--transition-easing-out);
9590
96-
&:focus-visible,
9791
&:hover {
9892
background: var(--color-accent-hover);
9993
}
10094
95+
&:focus-visible {
96+
background: var(--color-accent-hover);
97+
outline-color: var(--color-accent-ring);
98+
}
99+
101100
&:active {
102101
transform: translateY(1px);
103102
background: var(--color-accent-active);
104103
}
105104
106105
&:global(.small) {
107-
height: 2rem;
108-
padding: 0 var(--spacing-12);
106+
block-size: 2rem;
107+
padding-inline: var(--spacing-12);
109108
border-radius: var(--border-radius-12);
110109
font-size: var(--font-size-12);
111110
}
112111
113-
&:global(.iconOnly),
114-
&:global(.iconSmall) {
115-
padding: 0;
116-
}
117-
118-
&:global(.iconOnly) {
119-
width: 2.5rem;
120-
}
121-
122-
&:global(.iconSmall) {
123-
width: 2rem;
124-
height: 2rem;
125-
border-radius: var(--border-radius-12);
126-
}
127-
128112
&:global(.secondary) {
129113
background: var(--color-surface-base);
130114
color: var(--color-text-primary);
131115
border-color: var(--color-border-default);
132116
133-
&:focus-visible,
134117
&:hover {
135118
background: var(--color-surface-subtle);
136119
border-color: var(--color-border-default);
137120
color: var(--color-text-primary);
138121
}
139122
140-
&:active {
141-
transform: translateY(1px);
142-
}
143-
}
144-
145-
&:global(.ghost) {
146-
background: transparent;
147-
color: var(--color-text-secondary);
148-
149-
&:focus-visible,
150-
&:hover {
123+
&:focus-visible {
151124
background: var(--color-surface-subtle);
125+
border-color: var(--color-border-default);
152126
color: var(--color-text-primary);
153127
}
154128
@@ -162,30 +136,41 @@
162136
color: var(--color-danger);
163137
border-color: color-mix(in oklch, var(--color-danger), transparent 76%);
164138
165-
&:focus-visible,
166139
&:hover {
167140
background: color-mix(in oklch, var(--color-danger), transparent 90%);
168141
}
169142
143+
&:focus-visible {
144+
background: color-mix(in oklch, var(--color-danger), transparent 90%);
145+
outline-color: color-mix(in oklch, var(--color-danger), transparent 48%);
146+
}
147+
170148
&:active {
171149
transform: translateY(1px);
172150
}
173151
}
174152
}
175153
176-
.button:disabled,
177-
.button:disabled:focus-visible,
178-
.button:disabled:hover,
179-
.button:disabled:active {
154+
.component:disabled,
155+
.component:disabled:focus-visible,
156+
.component:disabled:hover,
157+
.component:disabled:active {
180158
cursor: not-allowed;
181159
transform: none;
182160
color: var(--color-text-muted);
183161
background: var(--color-surface-subtle);
184162
border-color: transparent;
163+
outline-color: transparent;
185164
}
186165
187166
.icon {
188167
font-size: 1.05em;
189168
flex-shrink: 0;
190169
}
170+
171+
@media (prefers-reduced-motion: reduce) {
172+
.component:active {
173+
transform: none;
174+
}
175+
}
191176
</style>

app/components/PerdCard.vue

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,8 @@
77
<style module>
88
.component {
99
background: var(--color-surface-base);
10-
border-radius: var(--border-radius-24);
10+
border-radius: var(--border-radius-16);
1111
padding: var(--spacing-24);
1212
border: 1px solid var(--color-border-subtle);
13-
box-shadow: var(--shadow-1);
1413
}
1514
</style>

app/components/PerdHeading.vue

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,34 @@
11
<template>
22
<component
33
:is="tag"
4-
:class="headingClass"
4+
:class="[$style.component, headingLevelClass]"
55
>
66
<slot />
77
</component>
88
</template>
99

1010
<script lang="ts">
11-
export type HeadingLevel = 1 | 2 | 3
11+
export type HeadingLevel = 1 | 2
1212
</script>
1313
1414
<script lang="ts" setup>
15-
import { computed, useCssModule } from 'vue'
15+
import { computed } from 'vue'
1616
1717
interface Props {
1818
level: HeadingLevel;
1919
}
2020
2121
const { level } = defineProps<Props>()
22-
const styles = useCssModule()
2322
2423
const tag = computed(() => `h${level}` as const)
25-
const headingClass = computed(() => [styles.component, tag.value])
24+
const headingLevelClass = computed(() => tag.value)
2625
</script>
2726

2827
<style module>
2928
.component {
3029
padding: 0;
3130
margin: 0;
32-
letter-spacing: -0.03em;
31+
letter-spacing: 0;
3332
color: var(--color-text-primary);
3433
3534
&:global(.h1) {
@@ -43,11 +42,5 @@
4342
font-weight: var(--font-weight-bold);
4443
line-height: var(--line-height-snug);
4544
}
46-
47-
&:global(.h3) {
48-
font-size: var(--font-size-16);
49-
font-weight: var(--font-weight-semibold);
50-
line-height: var(--line-height-snug);
51-
}
5245
}
5346
</style>

0 commit comments

Comments
 (0)