@reportforge/playwright-pdf 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/CHANGELOG.md +285 -0
  2. package/LICENSE +21 -0
  3. package/README.md +524 -0
  4. package/ci-templates/azure-devops/azure-pipelines.yml +58 -0
  5. package/ci-templates/bitbucket/bitbucket-pipelines.yml +42 -0
  6. package/ci-templates/github-actions/basic-workflow.yml +44 -0
  7. package/ci-templates/github-actions/matrix-workflow.yml +69 -0
  8. package/ci-templates/gitlab-ci/.gitlab-ci.yml +42 -0
  9. package/ci-templates/jenkins/Jenkinsfile +54 -0
  10. package/dist/index.d.mts +272 -0
  11. package/dist/index.d.ts +272 -0
  12. package/dist/index.js +12566 -0
  13. package/dist/index.mjs +12567 -0
  14. package/dist/templates/layouts/detailed.hbs +38 -0
  15. package/dist/templates/layouts/executive.hbs +35 -0
  16. package/dist/templates/layouts/minimal.hbs +29 -0
  17. package/dist/templates/partials/charts.hbs +306 -0
  18. package/dist/templates/partials/ci-environment.hbs +56 -0
  19. package/dist/templates/partials/cover-page.hbs +46 -0
  20. package/dist/templates/partials/defect-log.hbs +27 -0
  21. package/dist/templates/partials/executive-summary.hbs +60 -0
  22. package/dist/templates/partials/failure-deep-dive.hbs +61 -0
  23. package/dist/templates/partials/head.hbs +17 -0
  24. package/dist/templates/partials/release-gate.hbs +63 -0
  25. package/dist/templates/partials/requirements-matrix.hbs +35 -0
  26. package/dist/templates/partials/slow-tests.hbs +27 -0
  27. package/dist/templates/partials/suite-breakdown.hbs +58 -0
  28. package/dist/templates/partials/watermark.hbs +3 -0
  29. package/dist/templates/styles/base.css +234 -0
  30. package/dist/templates/styles/detailed.css +311 -0
  31. package/dist/templates/styles/executive.css +334 -0
  32. package/dist/templates/styles/minimal.css +208 -0
  33. package/package.json +99 -0
