Remove redundant headers from pack detail tabs, fix button theming

All 7 pack detail components (dashboard, editor, rule-builder, yaml,
simulation, approvals, explain) had their own eyebrow + h1 + lede
headers that duplicated the parent pack-shell's dynamic title+subtitle.

Changes per component:
- Dashboard: removed header, added empty state with guidance, themed btns
- Editor: removed header, kept metadata as right-aligned flex, themed btns
- YAML: removed header, fixed label colors and button theming
- Rule builder: removed header, fixed label colors
- Simulation: removed header, kept status pill, themed btns from gradient
  to btn-primary-bg, fixed hardcoded rgba colors
- Approvals: removed header, kept workflow status badges, themed btns
- Explain: removed header, kept action links, added btn/btn--secondary CSS

Button theming: replaced var(--color-status-info-text) backgrounds
and hardcoded rgba() with var(--color-btn-primary-bg/border/text)
and var(--color-btn-secondary-bg/border/text) across all components.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
master
2026-03-29 16:03:44 +03:00
parent 01cc3f044f
commit a8ad459506
7 changed files with 122 additions and 258 deletions

View File

@@ -22,33 +22,24 @@ import { PolicyApiService } from '../services/policy-api.service';
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<section class="approvals" [attr.aria-busy]="loading">
<header class="approvals__header">
<div>
<p class="approvals__eyebrow">Policy Studio · Approvals</p>
<h1>Submit, review, approve</h1>
<p class="approvals__lede">
Two-person approval with deterministic audit trail and scoped activation windows.
</p>
@if (workflow) {
<div class="approvals__actions">
<span class="pill" [class.pill--approved]="workflow.status === 'approved'" [class.pill--pending]="workflow.status !== 'approved'">
{{ workflow.status | titlecase }}
</span>
<span class="approvals__count">Required approvers: {{ workflow.requiredApprovers }}</span>
<span class="approvals__count">Current: {{ workflow.currentApprovers }}</span>
<span class="approvals__badge" [class.approvals__badge--ready]="isReadyToApprove" [class.approvals__badge--missing]="!isReadyToApprove">
Two-person rule: {{ isReadyToApprove ? 'Satisfied' : 'Missing second approver' }}
</span>
<span class="approvals__badge" [class.approvals__badge--ready]="pendingChecklist === 0" [class.approvals__badge--missing]="pendingChecklist > 0">
Checklist: {{ pendingChecklist === 0 ? 'Ready' : pendingChecklist + ' open item' + (pendingChecklist === 1 ? '' : 's') }}
</span>
<span class="approvals__badge" [class.approvals__badge--ready]="scheduleSummary !== 'Unscheduled'" [class.approvals__badge--missing]="scheduleSummary === 'Unscheduled'">
Schedule: {{ scheduleSummary }}
</span>
</div>
@if (workflow) {
<div class="approvals__meta">
<span class="pill" [class.pill--approved]="workflow.status === 'approved'" [class.pill--pending]="workflow.status !== 'approved'">
{{ workflow.status | titlecase }}
</span>
<span class="approvals__count">Required approvers: {{ workflow.requiredApprovers }}</span>
<span class="approvals__count">Current: {{ workflow.currentApprovers }}</span>
<span class="approvals__badge" [class.approvals__badge--ready]="isReadyToApprove" [class.approvals__badge--missing]="!isReadyToApprove">
Two-person rule: {{ isReadyToApprove ? 'Satisfied' : 'Missing second approver' }}
</span>
<span class="approvals__badge" [class.approvals__badge--ready]="pendingChecklist === 0" [class.approvals__badge--missing]="pendingChecklist > 0">
Checklist: {{ pendingChecklist === 0 ? 'Ready' : pendingChecklist + ' open item' + (pendingChecklist === 1 ? '' : 's') }}
</span>
<span class="approvals__badge" [class.approvals__badge--ready]="scheduleSummary !== 'Unscheduled'" [class.approvals__badge--missing]="scheduleSummary === 'Unscheduled'">
Schedule: {{ scheduleSummary }}
</span>
</div>
}
</header>
}
@if (workflow) {
<div class="approvals__grid">
@@ -225,30 +216,13 @@ import { PolicyApiService } from '../services/policy-api.service';
gap: 1rem;
}
.approvals__header {
.approvals__actions {
display: flex;
justify-content: space-between;
gap: 1rem;
align-items: flex-start;
}
.approvals__eyebrow {
margin: 0;
color: var(--color-brand-muted);
text-transform: uppercase;
letter-spacing: 0.05em;
font-size: 0.8rem;
}
.approvals__lede {
margin: 0.2rem 0 0;
color: var(--color-text-secondary);
}
.approvals__meta {
display: grid;
justify-items: end;
gap: 0.3rem;
justify-content: flex-end;
gap: 0.5rem;
margin-bottom: 1rem;
flex-wrap: wrap;
align-items: center;
}
.pill {
@@ -334,16 +308,16 @@ import { PolicyApiService } from '../services/policy-api.service';
}
.btn {
background: var(--color-status-info-text);
border: 1px solid var(--color-status-info-text);
color: var(--color-text-primary);
background: var(--color-btn-primary-bg);
border: 1px solid var(--color-btn-primary-border);
color: var(--color-btn-primary-text);
border-radius: var(--radius-xl);
padding: 0.55rem 0.9rem;
font-weight: var(--font-weight-bold);
cursor: pointer;
}
.btn:hover { background: var(--color-status-info-text); }
.btn:hover { opacity: 0.9; }
.btn:disabled { opacity: 0.6; cursor: not-allowed; }
@@ -469,7 +443,7 @@ import { PolicyApiService } from '../services/policy-api.service';
.schedule__summary { display: flex; flex-direction: column; gap: 0.15rem; color: var(--color-text-secondary); }
@media (max-width: 960px) { .approvals__header { flex-direction: column; } }
@media (max-width: 960px) { .approvals__actions { justify-content: flex-start; } }
`,
]
})

View File

@@ -18,20 +18,20 @@ import {
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<section class="dash" [attr.aria-busy]="loading">
<header class="dash__header">
<div>
<p class="dash__eyebrow">Policy Studio · Runs</p>
<h1>Run dashboards</h1>
<p class="dash__lede">Heatmap, VEX wins, and suppressions; deterministic ordering.</p>
@if (dashboard) {
<div class="dash__actions">
<span class="pill">Runs: {{ dashboard.runs.length }}</span>
<span class="pill">Rules: {{ dashboard.ruleHeatmap.length }}</span>
</div>
@if (dashboard) {
<div class="dash__meta">
<span class="pill">Runs: {{ dashboard.runs.length }}</span>
<span class="pill">Rules: {{ dashboard.ruleHeatmap.length }}</span>
</div>
}
</header>
}
@if (!loading && !dashboard) {
<div class="dash__empty">
<p class="dash__empty-title">No run data available</p>
<p class="dash__empty-hint">Run a policy evaluation to see dashboards, heatmaps, and daily deltas here.</p>
</div>
}
@if (dashboard) {
<div class="dash__grid">
<div class="card">
@@ -105,12 +105,12 @@ import {
`,
styles: [
`
:host { display: block; background: var(--color-surface-primary); color: var(--color-text-primary); ; }
:host { display: block; background: var(--color-surface-primary); color: var(--color-text-primary); }
.dash { max-width: 1200px; margin: 0 auto; padding: 1.5rem; }
.dash__header { display: flex; justify-content: space-between; align-items: flex-start; gap: 1rem; }
.dash__eyebrow { margin: 0; color: var(--color-status-info); text-transform: uppercase; letter-spacing: 0.05em; font-size: 0.8rem; }
.dash__lede { margin: 0.2rem 0 0; color: var(--color-text-muted); }
.dash__meta { display: flex; gap: 0.5rem; flex-wrap: wrap; }
.dash__actions { display: flex; justify-content: flex-end; gap: 0.5rem; margin-bottom: 1rem; flex-wrap: wrap; }
.dash__empty { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 3rem 1.5rem; border: 1px dashed var(--color-border-primary); border-radius: var(--radius-xl); background: var(--color-surface-elevated); text-align: center; }
.dash__empty-title { margin: 0; font-size: 1.1rem; font-weight: var(--font-weight-semibold); color: var(--color-text-primary); }
.dash__empty-hint { margin: 0.5rem 0 0; color: var(--color-text-muted); font-size: 0.9rem; max-width: 420px; }
.pill { border: 1px solid var(--color-border-primary); padding: 0.35rem 0.7rem; border-radius: var(--radius-full); }
.dash__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 1rem; margin-top: 1rem; }
.card { background: var(--color-surface-elevated); border: 1px solid var(--color-border-primary); border-radius: var(--radius-xl); padding: 1rem; box-shadow: 0 10px 30px rgba(0,0,0,0.25); }
@@ -124,11 +124,15 @@ import {
.heatmap__name { color: var(--color-text-primary); font-weight: var(--font-weight-semibold); }
.heatmap__bar { display: flex; align-items: center; gap: 0.4rem; background: var(--color-surface-elevated); border-radius: var(--radius-full); overflow: hidden; padding: 0.2rem; }
.heatmap__fill { display: block; height: 10px; background: linear-gradient(90deg, var(--color-status-info), var(--color-status-info-text)); border-radius: var(--radius-full); }
.heatmap__value { color: rgba(212, 201, 168, 0.5); font-size: 0.85rem; }
.heatmap__value { color: var(--color-text-muted); font-size: 0.85rem; }
.heatmap__latency { color: var(--color-text-muted); font-size: 0.85rem; }
.chips { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.5rem; }
.chip { border: 1px solid var(--color-border-primary); border-radius: var(--radius-full); padding: 0.25rem 0.6rem; background: var(--color-surface-primary); }
.chip--muted { opacity: 0.8; }
.btn { background: var(--color-btn-primary-bg); border: 1px solid var(--color-btn-primary-border); color: var(--color-btn-primary-text); border-radius: var(--radius-lg); padding: 0.4rem 0.8rem; cursor: pointer; font-weight: var(--font-weight-semibold); }
.btn:hover { opacity: 0.9; }
.btn:disabled { opacity: 0.6; cursor: not-allowed; }
.btn--ghost { background: transparent; color: var(--color-text-secondary); border: 1px solid var(--color-border-primary); }
`,
]
})

