diff --git a/src/app/shared/ui/pagination/pagination.component.html b/src/app/shared/ui/pagination/pagination.component.html
index af7d941..d8f2a3c 100644
--- a/src/app/shared/ui/pagination/pagination.component.html
+++ b/src/app/shared/ui/pagination/pagination.component.html
@@ -6,7 +6,7 @@
[attr.aria-label]="previousLabel()"
(click)="goTo(currentPage() - 1)"
>
- «
+
@for (page of pages(); track $index) {
@@ -32,6 +32,6 @@
[attr.aria-label]="nextLabel()"
(click)="goTo(currentPage() + 1)"
>
- »
+
diff --git a/src/app/shared/ui/pagination/pagination.component.ts b/src/app/shared/ui/pagination/pagination.component.ts
index 97b9485..fa40b08 100644
--- a/src/app/shared/ui/pagination/pagination.component.ts
+++ b/src/app/shared/ui/pagination/pagination.component.ts
@@ -1,5 +1,6 @@
import { ChangeDetectionStrategy, Component, computed, input, output } from '@angular/core';
import { ButtonComponent } from '../button/button.component';
+import { IconComponent } from '../icon/icon.component';
const SIBLING_COUNT = 1;
const ELLIPSIS = '…' as const;
@@ -7,7 +8,7 @@ const ELLIPSIS = '…' as const;
@Component({
selector: 'app-pagination',
standalone: true,
- imports: [ButtonComponent],
+ imports: [ButtonComponent, IconComponent],
templateUrl: './pagination.component.html',
styleUrl: './pagination.component.scss',
changeDetection: ChangeDetectionStrategy.OnPush
diff --git a/src/app/shared/ui/select/select.component.html b/src/app/shared/ui/select/select.component.html
index c87e1b0..e852836 100644
--- a/src/app/shared/ui/select/select.component.html
+++ b/src/app/shared/ui/select/select.component.html
@@ -1,20 +1,23 @@
-
+
+
+
+
@if (activeDescription(); as description) {
{{ description }}
}
diff --git a/src/app/shared/ui/select/select.component.scss b/src/app/shared/ui/select/select.component.scss
index 451d9c2..30bfc13 100644
--- a/src/app/shared/ui/select/select.component.scss
+++ b/src/app/shared/ui/select/select.component.scss
@@ -7,8 +7,24 @@
width: 100%;
}
+.app-select-wrap {
+ position: relative;
+ width: 100%;
+}
+
+.app-select-arrow {
+ position: absolute;
+ right: 12px;
+ top: 50%;
+ transform: translateY(-50%);
+ color: var(--text-secondary, #6b7280);
+ pointer-events: none;
+}
+
.app-select {
width: 100%;
+ appearance: none;
+ padding-right: 36px;
border: 1px solid var(--border-color, #e4e4e7);
border-radius: var(--radius-md, 6px);
background: var(--bg-primary, #fff);
diff --git a/src/app/shared/ui/select/select.component.ts b/src/app/shared/ui/select/select.component.ts
index 672bff0..737ad92 100644
--- a/src/app/shared/ui/select/select.component.ts
+++ b/src/app/shared/ui/select/select.component.ts
@@ -1,6 +1,7 @@
import { ChangeDetectionStrategy, Component, forwardRef, inject, input } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { FormFieldContext } from '../form-field/form-field.component';
+import { IconComponent } from '../icon/icon.component';
export type SelectSize = 'sm' | 'md' | 'lg';
@@ -13,6 +14,7 @@ export interface SelectOption {
@Component({
selector: 'app-select',
standalone: true,
+ imports: [IconComponent],
templateUrl: './select.component.html',
styleUrl: './select.component.scss',
changeDetection: ChangeDetectionStrategy.OnPush,
diff --git a/src/styles.scss b/src/styles.scss
index 204299c..31fa29e 100644
--- a/src/styles.scss
+++ b/src/styles.scss
@@ -149,6 +149,46 @@ a, button, input, textarea, select {
animation: app-icon-spin 1s linear infinite;
}
+/* Consistent, animated expander chevron for every native /
+ disclosure in the app, replacing the browser's default triangle marker
+ (which renders differently per browser). Matches the Lucide ChevronDown
+ path used everywhere else via app-icon, so expanders use the same icon
+ family as the rest of the UI without touching every call site. */
+details > summary {
+ list-style: none;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 8px;
+
+ &::-webkit-details-marker {
+ display: none;
+ }
+
+ &::after {
+ content: '';
+ flex-shrink: 0;
+ width: 16px;
+ height: 16px;
+ background-color: currentColor;
+ mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
+ mask-repeat: no-repeat;
+ mask-position: center;
+ mask-size: contain;
+ transition: transform 0.2s ease;
+ }
+}
+
+details[open] > summary::after {
+ transform: rotate(180deg);
+}
+
+@media (prefers-reduced-motion: reduce) {
+ details > summary::after {
+ transition: none;
+ }
+}
+
/* Respect OS-level reduced-motion preference globally: neutralizes hover
transforms, card-entrance/skeleton-shimmer animations, and smooth-scroll
everywhere in one place rather than requiring every component to opt in