@@ -0,0 +1,311 @@
1
+ /* ── Detailed Template · Claude Design Language ─────────────────────────── */
2
+
3
+ /* ── Header ─────────────────────────────────────────────────────────────── */
4
+ .report-header {
5
+ display: flex; align-items: center; gap: 18px;
6
+ padding: 22px 26px;
7
+ background: var(--surface);
8
+ border: 1px solid var(--border-2);
9
+ border-radius: 6px;
10
+ margin-bottom: 22px;
11
+ position: relative;
12
+ overflow: hidden;
13
+ }
14
+ .report-header::before {
15
+ content: '';
16
+ position: absolute; top: 0; left: 0; right: 0; height: 3px;
17
+ background: var(--accent);
18
+ -webkit-print-color-adjust: exact;
19
+ print-color-adjust: exact;
20
+ }
21
+ .report-header__logo { height: 40px; width: auto; }
22
+ .report-header__title {
23
+ font-family: 'Source Serif Pro', Georgia, serif;
24
+ font-size: 22px; font-weight: 700;
25
+ color: var(--text-1); letter-spacing: -0.2px;
26
+ }
27
+ .report-header__meta {
28
+ font-size: 10px; color: var(--text-3); margin-top: 4px;
29
+ letter-spacing: 0.3px;
30
+ }
31
+
32
+ /* ── Verdict ─────────────────────────────────────────────────────────────── */
33
+ .verdict {
34
+ display: inline-flex; align-items: center; gap: 8px;
35
+ padding: 5px 16px; border-radius: 4px;
36
+ font-family: 'Inter', system-ui, sans-serif; font-weight: 600; font-size: 10px;
37
+ letter-spacing: 1px; text-transform: uppercase; margin-bottom: 18px;
38
+ -webkit-print-color-adjust: exact;
39
+ print-color-adjust: exact;
40
+ }
41
+ .verdict--passed {
42
+ background: var(--pass-dim); color: var(--pass);
43
+ border: 1px solid #C5DBC9;
44
+ }
45
+ .verdict--failed {
46
+ background: var(--fail-dim); color: var(--fail);
47
+ border: 1px solid #E5C9BD;
48
+ }
49
+ .verdict--timedout {
50
+ background: var(--timeout-dim); color: var(--timeout);
51
+ border: 1px solid #E5D2A8;
52
+ }
53
+ .verdict--interrupted {
54
+ background: var(--surface-2); color: var(--text-2);
55
+ border: 1px solid var(--border-2);
56
+ }
57
+
58
+ /* ── KPI strip ───────────────────────────────────────────────────────────── */
59
+ .kpi-strip {
60
+ display: grid; grid-template-columns: repeat(5, 1fr);
61
+ gap: 10px; margin-bottom: 22px;
62
+ }
63
+ .kpi-card {
64
+ background: var(--surface);
65
+ border: 1px solid var(--border-2);
66
+ border-radius: 6px; padding: 16px 12px; text-align: center;
67
+ position: relative; overflow: hidden;
68
+ }
69
+ .kpi-card::before {
70
+ content: ''; position: absolute; top: 0; left: 0; right: 0; height: 3px;
71
+ -webkit-print-color-adjust: exact;
72
+ print-color-adjust: exact;
73
+ }
74
+ .kpi-card--total::before { background: var(--accent); }
75
+ .kpi-card--pass::before { background: var(--pass); }
76
+ .kpi-card--fail::before { background: var(--fail); }
77
+ .kpi-card--skip::before { background: var(--skip); }
78
+ .kpi-card--flaky::before { background: var(--flaky); }
79
+
80
+ .kpi-card__value {
81
+ font-family: 'Source Serif Pro', Georgia, serif;
82
+ font-size: 30px; font-weight: 700; line-height: 1;
83
+ margin-top: 6px;
84
+ letter-spacing: -0.5px;
85
+ color: var(--text-1);
86
+ }
87
+ .kpi-card--total .kpi-card__value { color: var(--info); }
88
+ .kpi-card--pass .kpi-card__value { color: var(--pass); }
89
+ .kpi-card--fail .kpi-card__value { color: var(--fail); }
90
+ .kpi-card--skip .kpi-card__value { color: var(--skip); }
91
+ .kpi-card--flaky .kpi-card__value { color: var(--flaky); }
92
+
93
+ .kpi-card__label {
94
+ font-family: 'Inter', system-ui, sans-serif;
95
+ font-size: 8.5px; font-weight: 600; letter-spacing: 1.1px;
96
+ text-transform: uppercase; color: var(--text-3);
97
+ margin-top: 8px;
98
+ }
99
+ .kpi-card__rate {
100
+ font-size: 11px; font-weight: 600; color: var(--pass);
101
+ margin-top: 4px;
102
+ font-family: 'Inter', system-ui, sans-serif;
103
+ }
104
+
105
+ /* ── Summary row ─────────────────────────────────────────────────────────── */
106
+ .summary-row {
107
+ display: flex; gap: 0;
108
+ background: var(--surface); border: 1px solid var(--border-2);
109
+ border-radius: 6px; margin-bottom: 22px;
110
+ font-size: 10.5px; overflow: hidden;
111
+ }
112
+ .summary-row__item {
113
+ display: flex; flex-direction: column;
114
+ padding: 12px 18px;
115
+ border-right: 1px solid var(--border);
116
+ flex: 1;
117
+ }
118
+ .summary-row__item:last-child { border-right: none; }
119
+ .summary-row__label {
120
+ font-size: 8.5px; letter-spacing: 1.1px; text-transform: uppercase;
121
+ color: var(--text-3); font-weight: 600;
122
+ font-family: 'Inter', system-ui, sans-serif;
123
+ }
124
+ .summary-row__value {
125
+ font-weight: 600; color: var(--text-1);
126
+ margin-top: 4px; font-size: 12px;
127
+ }
128
+
129
+ /* ── Charts ─────────────────────────────────────────────────────────────── */
130
+ .charts-grid {
131
+ display: grid; grid-template-columns: 210px 1fr;
132
+ gap: 12px; margin-bottom: 24px;
133
+ }
134
+ .chart-card {
135
+ background: var(--surface);
136
+ border: 1px solid var(--border-2);
137
+ border-radius: 6px; padding: 16px 14px; text-align: center;
138
+ }
139
+ .chart-card h3 {
140
+ margin: 0 0 12px;
141
+ font-family: 'Inter', system-ui, sans-serif; font-size: 9px;
142
+ font-weight: 600; letter-spacing: 1.2px; text-transform: uppercase;
143
+ color: var(--text-3);
144
+ }
145
+
146
+ /* ── Suite breakdown ────────────────────────────────────────────────────── */
147
+ .suite-group {
148
+ background: var(--surface);
149
+ border: 1px solid var(--border-2);
150
+ border-radius: 6px; margin-bottom: 10px; overflow: hidden;
151
+ }
152
+ .suite-group__header {
153
+ padding: 10px 14px;
154
+ background: var(--surface-2);
155
+ border-bottom: 1px solid var(--border);
156
+ border-left: 3px solid var(--primary, #CC785C);
157
+ display: flex; justify-content: space-between; align-items: center;
158
+ }
159
+ .suite-title {
160
+ font-family: 'Inter', system-ui, sans-serif;
161
+ font-size: 11px; font-weight: 600; color: var(--text-1);
162
+ letter-spacing: 0.1px;
163
+ }
164
+ .suite-stats { display: flex; gap: 5px; }
165
+ .test-path {
166
+ font-family: 'JetBrains Mono', monospace;
167
+ font-size: 8.5px; color: var(--text-3); margin-top: 2px;
168
+ }
169
+
170
+ /* ── Failure item ────────────────────────────────────────────────────────── */
171
+ .failure-item {
172
+ background: var(--surface);
173
+ border: 1px solid var(--border-2);
174
+ border-left: 3px solid var(--fail);
175
+ border-radius: 6px; padding: 16px 18px;
176
+ margin-bottom: 12px; page-break-inside: avoid;
177
+ }
178
+ .failure-item__header {
179
+ display: flex; justify-content: space-between;
180
+ align-items: flex-start; margin-bottom: 10px;
181
+ }
182
+ .failure-item__title {
183
+ font-family: 'Inter', system-ui, sans-serif;
184
+ font-weight: 600; font-size: 12px; color: var(--text-1);
185
+ }
186
+ .failure-item__path {
187
+ font-family: 'JetBrains Mono', monospace;
188
+ font-size: 8.5px; color: var(--text-3); margin-bottom: 10px;
189
+ }
190
+ .failure-item__message {
191
+ background: var(--fail-dim);
192
+ border: 1px solid #E5C9BD;
193
+ border-left: 2px solid var(--fail);
194
+ border-radius: 4px; padding: 10px 14px; margin-bottom: 12px;
195
+ font-family: 'JetBrains Mono', monospace;
196
+ font-size: 9.5px; color: #8A2E1E;
197
+ word-break: break-word; line-height: 1.6;
198
+ }
199
+ .retry-history {
200
+ font-size: 9px; color: var(--text-3); margin-top: 10px;
201
+ padding-top: 10px; border-top: 1px solid var(--border);
202
+ font-family: 'Inter', system-ui, sans-serif; font-weight: 600;
203
+ letter-spacing: 0.5px; text-transform: uppercase;
204
+ }
205
+ .retry-attempt {
206
+ display: inline-block; padding: 2px 7px;
207
+ border-radius: 3px; margin-right: 4px;
208
+ font-size: 8.5px; font-family: 'Inter', system-ui, sans-serif; font-weight: 600;
209
+ -webkit-print-color-adjust: exact;
210
+ print-color-adjust: exact;
211
+ }
212
+ .retry-attempt--failed { background: var(--fail-dim); color: var(--fail); border: 1px solid #E5C9BD; }
213
+ .retry-attempt--passed { background: var(--pass-dim); color: var(--pass); border: 1px solid #C5DBC9; }
214
+
215
+ /* ── Defect log ─────────────────────────────────────────────────────────── */
216
+ .defect-id {
217
+ font-family: 'JetBrains Mono', monospace;
218
+ font-size: 9px; color: var(--accent);
219
+ background: var(--accent-soft);
220
+ padding: 2px 7px; border-radius: 3px;
221
+ border: 1px solid #E8C9BC;
222
+ font-weight: 500;
223
+ }
224
+
225
+ /* ── Coverage bar ────────────────────────────────────────────────────────── */
226
+ .coverage-bar {
227
+ height: 6px; border-radius: 3px;
228
+ background: var(--surface-3); overflow: hidden;
229
+ border: 1px solid var(--border);
230
+ }
231
+ .coverage-bar__fill {
232
+ height: 100%; border-radius: 3px;
233
+ background: var(--pass);
234
+ -webkit-print-color-adjust: exact;
235
+ print-color-adjust: exact;
236
+ }
237
+
238
+ /* ── Environment table ───────────────────────────────────────────────────── */
239
+ .env-table {
240
+ background: var(--surface);
241
+ border: 1px solid var(--border-2);
242
+ border-radius: 6px;
243
+ overflow: hidden;
244
+ }
245
+ .env-table td:first-child {
246
+ font-family: 'Inter', system-ui, sans-serif; font-weight: 600;
247
+ font-size: 9px; letter-spacing: 0.8px; text-transform: uppercase;
248
+ color: var(--text-2); width: 170px; white-space: nowrap;
249
+ background: var(--surface-2);
250
+ border-right: 1px solid var(--border);
251
+ }
252
+ .env-value {
253
+ font-family: 'JetBrains Mono', monospace;
254
+ font-size: 9.5px; color: var(--text-1);
255
+ }
256
+
257
+ /* ── History trend card ──────────────────────────────────────────────────── */
258
+ .trend-card {
259
+ background: var(--surface);
260
+ border: 1px solid var(--border-2);
261
+ border-radius: 6px;
262
+ padding: 16px 18px 14px;
263
+ margin-bottom: 24px;
264
+ page-break-inside: avoid;
265
+ }
266
+ .trend-card__header {
267
+ display: flex; align-items: center; justify-content: space-between;
268
+ margin-bottom: 14px;
269
+ }
270
+ .trend-card__title {
271
+ font-family: 'Inter', system-ui, sans-serif;
272
+ font-size: 9px; font-weight: 700;
273
+ letter-spacing: 1.2px; text-transform: uppercase;
274
+ color: var(--text-3);
275
+ }
276
+ .delta { font-size: 11px; font-weight: 700; }
277
+ .delta-up { color: var(--pass); }
278
+ .delta-down { color: var(--fail); }
279
+
280
+ /* ── Run history table (generated by JS) ─────────────────────────────────── */
281
+ .trend-run-history {
282
+ margin-top: 10px;
283
+ border-top: 1px solid var(--border);
284
+ padding-top: 8px;
285
+ }
286
+ .rh-item {
287
+ display: flex; align-items: center; gap: 12px;
288
+ padding: 5px 8px; border-radius: 4px;
289
+ font-size: 9px; font-family: 'Inter', system-ui, sans-serif;
290
+ }
291
+ .rh-item:nth-child(odd) {
292
+ background: var(--surface-2);
293
+ -webkit-print-color-adjust: exact; print-color-adjust: exact;
294
+ }
295
+ .rh-dot { flex-shrink: 0; }
296
+ .rh-date { color: var(--text-2); flex: 1; }
297
+ .rh-rate { font-weight: 700; min-width: 34px; color: var(--text-1); }
298
+ .rh-rate--pass { color: var(--pass); }
299
+ .rh-rate--fail { color: var(--fail); }
300
+ .rh-rate--partial { color: var(--flaky); }
301
+ .rh-tests { color: var(--text-3); min-width: 58px; }
302
+ .rh-dur { color: var(--text-3); }
303
+
304
+ /* ── Verdict dots (used in run history rh-dot) ───────────────────────────── */
305
+ .verdict-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }
306
+ .verdict-passed { background: var(--pass); -webkit-print-color-adjust: exact; print-color-adjust: exact; }
307
+ .verdict-partial { background: var(--flaky); -webkit-print-color-adjust: exact; print-color-adjust: exact; }
308
+ .verdict-failed { background: var(--fail); -webkit-print-color-adjust: exact; print-color-adjust: exact; }
309
+ .verdict-unknown { background: var(--skip); -webkit-print-color-adjust: exact; print-color-adjust: exact; }
310
+ </content>
311
+ </invoke>
@@ -0,0 +1,334 @@
1
+ /* ── Executive Template · Claude Design Language ────────────────────────── */
2
+
3
+ /* ── Cover page ─────────────────────────────────────────────────────────── */
4
+ .cover-page {
5
+ min-height: 100vh;
6
+ display: flex; flex-direction: column;
7
+ justify-content: center; align-items: center; text-align: center;
8
+ background: var(--bg);
9
+ padding: 60px 50px;
10
+ page-break-after: always;
11
+ position: relative;
12
+ }
13
+ .cover-page__logo {
14
+ height: 64px; width: auto; margin-bottom: 44px;
15
+ }
16
+ .cover-page__title {
17
+ font-family: 'Source Serif Pro', Georgia, serif;
18
+ font-size: 42px; font-weight: 700;
19
+ letter-spacing: -0.6px; color: var(--text-1);
20
+ margin-bottom: 12px; line-height: 1.1;
21
+ }
22
+ .cover-page__subtitle {
23
+ font-family: 'Inter', system-ui, sans-serif;
24
+ font-size: 12px; color: var(--text-2);
25
+ margin-bottom: 36px; font-weight: 500;
26
+ letter-spacing: 1.6px; text-transform: uppercase;
27
+ }
28
+ .cover-page__verdict {
29
+ display: inline-block;
30
+ padding: 10px 30px; border-radius: 6px;
31
+ font-family: 'Inter', system-ui, sans-serif; font-size: 13px;
32
+ font-weight: 600; letter-spacing: 1.4px;
33
+ text-transform: uppercase; margin-bottom: 40px;
34
+ -webkit-print-color-adjust: exact;
35
+ print-color-adjust: exact;
36
+ }
37
+ .cover-page__verdict--passed {
38
+ background: var(--pass-dim); color: var(--pass);
39
+ border: 1px solid #C5DBC9;
40
+ }
41
+ .cover-page__verdict--failed {
42
+ background: var(--fail-dim); color: var(--fail);
43
+ border: 1px solid #E5C9BD;
44
+ }
45
+ .cover-page__verdict--timedout {
46
+ background: var(--timeout-dim); color: var(--timeout);
47
+ border: 1px solid #E5D2A8;
48
+ }
49
+ .cover-page__verdict--interrupted {
50
+ background: var(--surface-2); color: var(--text-2);
51
+ border: 1px solid var(--border-2);
52
+ }
53
+
54
+ .cover-page__stats-strip {
55
+ display: flex; gap: 0;
56
+ border: 1px solid var(--border-2); border-radius: 6px;
57
+ overflow: hidden; margin-bottom: 36px;
58
+ background: var(--surface);
59
+ }
60
+ .cover-page__stat {
61
+ padding: 16px 26px; text-align: center;
62
+ border-right: 1px solid var(--border);
63
+ }
64
+ .cover-page__stat:last-child { border-right: none; }
65
+ .cover-page__stat-val {
66
+ font-family: 'Source Serif Pro', Georgia, serif; font-size: 26px;
67
+ font-weight: 700; color: var(--text-1);
68
+ letter-spacing: -0.4px;
69
+ }
70
+ .cover-page__stat-lbl {
71
+ font-family: 'Inter', system-ui, sans-serif; font-size: 8px;
72
+ font-weight: 600; letter-spacing: 1.3px;
73
+ text-transform: uppercase; color: var(--text-3);
74
+ margin-top: 6px;
75
+ }
76
+ .cover-page__meta {
77
+ font-family: 'Inter', system-ui, sans-serif;
78
+ font-size: 11px; color: var(--text-2);
79
+ line-height: 1.9; letter-spacing: 0.2px;
80
+ }
81
+ .cover-page__divider {
82
+ width: 64px; height: 2px;
83
+ background: var(--accent);
84
+ border-radius: 1px;
85
+ margin: 24px auto 28px;
86
+ -webkit-print-color-adjust: exact;
87
+ print-color-adjust: exact;
88
+ }
89
+
90
+ /* ── Header bar ─────────────────────────────────────────────────────────── */
91
+ .report-header {
92
+ background: var(--surface);
93
+ border: 1px solid var(--border-2);
94
+ border-radius: 6px; padding: 16px 22px; margin-bottom: 22px;
95
+ display: flex; align-items: center; justify-content: space-between;
96
+ position: relative; overflow: hidden;
97
+ }
98
+ .report-header::before {
99
+ content: '';
100
+ position: absolute; top: 0; left: 0; right: 0; height: 3px;
101
+ background: var(--accent);
102
+ -webkit-print-color-adjust: exact;
103
+ print-color-adjust: exact;
104
+ }
105
+ .report-header__left { display: flex; align-items: center; gap: 14px; }
106
+ .report-header__logo { height: 30px; }
107
+ .report-header__title {
108
+ font-family: 'Source Serif Pro', Georgia, serif;
109
+ font-size: 18px; font-weight: 700; color: var(--text-1);
110
+ letter-spacing: -0.2px;
111
+ }
112
+ .report-header__date {
113
+ font-size: 10px; color: var(--text-3);
114
+ font-family: 'Inter', system-ui, sans-serif;
115
+ font-weight: 500; letter-spacing: 0.4px;
116
+ }
117
+
118
+ /* ── KPI dashboard ─────────────────────────────────────────────────────── */
119
+ .kpi-strip {
120
+ display: grid; grid-template-columns: repeat(5, 1fr);
121
+ gap: 10px; margin-bottom: 22px;
122
+ }
123
+ .kpi-card {
124
+ background: var(--surface);
125
+ border: 1px solid var(--border-2);
126
+ border-radius: 6px; padding: 18px 12px; text-align: center;
127
+ position: relative; overflow: hidden;
128
+ }
129
+ .kpi-card::before {
130
+ content: ''; position: absolute; top: 0; left: 0; right: 0; height: 3px;
131
+ -webkit-print-color-adjust: exact;
132
+ print-color-adjust: exact;
133
+ }
134
+ .kpi-card--total::before { background: var(--accent); }
135
+ .kpi-card--pass::before { background: var(--pass); }
136
+ .kpi-card--fail::before { background: var(--fail); }
137
+ .kpi-card--skip::before { background: var(--skip); }
138
+ .kpi-card--flaky::before { background: var(--flaky); }
139
+
140
+ .kpi-card__value {
141
+ font-family: 'Source Serif Pro', Georgia, serif;
142
+ font-size: 32px; font-weight: 700; line-height: 1;
143
+ margin-top: 6px;
144
+ letter-spacing: -0.5px;
145
+ color: var(--text-1);
146
+ }
147
+ .kpi-card--total .kpi-card__value { color: var(--info); }
148
+ .kpi-card--pass .kpi-card__value { color: var(--pass); }
149
+ .kpi-card--fail .kpi-card__value { color: var(--fail); }
150
+ .kpi-card--skip .kpi-card__value { color: var(--skip); }
151
+ .kpi-card--flaky .kpi-card__value { color: var(--flaky); }
152
+ .kpi-card__label {
153
+ font-family: 'Inter', system-ui, sans-serif; font-size: 8px;
154
+ font-weight: 600; letter-spacing: 1.2px; text-transform: uppercase;
155
+ color: var(--text-3); margin-top: 8px;
156
+ }
157
+ .kpi-card__rate {
158
+ font-size: 12px; font-weight: 600; color: var(--pass);
159
+ margin-top: 5px;
160
+ font-family: 'Inter', system-ui, sans-serif;
161
+ }
162
+
163
+ /* ── Verdict badge ───────────────────────────────────────────────────────── */
164
+ .verdict {
165
+ display: inline-flex; align-items: center; gap: 8px;
166
+ padding: 6px 18px; border-radius: 4px;
167
+ font-family: 'Inter', system-ui, sans-serif; font-weight: 600; font-size: 11px;
168
+ letter-spacing: 1.1px; text-transform: uppercase;
169
+ margin-bottom: 18px;
170
+ -webkit-print-color-adjust: exact;
171
+ print-color-adjust: exact;
172
+ }
173
+ .verdict--passed {
174
+ background: var(--pass-dim); color: var(--pass);
175
+ border: 1px solid #C5DBC9;
176
+ }
177
+ .verdict--failed {
178
+ background: var(--fail-dim); color: var(--fail);
179
+ border: 1px solid #E5C9BD;
180
+ }
181
+ .verdict--timedout {
182
+ background: var(--timeout-dim); color: var(--timeout);
183
+ border: 1px solid #E5D2A8;
184
+ }
185
+ .verdict--interrupted {
186
+ background: var(--surface-2); color: var(--text-2);
187
+ border: 1px solid var(--border-2);
188
+ }
189
+
190
+ /* ── Summary row ─────────────────────────────────────────────────────────── */
191
+ .summary-row {
192
+ display: flex; gap: 0;
193
+ background: var(--surface); border: 1px solid var(--border-2);
194
+ border-radius: 6px; margin-bottom: 22px;
195
+ font-size: 10.5px; overflow: hidden;
196
+ }
197
+ .summary-row__item {
198
+ display: flex; flex-direction: column;
199
+ padding: 12px 18px;
200
+ border-right: 1px solid var(--border);
201
+ flex: 1;
202
+ }
203
+ .summary-row__item:last-child { border-right: none; }
204
+ .summary-row__label {
205
+ font-size: 8.5px; letter-spacing: 1.1px; text-transform: uppercase;
206
+ color: var(--text-3); font-weight: 600;
207
+ font-family: 'Inter', system-ui, sans-serif;
208
+ }
209
+ .summary-row__value { font-weight: 600; color: var(--text-1); margin-top: 4px; font-size: 12px; }
210
+
211
+ /* ── Charts ─────────────────────────────────────────────────────────────── */
212
+ .charts-grid {
213
+ display: grid; grid-template-columns: 218px 1fr;
214
+ gap: 12px; margin-bottom: 22px;
215
+ }
216
+ .chart-card {
217
+ background: var(--surface);
218
+ border: 1px solid var(--border-2);
219
+ border-radius: 6px; padding: 16px 14px; text-align: center;
220
+ }
221
+ .chart-card h3 {
222
+ margin: 0 0 12px;
223
+ font-family: 'Inter', system-ui, sans-serif; font-size: 9px;
224
+ font-weight: 600; letter-spacing: 1.3px; text-transform: uppercase;
225
+ color: var(--text-3);
226
+ }
227
+
228
+ /* ── Executive failure summary ───────────────────────────────────────────── */
229
+ .failure-summary-item {
230
+ display: flex; align-items: center; justify-content: space-between;
231
+ padding: 12px 16px;
232
+ border-bottom: 1px solid var(--border);
233
+ background: var(--surface);
234
+ border-left: 3px solid var(--fail);
235
+ }
236
+ .failure-summary-item:first-child {
237
+ border-radius: 6px 6px 0 0;
238
+ border-top: 1px solid var(--border-2);
239
+ border-right: 1px solid var(--border-2);
240
+ }
241
+ .failure-summary-item:last-child {
242
+ border-radius: 0 0 6px 6px;
243
+ border-bottom: 1px solid var(--border-2);
244
+ border-right: 1px solid var(--border-2);
245
+ }
246
+ .failure-summary-item:only-child {
247
+ border-radius: 6px;
248
+ border: 1px solid var(--border-2);
249
+ border-left: 3px solid var(--fail);
250
+ }
251
+ .failure-summary-item__title {
252
+ font-size: 11px; font-weight: 600; color: var(--text-1);
253
+ padding-left: 6px;
254
+ }
255
+ .failure-summary-item__suite {
256
+ font-size: 9px; color: var(--text-3); margin-top: 3px;
257
+ font-family: 'JetBrains Mono', monospace;
258
+ padding-left: 6px;
259
+ }
260
+
261
+ /* ── Environment grid ────────────────────────────────────────────────────── */
262
+ .env-grid {
263
+ display: grid; grid-template-columns: 1fr 1fr;
264
+ gap: 0;
265
+ background: var(--surface);
266
+ border: 1px solid var(--border-2);
267
+ border-radius: 6px;
268
+ overflow: hidden;
269
+ }
270
+ .env-item {
271
+ display: flex; gap: 12px; font-size: 10.5px; align-items: baseline;
272
+ padding: 10px 18px;
273
+ border-bottom: 1px solid var(--border);
274
+ border-right: 1px solid var(--border);
275
+ }
276
+ .env-item:nth-child(even) { border-right: none; }
277
+ .env-item:nth-last-child(-n+2) { border-bottom: none; }
278
+ .env-item__key {
279
+ font-family: 'Inter', system-ui, sans-serif; font-weight: 600;
280
+ font-size: 8.5px; letter-spacing: 1px; text-transform: uppercase;
281
+ color: var(--text-2); min-width: 80px;
282
+ }
283
+ .env-item__val {
284
+ font-family: 'JetBrains Mono', monospace;
285
+ font-size: 9.5px; color: var(--text-1);
286
+ }
287
+
288
+ /* ── Release gate ────────────────────────────────────────────────────────── */
289
+ .release-gate {
290
+ display: flex; align-items: center; gap: 16px;
291
+ padding: 16px 20px; border-radius: 6px; margin-bottom: 22px;
292
+ border: 1px solid;
293
+ position: relative; overflow: hidden;
294
+ -webkit-print-color-adjust: exact;
295
+ print-color-adjust: exact;
296
+ }
297
+ .release-gate--pass {
298
+ background: var(--pass-dim); border-color: #C5DBC9;
299
+ }
300
+ .release-gate--fail {
301
+ background: var(--fail-dim); border-color: #E5C9BD;
302
+ }
303
+ .release-gate__icon {
304
+ font-size: 22px; font-weight: 700; flex-shrink: 0; width: 32px;
305
+ text-align: center; line-height: 1;
306
+ }
307
+ .release-gate--pass .release-gate__icon { color: var(--pass); }
308
+ .release-gate--fail .release-gate__icon { color: var(--fail); }
309
+ .release-gate__body { flex: 1; }
310
+ .release-gate__label {
311
+ font-family: 'Inter', system-ui, sans-serif; font-size: 8px;
312
+ font-weight: 700; letter-spacing: 1.4px; text-transform: uppercase;
313
+ color: var(--text-3); margin-bottom: 4px;
314
+ }
315
+ .release-gate__verdict {
316
+ font-family: 'Source Serif Pro', Georgia, serif;
317
+ font-size: 18px; font-weight: 700; letter-spacing: -0.2px; line-height: 1.1;
318
+ }
319
+ .release-gate__verdict--pass { color: var(--pass); }
320
+ .release-gate__verdict--fail { color: var(--fail); }
321
+ .release-gate__detail {
322
+ font-family: 'Inter', system-ui, sans-serif; font-size: 10px;
323
+ color: var(--text-2); margin-top: 4px;
324
+ }
325
+ .release-gate__meta {
326
+ display: flex; flex-direction: column; gap: 3px; align-items: flex-end;
327
+ font-family: 'JetBrains Mono', monospace; font-size: 9px; color: var(--text-3);
328
+ flex-shrink: 0; text-align: right;
329
+ }
330
+ .release-gate__sep { color: var(--border-3); }
331
+ .release-gate__flaky-warn { color: var(--flaky); font-weight: 600; }
332
+
333
+ </content>
334
+ </invoke>