View File

@@ -45,35 +45,23 @@ interface ChecklistItem {
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<section class="policy-editor" [attr.aria-busy]="loadingPack">
<header class="policy-editor__header">
<div class="policy-editor__title">
<p class="policy-editor__eyebrow">Policy Studio · Authoring</p>
<h1>{{ pack?.name || 'Loading policy…' }}</h1>
@if (pack) {
<p class="policy-editor__subtitle">
Version {{ pack.version }} · Status: {{ pack.status | titlecase }} ·
Digest: {{ pack.digest || 'pending' }}
</p>
}
</div>
@if (pack) {
<div class="policy-editor__meta">
<div class="policy-editor__meta-item">
<span class="policy-editor__meta-label">Updated</span>
<span>{{ pack.modifiedAt | date: 'medium' }}</span>
</div>
<div class="policy-editor__meta-item">
<span class="policy-editor__meta-label">Authors</span>
<span>{{ pack.metadata?.author || pack.createdBy }}</span>
</div>
<div class="policy-editor__meta-item">
<span class="policy-editor__meta-label">Tags</span>
<span>{{ pack.tags?.length || 0 }}</span>
</div>
@if (pack) {
<div class="policy-editor__meta">
<div class="policy-editor__meta-item">
<span class="policy-editor__meta-label">Updated</span>
<span>{{ pack.modifiedAt | date: 'medium' }}</span>
</div>
}
</header>
<div class="policy-editor__meta-item">
<span class="policy-editor__meta-label">Authors</span>
<span>{{ pack.metadata?.author || pack.createdBy }}</span>
</div>
<div class="policy-editor__meta-item">
<span class="policy-editor__meta-label">Tags</span>
<span>{{ pack.tags?.length || 0 }}</span>
</div>
</div>
}
<div class="policy-editor__layout">
<section class="policy-editor__main" aria-label="Policy editor">
<div class="editor-shell" [class.editor-shell--loading]="loadingEditor">
@@ -201,40 +189,12 @@ interface ChecklistItem {
padding: 1.5rem;
}
.policy-editor__header {
display: flex;
justify-content: space-between;
gap: 1.5rem;
align-items: flex-start;
margin-bottom: 1.25rem;
}
.policy-editor__title h1 {
margin: 0.1rem 0;
font-size: 1.8rem;
font-weight: var(--font-weight-bold);
color: var(--color-text-inverse);
}
.policy-editor__eyebrow {
margin: 0;
color: var(--color-status-info-border);
letter-spacing: 0.05em;
text-transform: uppercase;
font-size: 0.75rem;
}
.policy-editor__subtitle {
margin: 0;
color: var(--color-text-muted);
font-size: 0.95rem;
}
.policy-editor__meta {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
display: flex;
gap: 0.75rem;
min-width: 320px;
justify-content: flex-end;
flex-wrap: wrap;
margin-bottom: 1rem;
}
.policy-editor__meta-item {
@@ -334,9 +294,9 @@ interface ChecklistItem {
}
.btn {
border: 1px solid var(--color-status-info-text);
background: var(--color-status-info-text);
color: var(--color-text-primary);
border: 1px solid var(--color-btn-primary-border);
background: var(--color-btn-primary-bg);
color: var(--color-btn-primary-text);
border-radius: var(--radius-lg);
padding: 0.55rem 0.85rem;
font-weight: var(--font-weight-semibold);
@@ -345,8 +305,7 @@ interface ChecklistItem {
}
.btn:hover {
background: var(--color-status-info-text);
border-color: var(--color-status-info-text);
opacity: 0.9;
}
.btn:disabled {
@@ -356,6 +315,7 @@ interface ChecklistItem {
.btn--ghost {
background: transparent;
color: var(--color-text-secondary);
border-color: var(--color-border-primary);
}

View File

@@ -13,24 +13,17 @@ import jsPDF from './jspdf.stub';
template: `
<section class="expl" [attr.aria-busy]="loading">
@if (result) {
<header class="expl__header">
<div>
<p class="expl__eyebrow">Policy Studio &middot; Explain</p>
<h1>Run {{ result.runId }}</h1>
<p class="expl__lede">Policy {{ result.policyId }} &middot; Version {{ result.policyVersion }}</p>
</div>
<div class="expl__meta">
<a
routerLink="/triage/audit-bundles/new"
[queryParams]="{ runId: result.runId, policyId: result.policyId }"
class="expl__btn"
>
Create immutable audit bundle
</a>
<button type="button" (click)="exportJson()">Export JSON</button>
<button type="button" (click)="exportPdf()">Export PDF</button>
</div>
</header>
<div class="expl__actions">
<a
routerLink="/triage/audit-bundles/new"
[queryParams]="{ runId: result.runId, policyId: result.policyId }"
class="expl__btn"
>
Create immutable audit bundle
</a>
<button type="button" class="btn btn--secondary" (click)="exportJson()">Export JSON</button>
<button type="button" class="btn btn--secondary" (click)="exportPdf()">Export PDF</button>
</div>
}
@if (result) {
@@ -73,14 +66,14 @@ import jsPDF from './jspdf.stub';
`,
styles: [
`
:host { display: block; background: var(--color-surface-elevated); color: var(--color-text-primary); ; }
:host { display: block; background: var(--color-surface-elevated); color: var(--color-text-primary); }
.expl { max-width: 1200px; margin: 0 auto; padding: 1.5rem; }
.expl__header { display: flex; justify-content: space-between; align-items: center; }
.expl__eyebrow { margin: 0; color: var(--color-status-info); text-transform: uppercase; letter-spacing: 0.05em; font-size: 0.8rem; }
.expl__lede { margin: 0.2rem 0 0; color: var(--color-text-muted); }
.expl__meta { display: flex; gap: 0.5rem; align-items: center; }
.expl__btn { display: inline-flex; align-items: center; border: 1px solid var(--color-border-primary); border-radius: var(--radius-lg); padding: 0.35rem 0.65rem; color: var(--color-text-primary); text-decoration: none; background: var(--color-surface-elevated); }
.expl__btn:hover { border-color: var(--color-status-info); }
.expl__actions { display: flex; justify-content: flex-end; gap: 0.5rem; margin-bottom: 1rem; align-items: center; }
.expl__btn { display: inline-flex; align-items: center; border: 1px solid var(--color-btn-secondary-border); border-radius: var(--radius-lg); padding: 0.35rem 0.65rem; color: var(--color-btn-secondary-text); text-decoration: none; background: var(--color-btn-secondary-bg); }
.expl__btn:hover { opacity: 0.9; }
.btn { background: var(--color-btn-primary-bg); border: 1px solid var(--color-btn-primary-border); color: var(--color-btn-primary-text); border-radius: var(--radius-lg); padding: 0.35rem 0.65rem; cursor: pointer; font-weight: var(--font-weight-semibold); }
.btn--secondary { background: var(--color-btn-secondary-bg); border-color: var(--color-btn-secondary-border); color: var(--color-btn-secondary-text); }
.btn:hover { opacity: 0.9; }
.expl__grid { display: grid; grid-template-columns: 2fr 1fr; gap: 1rem; margin-top: 1rem; }
.card { background: var(--color-surface-elevated); border: 1px solid var(--color-border-primary); border-radius: var(--radius-xl); padding: 1rem; }
ol { margin: 0.5rem 0 0; padding-left: 1.25rem; }

View File

@@ -9,17 +9,6 @@ import { ActivatedRoute } from '@angular/router';
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<section class="rb" [attr.aria-busy]="false">
<header class="rb__header">
<div>
<p class="rb__eyebrow">Policy Studio · Rule Builder</p>
<h1>Guided rule construction</h1>
<p class="rb__lede">Deterministic preview JSON updates as you edit.</p>
</div>
<div class="rb__meta">
<span>Pack: {{ packId }}</span>
</div>
</header>
<div class="rb__grid">
<form [formGroup]="form" class="rb__form">
<label>
@@ -72,14 +61,11 @@ import { ActivatedRoute } from '@angular/router';
`,
styles: [
`
:host { display: block; background: var(--color-surface-primary); color: var(--color-text-primary); ; }
:host { display: block; background: var(--color-surface-primary); color: var(--color-text-primary); }
.rb { max-width: 1200px; margin: 0 auto; padding: 1.5rem; }
.rb__header { display: flex; justify-content: space-between; gap: 1rem; }
.rb__eyebrow { margin: 0; color: var(--color-status-info); text-transform: uppercase; letter-spacing: 0.05em; font-size: 0.8rem; }
.rb__lede { margin: 0.2rem 0 0; color: var(--color-text-muted); }
.rb__grid { display: grid; grid-template-columns: minmax(0, 1.1fr) 1fr; gap: 1rem; margin-top: 1rem; }
.rb__grid { display: grid; grid-template-columns: minmax(0, 1.1fr) 1fr; gap: 1rem; }
.rb__form { background: var(--color-surface-elevated); border: 1px solid var(--color-border-primary); border-radius: var(--radius-xl); padding: 1rem; display: grid; gap: 0.65rem; }
label { display: grid; gap: 0.25rem; color: rgba(212, 201, 168, 0.5); }
label { display: grid; gap: 0.25rem; color: var(--color-text-secondary); }
input, select { background: var(--color-surface-primary); color: var(--color-text-primary); border: 1px solid var(--color-border-primary); border-radius: var(--radius-lg); padding: 0.5rem; }
.rb__preview { background: var(--color-surface-elevated); border: 1px solid var(--color-border-primary); border-radius: var(--radius-xl); padding: 1rem; }
pre { margin: 0; max-height: 420px; overflow: auto; background: var(--color-surface-primary); border: 1px solid var(--color-border-primary); border-radius: var(--radius-xl); padding: 0.75rem; }

View File

@@ -19,24 +19,15 @@ import { PolicyApiService } from '../services/policy-api.service';
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<section class="sim" [attr.aria-busy]="loading">
<header class="sim__header">
<div>
<p class="sim__eyebrow">Policy Studio · Simulation</p>
<h1>What-if analysis</h1>
<p class="sim__lede">
Run deterministic diffs against the active policy to preview impact before promote.
</p>
</div>
<div class="sim__meta">
<span class="pill" [class.pill--ok]="result?.status === 'completed'" [class.pill--warn]="result?.status === 'failed'">
{{ result ? result.status : 'Idle' | titlecase }}
</span>
@if (result) {
<span class="sim__timestamp">Completed at {{ result.executedAt | date:'medium' }}</span>
}
</div>
</header>
<div class="sim__actions">
<span class="pill" [class.pill--ok]="result?.status === 'completed'" [class.pill--warn]="result?.status === 'failed'">
{{ result ? result.status : 'Idle' | titlecase }}
</span>
@if (result) {
<span class="sim__timestamp">Completed at {{ result.executedAt | date:'medium' }}</span>
}
</div>
<div class="sim__layout">
<form class="sim__form" [formGroup]="form" (ngSubmit)="onRun()" aria-label="Simulation input">
<label class="field">
@@ -231,32 +222,12 @@ import { PolicyApiService } from '../services/policy-api.service';
padding: 1.5rem;
}
.sim__header {
.sim__actions {
display: flex;
justify-content: space-between;
gap: 1rem;
align-items: flex-start;
justify-content: flex-end;
gap: 0.5rem;
margin-bottom: 1rem;
}
.sim__eyebrow {
margin: 0;
color: var(--color-brand-muted);
font-size: 0.8rem;
letter-spacing: 0.05em;
text-transform: uppercase;
}
.sim__lede {
margin: 0.25rem 0 0;
color: rgba(212, 201, 168, 0.5);
}
.sim__meta {
display: flex;
flex-direction: column;
gap: 0.35rem;
align-items: flex-end;
align-items: center;
}
.pill {
@@ -300,7 +271,7 @@ import { PolicyApiService } from '../services/policy-api.service';
.field span {
display: block;
margin-bottom: 0.25rem;
color: rgba(212, 201, 168, 0.5);
color: var(--color-text-secondary);
font-weight: var(--font-weight-semibold);
}
@@ -322,20 +293,18 @@ import { PolicyApiService } from '../services/policy-api.service';
.btn {
justify-self: start;
background: linear-gradient(120deg, var(--color-status-info-text), var(--color-status-info));
border: 1px solid var(--color-status-info-text);
color: var(--color-text-inverse);
background: var(--color-btn-primary-bg);
border: 1px solid var(--color-btn-primary-border);
color: var(--color-btn-primary-text);
font-weight: var(--font-weight-bold);
padding: 0.6rem 1rem;
border-radius: var(--radius-xl);
cursor: pointer;
box-shadow: 0 10px 30px rgba(37, 99, 235, 0.25);
transition: transform 120ms ease, box-shadow 120ms ease;
transition: opacity 120ms ease;
}
.btn:hover {
transform: translateY(-1px);
box-shadow: 0 14px 36px rgba(37, 99, 235, 0.35);
opacity: 0.9;
}
.btn:disabled {
@@ -390,7 +359,7 @@ import { PolicyApiService } from '../services/policy-api.service';
.diff-grid h4 {
margin: 0 0 0.2rem;
color: rgba(212, 201, 168, 0.5);
color: var(--color-text-secondary);
}
.diff-grid ul {
@@ -441,7 +410,7 @@ import { PolicyApiService } from '../services/policy-api.service';
}
th {
color: rgba(212, 201, 168, 0.5);
color: var(--color-text-secondary);
position: sticky;
top: 0;
}

View File

@@ -19,24 +19,6 @@ interface YamlDiagnostic {
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<section class="yaml" [attr.aria-busy]="loading">
<header class="yaml__header">
<div>
<p class="yaml__eyebrow">Policy Studio · YAML</p>
<h1>{{ pack?.name || 'Loading policy…' }}</h1>
@if (pack) {
<p class="yaml__lede">
Version {{ pack.version }} · Status: {{ pack.status | titlecase }}
</p>
}
</div>
@if (pack) {
<div class="yaml__meta">
<span>Updated {{ pack.modifiedAt | date: 'medium' }}</span>
<span>Tags: {{ pack.tags.length }}</span>
</div>
}
</header>
<div class="yaml__layout">
<div class="yaml__editor">
<label for="yaml-input">YAML</label>
@@ -77,18 +59,14 @@ interface YamlDiagnostic {
`,
styles: [
`
:host { display: block; background: var(--color-surface-primary); color: var(--color-text-primary); ; }
:host { display: block; background: var(--color-surface-primary); color: var(--color-text-primary); }
.yaml { max-width: 1200px; margin: 0 auto; padding: 1.5rem; }
.yaml__header { display: flex; justify-content: space-between; gap: 1rem; }
.yaml__eyebrow { margin: 0; color: var(--color-status-info); text-transform: uppercase; letter-spacing: 0.05em; font-size: 0.8rem; }
.yaml__lede { margin: 0.2rem 0 0; color: var(--color-text-muted); }
.yaml__meta { display: grid; justify-items: end; gap: 0.2rem; color: var(--color-text-muted); }
.yaml__layout { display: grid; grid-template-columns: minmax(0, 1.4fr) 1fr; gap: 1rem; margin-top: 1rem; }
.yaml__layout { display: grid; grid-template-columns: minmax(0, 1.4fr) 1fr; gap: 1rem; }
.yaml__editor { background: var(--color-surface-elevated); border: 1px solid var(--color-border-primary); border-radius: var(--radius-xl); padding: 1rem; display: grid; gap: 0.5rem; }
label { color: rgba(212, 201, 168, 0.5); font-weight: var(--font-weight-semibold); }
label { color: var(--color-text-secondary); font-weight: var(--font-weight-semibold); }
textarea { width: 100%; background: var(--color-surface-primary); color: var(--color-text-primary); border: 1px solid var(--color-border-primary); border-radius: var(--radius-xl); padding: 0.75rem; font-family: 'Monaco','Consolas', monospace; }
.toolbar { display: flex; gap: 0.5rem; align-items: center; }
button { background: var(--color-btn-primary-bg); border: 1px solid var(--color-btn-primary-bg); color: var(--color-text-primary); border-radius: var(--radius-lg); padding: 0.4rem 0.8rem; cursor: pointer; }
button { background: var(--color-btn-primary-bg); border: 1px solid var(--color-btn-primary-border); color: var(--color-btn-primary-text); border-radius: var(--radius-lg); padding: 0.4rem 0.8rem; cursor: pointer; }
button:disabled { opacity: 0.6; cursor: not-allowed; }
.pill { border: 1px solid var(--color-border-primary); padding: 0.3rem 0.6rem; border-radius: var(--radius-full); }
.pill--ok { border-color: var(--color-status-success); color: var(--color-status-success); }