Unify section spacing rhythm

هذا الالتزام موجود في:
2026-05-02 23:36:29 +03:00
الأصل 93c8a87d93
التزام 24ab318204
4 ملفات معدلة مع 83 إضافات و52 حذوفات

عرض الملف

@@ -234,6 +234,22 @@
line-height: 1.75; line-height: 1.75;
} }
.content-stack-default > * + * {
margin-top: 1rem;
}
.content-stack-relaxed > * + * {
margin-top: 1.5rem;
}
.section-heading-stack > * + * {
margin-top: 1rem;
}
.hero-copy-stack > * + * {
margin-top: 1rem;
}
.type-brand { .type-brand {
font-size: var(--text-brand); font-size: var(--text-brand);
line-height: 1; line-height: 1;
@@ -544,6 +560,14 @@
border-color: var(--meta-border-color); border-color: var(--meta-border-color);
} }
.project-card-copy > * + * {
margin-top: 1.5rem;
}
.project-meta-item > * + * {
margin-top: 0.5rem;
}
.surface-chip { .surface-chip {
@apply rounded-full border; @apply rounded-full border;
border-color: var(--color-line); border-color: var(--color-line);
@@ -616,6 +640,10 @@
line-height: 1.55; line-height: 1.55;
} }
.contact-card-copy > * + * {
margin-top: 0.75rem;
}
.contact-value-ltr { .contact-value-ltr {
direction: ltr; direction: ltr;
unicode-bidi: isolate; unicode-bidi: isolate;

عرض الملف

@@ -66,7 +66,7 @@ export function HomePage({ language }: { language: Language }) {
{founderName} {founderName}
</h1> </h1>
<div className="mt-8 max-w-2xl space-y-4"> <div className="hero-copy-stack mt-8 max-w-2xl">
<p className="type-body-responsive uppercase tracking-[0.18em] text-[var(--color-muted)]"> <p className="type-body-responsive uppercase tracking-[0.18em] text-[var(--color-muted)]">
{t.ui.architectureEngineer} {t.ui.architectureEngineer}
</p> </p>
@@ -110,18 +110,18 @@ export function HomePage({ language }: { language: Language }) {
</div> </div>
<div className="grid gap-5 md:grid-cols-2"> <div className="grid gap-5 md:grid-cols-2">
<div className="soft-card"> <div className="soft-card content-stack-default">
<p className="eyebrow-note">{t.ui.profile}</p> <p className="eyebrow-note">{t.ui.profile}</p>
<p className="type-card-title-small display-face mt-4 text-[var(--color-ink)]"> <p className="type-card-title-small display-face text-[var(--color-ink)]">
{t.hero.profileBlurb} {t.hero.profileBlurb}
</p> </p>
</div> </div>
<div className="gradient-card"> <div className="gradient-card content-stack-default">
<p className="eyebrow-note">{t.hero.featuredProjectTitle}</p> <p className="eyebrow-note">{t.hero.featuredProjectTitle}</p>
<p className="type-card-title display-face mt-4 text-[var(--color-ink)]"> <p className="type-card-title display-face text-[var(--color-ink)]">
{t.featured.projects[0]?.location ?? address} {t.featured.projects[0]?.location ?? address}
</p> </p>
<p className="type-body mt-3 text-[var(--color-muted)]">{t.hero.featuredProjectText}</p> <p className="type-body text-[var(--color-muted)]">{t.hero.featuredProjectText}</p>
</div> </div>
</div> </div>
</section> </section>
@@ -135,7 +135,7 @@ export function HomePage({ language }: { language: Language }) {
description={t.about.description} description={t.about.description}
/> />
<div className="type-body-editorial mt-8 max-w-2xl space-y-5 text-[var(--color-muted)]"> <div className="content-stack-relaxed type-body-editorial mt-8 max-w-2xl text-[var(--color-muted)]">
{t.about.paragraphs.map((paragraph) => ( {t.about.paragraphs.map((paragraph) => (
<p key={paragraph}>{paragraph}</p> <p key={paragraph}>{paragraph}</p>
))} ))}
@@ -145,18 +145,18 @@ export function HomePage({ language }: { language: Language }) {
</div> </div>
<div id="philosophy" className="grid gap-5 scroll-mt-28"> <div id="philosophy" className="grid gap-5 scroll-mt-28">
<div className="gradient-card"> <div className="gradient-card content-stack-default">
<p className="eyebrow-note">{t.ui.designPhilosophy}</p> <p className="eyebrow-note">{t.ui.designPhilosophy}</p>
<p className="type-card-title display-face mt-4 text-[var(--color-ink)]"> <p className="type-card-title display-face text-[var(--color-ink)]">
"{t.philosophy.quote}" "{t.philosophy.quote}"
</p> </p>
</div> </div>
<div className="soft-card"> <div className="soft-card content-stack-default">
<p className="eyebrow-note">{t.ui.materialsMood}</p> <p className="eyebrow-note">{t.ui.materialsMood}</p>
<p className="type-body-editorial mt-4 text-[var(--color-muted)]">{t.philosophy.body}</p> <p className="type-body-editorial text-[var(--color-muted)]">{t.philosophy.body}</p>
<div className="mt-6 flex flex-wrap gap-3"> <div className="flex flex-wrap gap-3">
{t.philosophy.tags.map((item) => ( {t.philosophy.tags.map((item) => (
<span <span
key={item} key={item}
@@ -183,9 +183,9 @@ export function HomePage({ language }: { language: Language }) {
<div className="grid gap-5 md:grid-cols-2 xl:grid-cols-3"> <div className="grid gap-5 md:grid-cols-2 xl:grid-cols-3">
{t.sectors.categories.map((category, index) => ( {t.sectors.categories.map((category, index) => (
<article key={category} className="soft-card min-h-[190px]"> <article key={category} className="soft-card content-stack-relaxed min-h-[190px]">
<p className="eyebrow-note">{String(index + 1).padStart(2, "0")}</p> <p className="eyebrow-note">{String(index + 1).padStart(2, "0")}</p>
<h3 className="type-card-title mt-8 text-[var(--color-ink)]">{category}</h3> <h3 className="type-card-title text-[var(--color-ink)]">{category}</h3>
</article> </article>
))} ))}
</div> </div>
@@ -224,14 +224,14 @@ export function HomePage({ language }: { language: Language }) {
{t.awards.items.map((award, index) => ( {t.awards.items.map((award, index) => (
<article <article
key={`${award.year}-${award.title}`} key={`${award.year}-${award.title}`}
className="surface-card rounded-[24px] p-5" className="surface-card content-stack-default rounded-[24px] p-5"
> >
<div className="flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between"> <div className="flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between">
<p className="eyebrow-note">{String(index + 1).padStart(2, "0")}</p> <p className="eyebrow-note">{String(index + 1).padStart(2, "0")}</p>
<p className="type-label font-semibold text-[var(--color-blue-400)]">{award.year}</p> <p className="type-label font-semibold text-[var(--color-blue-400)]">{award.year}</p>
</div> </div>
<h3 className="type-card-title-small mt-4 text-[var(--color-ink)]">{award.title}</h3> <h3 className="type-card-title-small text-[var(--color-ink)]">{award.title}</h3>
<p className="type-body mt-3 text-[var(--color-muted)]">{award.description}</p> <p className="type-body text-[var(--color-muted)]">{award.description}</p>
</article> </article>
))} ))}
</div> </div>
@@ -249,9 +249,9 @@ export function HomePage({ language }: { language: Language }) {
/> />
<div className="mt-10 grid gap-6 md:grid-cols-2"> <div className="mt-10 grid gap-6 md:grid-cols-2">
<div> <div className="content-stack-default">
<p className="eyebrow-note">{t.ui.coreSkills}</p> <p className="eyebrow-note">{t.ui.coreSkills}</p>
<div className="mt-4 flex flex-wrap gap-3"> <div className="flex flex-wrap gap-3">
{t.craft.skills.map((skill) => ( {t.craft.skills.map((skill) => (
<span <span
key={skill} key={skill}
@@ -263,9 +263,9 @@ export function HomePage({ language }: { language: Language }) {
</div> </div>
</div> </div>
<div> <div className="content-stack-default">
<p className="eyebrow-note">{t.ui.software}</p> <p className="eyebrow-note">{t.ui.software}</p>
<div className="mt-4 flex flex-wrap gap-3"> <div className="flex flex-wrap gap-3">
{t.craft.software.map((tool) => ( {t.craft.software.map((tool) => (
<span <span
key={tool} key={tool}
@@ -295,11 +295,11 @@ export function HomePage({ language }: { language: Language }) {
<div className="grid gap-5"> <div className="grid gap-5">
{t.craft.additionalProjects.map((project) => ( {t.craft.additionalProjects.map((project) => (
<article key={project.title} className="gradient-card"> <article key={project.title} className="gradient-card content-stack-default">
<p className="eyebrow-note">{project.year}</p> <p className="eyebrow-note">{project.year}</p>
<h3 className="type-card-title mt-4 text-[var(--color-ink)]">{project.title}</h3> <h3 className="type-card-title text-[var(--color-ink)]">{project.title}</h3>
<p className="type-body mt-3 text-[var(--color-muted)]">{project.type}</p> <p className="type-body text-[var(--color-muted)]">{project.type}</p>
<p className="type-label-wide mt-8 font-semibold text-[var(--color-ink)]"> <p className="type-label-wide font-semibold text-[var(--color-ink)]">
{project.location} {project.location}
</p> </p>
</article> </article>
@@ -318,26 +318,26 @@ export function HomePage({ language }: { language: Language }) {
</div> </div>
<div className="grid gap-5 sm:grid-cols-2"> <div className="grid gap-5 sm:grid-cols-2">
<Link href={`${basePath}/resume`} className="soft-card block"> <Link href={`${basePath}/resume`} className="soft-card content-stack-default block">
<p className="eyebrow-note">{t.ui.onlineResume}</p> <p className="eyebrow-note">{t.ui.onlineResume}</p>
<p className="type-card-title display-face mt-4 text-[var(--color-ink)]"> <p className="type-card-title display-face text-[var(--color-ink)]">
{t.ui.viewFullResume} {t.ui.viewFullResume}
</p> </p>
</Link> </Link>
{hasResume ? ( {hasResume ? (
<Link href={resumeFile.href} className="gradient-card block" download> <Link href={resumeFile.href} className="gradient-card content-stack-default block" download>
<p className="eyebrow-note">{t.ui.pdfDownload}</p> <p className="eyebrow-note">{t.ui.pdfDownload}</p>
<p className="type-card-title display-face mt-4 text-[var(--color-ink)]"> <p className="type-card-title display-face text-[var(--color-ink)]">
{t.ui.downloadCv} {t.ui.downloadCv}
</p> </p>
</Link> </Link>
) : ( ) : (
<div className="gradient-card"> <div className="gradient-card content-stack-default">
<p className="eyebrow-note">{t.ui.pdfDownload}</p> <p className="eyebrow-note">{t.ui.pdfDownload}</p>
<p className="type-card-title display-face mt-4 text-[var(--color-ink)]"> <p className="type-card-title display-face text-[var(--color-ink)]">
{t.ui.downloadCv} {t.ui.downloadCv}
</p> </p>
<p className="type-body mt-3 text-[var(--color-muted)]">{t.ui.resumeUnavailable}</p> <p className="type-body text-[var(--color-muted)]">{t.ui.resumeUnavailable}</p>
</div> </div>
)} )}
</div> </div>
@@ -346,9 +346,9 @@ export function HomePage({ language }: { language: Language }) {
<section className="grid gap-5 md:grid-cols-2 xl:grid-cols-4"> <section className="grid gap-5 md:grid-cols-2 xl:grid-cols-4">
{t.metrics.map((metric) => ( {t.metrics.map((metric) => (
<article key={metric.label} className="soft-card text-center"> <article key={metric.label} className="soft-card content-stack-default text-center">
<p className="type-metric display-face text-[var(--color-ink)]">{metric.value}</p> <p className="type-metric display-face text-[var(--color-ink)]">{metric.value}</p>
<p className="type-label-wide mt-4 text-[var(--color-muted)]"> <p className="type-label-wide text-[var(--color-muted)]">
{metric.label} {metric.label}
</p> </p>
</article> </article>
@@ -378,17 +378,17 @@ export function HomePage({ language }: { language: Language }) {
const isPhoneValue = item.kind === "phone" || item.kind === "whatsapp"; const isPhoneValue = item.kind === "phone" || item.kind === "whatsapp";
const isLtrValue = isEmail || isPhoneValue; const isLtrValue = isEmail || isPhoneValue;
const content = ( const content = (
<> <div className="contact-card-copy">
<p className="contact-label text-[var(--color-muted)]">{item.label}</p> <p className="contact-label text-[var(--color-muted)]">{item.label}</p>
<p <p
dir={isLtrValue ? "ltr" : undefined} dir={isLtrValue ? "ltr" : undefined}
className={`contact-value mt-3 break-words font-semibold text-[var(--color-ink)] ${ className={`contact-value break-words font-semibold text-[var(--color-ink)] ${
isEmail ? "contact-value-email" : "" isEmail ? "contact-value-email" : ""
} ${isPhoneValue ? "contact-value-ltr" : ""}`} } ${isPhoneValue ? "contact-value-ltr" : ""}`}
> >
{item.value} {item.value}
</p> </p>
</> </div>
); );
const cardClass = const cardClass =
`contact-card ${shouldSpan ? "md:col-span-2" : ""}`; `contact-card ${shouldSpan ? "md:col-span-2" : ""}`;

عرض الملف

@@ -49,36 +49,36 @@ export function ProjectCard({
</div> </div>
</div> </div>
<div className="flex flex-col justify-center"> <div className="project-card-copy flex flex-col justify-center">
<div className="type-label-wide flex flex-wrap items-center gap-x-3 gap-y-2 text-[var(--color-muted)] sm:flex-nowrap"> <div className="type-label-wide flex flex-wrap items-center gap-x-3 gap-y-2 text-[var(--color-muted)] sm:flex-nowrap">
<span>{project.id}</span> <span>{project.id}</span>
<span className="project-rule-line h-px w-12 shrink-0" /> <span className="project-rule-line h-px w-12 shrink-0" />
<span>{project.location}</span> <span>{project.location}</span>
</div> </div>
<h3 className="type-project-title mt-5 text-[var(--color-ink)]"> <h3 className="type-project-title text-[var(--color-ink)]">
{project.title} {project.title}
</h3> </h3>
<p className="type-body-responsive mt-5 max-w-xl text-[var(--color-muted)]"> <p className="type-body-responsive max-w-xl text-[var(--color-muted)]">
{project.description} {project.description}
</p> </p>
<dl className="project-meta-list mt-8 grid gap-4 border-y py-6 sm:grid-cols-3"> <dl className="project-meta-list grid gap-4 border-y py-6 sm:grid-cols-3">
<div> <div className="project-meta-item">
<dt className="eyebrow-note">{labels?.year ?? "Year"}</dt> <dt className="eyebrow-note">{labels?.year ?? "Year"}</dt>
<dd className="type-body mt-2 font-semibold text-[var(--color-ink)]">{project.year}</dd> <dd className="type-body font-semibold text-[var(--color-ink)]">{project.year}</dd>
</div> </div>
<div> <div className="project-meta-item">
<dt className="eyebrow-note">{labels?.area ?? "Area"}</dt> <dt className="eyebrow-note">{labels?.area ?? "Area"}</dt>
<dd className="type-body mt-2 font-semibold text-[var(--color-ink)]">{project.area}</dd> <dd className="type-body font-semibold text-[var(--color-ink)]">{project.area}</dd>
</div> </div>
<div> <div className="project-meta-item">
<dt className="eyebrow-note">{labels?.role ?? "Role"}</dt> <dt className="eyebrow-note">{labels?.role ?? "Role"}</dt>
<dd className="type-body mt-2 font-semibold text-[var(--color-ink)]">{project.role}</dd> <dd className="type-body font-semibold text-[var(--color-ink)]">{project.role}</dd>
</div> </div>
</dl> </dl>
<ul className="type-chip mt-8 grid gap-3 text-[var(--color-muted)] sm:grid-cols-2"> <ul className="type-chip grid gap-3 text-[var(--color-muted)] sm:grid-cols-2">
{project.highlights.map((highlight) => ( {project.highlights.map((highlight) => (
<li key={highlight} className="flex items-center gap-3"> <li key={highlight} className="flex items-center gap-3">
<span className="h-2 w-2 rounded-full bg-[var(--color-blue-500)]" /> <span className="h-2 w-2 rounded-full bg-[var(--color-blue-500)]" />
@@ -90,7 +90,7 @@ export function ProjectCard({
{project.sheetImage ? ( {project.sheetImage ? (
<a <a
href={project.sheetImage} href={project.sheetImage}
className="button-secondary mt-8 w-fit" className="button-secondary w-fit"
target="_blank" target="_blank"
rel="noreferrer" rel="noreferrer"
> >

عرض الملف

@@ -11,16 +11,19 @@ export function SectionHeading({
description, description,
align = "left", align = "left",
}: SectionHeadingProps) { }: SectionHeadingProps) {
const alignment = align === "center" ? "mx-auto max-w-3xl text-center" : "max-w-3xl"; const alignment =
align === "center"
? "section-heading-stack mx-auto max-w-3xl text-center"
: "section-heading-stack max-w-3xl";
return ( return (
<div className={alignment}> <div className={alignment}>
<p className="section-kicker">{eyebrow}</p> <p className="section-kicker">{eyebrow}</p>
<h2 className="type-section-title mt-4 text-[var(--color-ink)]"> <h2 className="type-section-title text-[var(--color-ink)]">
{title} {title}
</h2> </h2>
{description ? ( {description ? (
<p className="type-body-responsive mt-5 text-[var(--color-muted)]">{description}</p> <p className="type-body-responsive text-[var(--color-muted)]">{description}</p>
) : null} ) : null}
</div> </div>
); );