content: replace scaffolding with bilingual pages and case studies
Ship the final German and English copy, compose every route from shared page primitives, and cover claims, parity and contact briefing in tests. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
55
src/app/shared/case-study/case-study.html
Normal file
55
src/app/shared/case-study/case-study.html
Normal file
@@ -0,0 +1,55 @@
|
||||
<article class="case-study stack" [id]="caseStudy().id" [attr.aria-labelledby]="headingId()">
|
||||
<header class="stack">
|
||||
<h2 [id]="headingId()">{{ caseStudy().headline }}</h2>
|
||||
<p class="meta">
|
||||
{{ caseStudy().client }} · {{ caseStudy().role }} · {{ caseStudy().period }} ·
|
||||
{{ caseStudy().domain }}
|
||||
</p>
|
||||
<p>{{ caseStudy().summary }}</p>
|
||||
<p>{{ caseStudy().responsibility }}</p>
|
||||
@if (caseStudy().transparencyNote; as note) {
|
||||
<p class="transparency" role="note">{{ note }}</p>
|
||||
}
|
||||
</header>
|
||||
|
||||
<section class="stack" [attr.aria-labelledby]="caseStudy().id + '-situation'">
|
||||
<h3 [id]="caseStudy().id + '-situation'">{{ situationLabel() }}</h3>
|
||||
<p>{{ caseStudy().situation }}</p>
|
||||
</section>
|
||||
|
||||
<section class="stack" [attr.aria-labelledby]="caseStudy().id + '-approach'">
|
||||
<h3 [id]="caseStudy().id + '-approach'">{{ approachLabel() }}</h3>
|
||||
<ol>
|
||||
@for (item of caseStudy().approach; track $index) {
|
||||
<li>{{ item }}</li>
|
||||
}
|
||||
</ol>
|
||||
</section>
|
||||
|
||||
<section class="stack" [attr.aria-labelledby]="caseStudy().id + '-outcome'">
|
||||
<h3 [id]="caseStudy().id + '-outcome'">{{ outcomeLabel() }}</h3>
|
||||
<ul>
|
||||
@for (item of caseStudy().outcome; track $index) {
|
||||
<li>{{ item }}</li>
|
||||
}
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
@if (caseStudy().metrics.length > 0) {
|
||||
<app-metric-list [metrics]="caseStudy().metrics" [labelledBy]="metricsLabelId()" />
|
||||
}
|
||||
|
||||
<section class="stack" [attr.aria-labelledby]="caseStudy().id + '-stack'">
|
||||
<h3 [id]="caseStudy().id + '-stack'">{{ stackLabel() }}</h3>
|
||||
<ul class="cluster tags">
|
||||
@for (item of caseStudy().stack; track $index) {
|
||||
<li>{{ item }}</li>
|
||||
}
|
||||
</ul>
|
||||
<ul class="cluster tags">
|
||||
@for (tag of caseStudy().tags; track $index) {
|
||||
<li>{{ tag }}</li>
|
||||
}
|
||||
</ul>
|
||||
</section>
|
||||
</article>
|
||||
50
src/app/shared/case-study/case-study.scss
Normal file
50
src/app/shared/case-study/case-study.scss
Normal file
@@ -0,0 +1,50 @@
|
||||
.case-study {
|
||||
padding: var(--space-6);
|
||||
border-radius: var(--radius-md);
|
||||
background: var(--color-surface-raised);
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin: 0;
|
||||
font-size: var(--text-2xl);
|
||||
font-weight: 600;
|
||||
line-height: var(--leading-tight);
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 0;
|
||||
font-size: var(--text-lg);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.meta,
|
||||
p,
|
||||
li {
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
.meta,
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.transparency {
|
||||
padding: var(--space-3);
|
||||
border-left: var(--focus-ring-width) solid var(--color-accent);
|
||||
background: var(--color-surface-overlay);
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
ol,
|
||||
ul {
|
||||
margin: 0;
|
||||
padding-left: var(--space-6);
|
||||
}
|
||||
|
||||
.tags {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: var(--text-sm);
|
||||
color: var(--color-text-subtle);
|
||||
}
|
||||
21
src/app/shared/case-study/case-study.ts
Normal file
21
src/app/shared/case-study/case-study.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';
|
||||
import { type CaseStudyCopy } from '../../core/content/content.contracts';
|
||||
import { MetricList } from '../metric-list/metric-list';
|
||||
|
||||
@Component({
|
||||
selector: 'app-case-study',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
imports: [MetricList],
|
||||
templateUrl: './case-study.html',
|
||||
styleUrl: './case-study.scss',
|
||||
})
|
||||
export class CaseStudy {
|
||||
readonly caseStudy = input.required<CaseStudyCopy>();
|
||||
readonly situationLabel = input.required<string>();
|
||||
readonly approachLabel = input.required<string>();
|
||||
readonly outcomeLabel = input.required<string>();
|
||||
readonly stackLabel = input.required<string>();
|
||||
|
||||
protected readonly headingId = computed(() => `case-heading-${this.caseStudy().id}`);
|
||||
protected readonly metricsLabelId = computed(() => `case-metrics-${this.caseStudy().id}`);
|
||||
}
|
||||
Reference in New Issue
Block a user