Restyle approval buttons to match Stella Ops design system

Replace custom apc__btn classes with standard btn/btn-primary/btn-secondary/
btn-danger classes using design tokens (--color-brand-primary, --color-border-primary,
--color-severity-high, etc.).

Pending lane cards:
- Approve: btn-primary (amber fill)
- Reject: btn-danger (red outline)
- View: btn-secondary (neutral outline)

Approvals table:
- Same button classes with btn--sm size variant
- Policy link: btn-secondary
- Row actions in flex container with gap

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
master
2026-03-28 20:43:34 +02:00
parent 11c92ed436
commit 0998c89616

View File

@@ -102,9 +102,9 @@ function deriveOutcomeIcon(status: string): string {
<span class="apc__exp" [class.text-warning]="isExpiringSoon(apr.expiresAt)">{{ timeRemaining(apr.expiresAt) }}</span>
</div>
<div class="apc__btns">
<button class="apc__btn apc__btn--approve" (click)="onApprove(apr)" type="button">Approve</button>
<button class="apc__btn apc__btn--reject" (click)="onReject(apr)" type="button">Reject</button>
<button class="apc__btn apc__btn--view" (click)="onView(apr)" type="button">View</button>
<button class="btn btn-primary btn--sm" (click)="onApprove(apr)" type="button">Approve</button>
<button class="btn btn-danger btn--sm" (click)="onReject(apr)" type="button">Reject</button>
<button class="btn btn-secondary btn--sm" (click)="onView(apr)" type="button">View</button>
</div>
</div>
}
@@ -251,13 +251,13 @@ function deriveOutcomeIcon(status: string): string {
<td>
<div class="row-actions">
@if (apr.status === 'pending') {
<button class="apc__btn apc__btn--approve" (click)="onApprove(apr)" type="button">Approve</button>
<button class="apc__btn apc__btn--reject" (click)="onReject(apr)" type="button">Reject</button>
<button class="btn btn-primary btn--sm" (click)="onApprove(apr)" type="button">Approve</button>
<button class="btn btn-danger btn--sm" (click)="onReject(apr)" type="button">Reject</button>
}
@if (!apr.gatesPassed) {
<a class="apc__btn apc__btn--view" routerLink="/ops/policy/packs">Policy</a>
<a class="btn btn-secondary btn--sm" routerLink="/ops/policy/packs">Policy</a>
}
<button class="apc__btn apc__btn--view" (click)="onView(apr)" type="button">View</button>
<button class="btn btn-secondary btn--sm" (click)="onView(apr)" type="button">View</button>
</div>
</td>
</tr>
@@ -436,11 +436,19 @@ function deriveOutcomeIcon(status: string): string {
.empty-state{text-align:center;padding:2.5rem;color:var(--color-text-muted);border:1px dashed var(--color-border-primary);border-radius:var(--radius-lg);margin-top:.5rem}
.apc__btns{display:flex;border-top:1px solid var(--color-border-primary)}
.apc__btn{flex:1;padding:.4rem 0;font-size:.72rem;font-weight:500;border:none;cursor:pointer;transition:background 150ms ease;background:transparent;color:var(--color-text-secondary)}
.apc__btn:not(:last-child){border-right:1px solid var(--color-border-primary)}
.apc__btn--approve:hover{background:color-mix(in srgb,var(--color-status-success) 12%,transparent);color:var(--color-status-success)}
.apc__btn--reject:hover{background:color-mix(in srgb,var(--color-status-error) 12%,transparent);color:var(--color-status-error)}
.apc__btn--view:hover{background:var(--color-surface-tertiary);color:var(--color-text-primary)}
.apc__btns .btn{flex:1;justify-content:center;border-radius:0;border:none;border-right:1px solid var(--color-border-primary)}
.apc__btns .btn:last-child{border-right:none}
.row-actions{display:flex;gap:0.375rem;align-items:center;flex-wrap:wrap}
.btn{display:inline-flex;align-items:center;gap:0.375rem;padding:0.375rem 0.75rem;border:1px solid transparent;border-radius:var(--radius-sm);font-size:0.75rem;font-weight:500;cursor:pointer;transition:background 120ms ease, border-color 120ms ease, box-shadow 120ms ease;text-decoration:none;line-height:1.4}
.btn:focus-visible{outline:2px solid var(--color-brand-primary);outline-offset:2px}
.btn:disabled{opacity:0.45;cursor:not-allowed}
.btn--sm{padding:0.25rem 0.5rem;font-size:0.6875rem}
.btn-primary{background:var(--color-brand-primary);color:#fff;border-color:var(--color-brand-primary)}
.btn-primary:hover:not(:disabled){background:var(--color-brand-primary-hover, #e09520);box-shadow:0 1px 3px rgba(0,0,0,0.12)}
.btn-secondary{background:var(--color-surface-elevated, #fff);color:var(--color-text-secondary);border-color:var(--color-border-primary)}
.btn-secondary:hover:not(:disabled){background:var(--color-surface-secondary);border-color:var(--color-text-muted)}
.btn-danger{background:transparent;color:var(--color-severity-high);border-color:var(--color-severity-high)}
.btn-danger:hover:not(:disabled){background:color-mix(in srgb,var(--color-severity-high) 10%,transparent)}
/* ─── Dialogs ─── */
.dlg-overlay{position:fixed;inset:0;z-index:1100;display:flex;align-items:center;justify-content:center;padding:1rem;background:rgba(0,0,0,.5);backdrop-filter:blur(2px)}