Unify section spacing rhythm
هذا الالتزام موجود في:
@@ -234,6 +234,22 @@
|
||||
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 {
|
||||
font-size: var(--text-brand);
|
||||
line-height: 1;
|
||||
@@ -544,6 +560,14 @@
|
||||
border-color: var(--meta-border-color);
|
||||
}
|
||||
|
||||
.project-card-copy > * + * {
|
||||
margin-top: 1.5rem;
|
||||
}
|
||||
|
||||
.project-meta-item > * + * {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
.surface-chip {
|
||||
@apply rounded-full border;
|
||||
border-color: var(--color-line);
|
||||
@@ -616,6 +640,10 @@
|
||||
line-height: 1.55;
|
||||
}
|
||||
|
||||
.contact-card-copy > * + * {
|
||||
margin-top: 0.75rem;
|
||||
}
|
||||
|
||||
.contact-value-ltr {
|
||||
direction: ltr;
|
||||
unicode-bidi: isolate;
|
||||
|
||||
@@ -66,7 +66,7 @@ export function HomePage({ language }: { language: Language }) {
|
||||
{founderName}
|
||||
</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)]">
|
||||
{t.ui.architectureEngineer}
|
||||
</p>
|
||||
@@ -110,18 +110,18 @@ export function HomePage({ language }: { language: Language }) {
|
||||
</div>
|
||||
|
||||
<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="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}
|
||||
</p>
|
||||
</div>
|
||||
<div className="gradient-card">
|
||||
<div className="gradient-card content-stack-default">
|
||||
<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}
|
||||
</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>
|
||||
</section>
|
||||
@@ -135,7 +135,7 @@ export function HomePage({ language }: { language: Language }) {
|
||||
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) => (
|
||||
<p key={paragraph}>{paragraph}</p>
|
||||
))}
|
||||
@@ -145,18 +145,18 @@ export function HomePage({ language }: { language: Language }) {
|
||||
</div>
|
||||
|
||||
<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="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}"
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="soft-card">
|
||||
<div className="soft-card content-stack-default">
|
||||
<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) => (
|
||||
<span
|
||||
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">
|
||||
{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>
|
||||
<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>
|
||||
))}
|
||||
</div>
|
||||
@@ -224,14 +224,14 @@ export function HomePage({ language }: { language: Language }) {
|
||||
{t.awards.items.map((award, index) => (
|
||||
<article
|
||||
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">
|
||||
<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>
|
||||
</div>
|
||||
<h3 className="type-card-title-small mt-4 text-[var(--color-ink)]">{award.title}</h3>
|
||||
<p className="type-body mt-3 text-[var(--color-muted)]">{award.description}</p>
|
||||
<h3 className="type-card-title-small text-[var(--color-ink)]">{award.title}</h3>
|
||||
<p className="type-body text-[var(--color-muted)]">{award.description}</p>
|
||||
</article>
|
||||
))}
|
||||
</div>
|
||||
@@ -249,9 +249,9 @@ export function HomePage({ language }: { language: Language }) {
|
||||
/>
|
||||
|
||||
<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>
|
||||
<div className="mt-4 flex flex-wrap gap-3">
|
||||
<div className="flex flex-wrap gap-3">
|
||||
{t.craft.skills.map((skill) => (
|
||||
<span
|
||||
key={skill}
|
||||
@@ -263,9 +263,9 @@ export function HomePage({ language }: { language: Language }) {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div className="content-stack-default">
|
||||
<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) => (
|
||||
<span
|
||||
key={tool}
|
||||
@@ -295,11 +295,11 @@ export function HomePage({ language }: { language: Language }) {
|
||||
|
||||
<div className="grid gap-5">
|
||||
{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>
|
||||
<h3 className="type-card-title mt-4 text-[var(--color-ink)]">{project.title}</h3>
|
||||
<p className="type-body mt-3 text-[var(--color-muted)]">{project.type}</p>
|
||||
<p className="type-label-wide mt-8 font-semibold text-[var(--color-ink)]">
|
||||
<h3 className="type-card-title text-[var(--color-ink)]">{project.title}</h3>
|
||||
<p className="type-body text-[var(--color-muted)]">{project.type}</p>
|
||||
<p className="type-label-wide font-semibold text-[var(--color-ink)]">
|
||||
{project.location}
|
||||
</p>
|
||||
</article>
|
||||
@@ -318,26 +318,26 @@ export function HomePage({ language }: { language: Language }) {
|
||||
</div>
|
||||
|
||||
<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="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}
|
||||
</p>
|
||||
</Link>
|
||||
{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="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}
|
||||
</p>
|
||||
</Link>
|
||||
) : (
|
||||
<div className="gradient-card">
|
||||
<div className="gradient-card content-stack-default">
|
||||
<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}
|
||||
</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>
|
||||
@@ -346,9 +346,9 @@ export function HomePage({ language }: { language: Language }) {
|
||||
|
||||
<section className="grid gap-5 md:grid-cols-2 xl:grid-cols-4">
|
||||
{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-label-wide mt-4 text-[var(--color-muted)]">
|
||||
<p className="type-label-wide text-[var(--color-muted)]">
|
||||
{metric.label}
|
||||
</p>
|
||||
</article>
|
||||
@@ -378,17 +378,17 @@ export function HomePage({ language }: { language: Language }) {
|
||||
const isPhoneValue = item.kind === "phone" || item.kind === "whatsapp";
|
||||
const isLtrValue = isEmail || isPhoneValue;
|
||||
const content = (
|
||||
<>
|
||||
<div className="contact-card-copy">
|
||||
<p className="contact-label text-[var(--color-muted)]">{item.label}</p>
|
||||
<p
|
||||
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" : ""
|
||||
} ${isPhoneValue ? "contact-value-ltr" : ""}`}
|
||||
>
|
||||
{item.value}
|
||||
</p>
|
||||
</>
|
||||
</div>
|
||||
);
|
||||
const cardClass =
|
||||
`contact-card ${shouldSpan ? "md:col-span-2" : ""}`;
|
||||
|
||||
@@ -49,36 +49,36 @@ export function ProjectCard({
|
||||
</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">
|
||||
<span>{project.id}</span>
|
||||
<span className="project-rule-line h-px w-12 shrink-0" />
|
||||
<span>{project.location}</span>
|
||||
</div>
|
||||
|
||||
<h3 className="type-project-title mt-5 text-[var(--color-ink)]">
|
||||
<h3 className="type-project-title text-[var(--color-ink)]">
|
||||
{project.title}
|
||||
</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}
|
||||
</p>
|
||||
|
||||
<dl className="project-meta-list mt-8 grid gap-4 border-y py-6 sm:grid-cols-3">
|
||||
<div>
|
||||
<dl className="project-meta-list grid gap-4 border-y py-6 sm:grid-cols-3">
|
||||
<div className="project-meta-item">
|
||||
<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 className="project-meta-item">
|
||||
<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 className="project-meta-item">
|
||||
<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>
|
||||
</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) => (
|
||||
<li key={highlight} className="flex items-center gap-3">
|
||||
<span className="h-2 w-2 rounded-full bg-[var(--color-blue-500)]" />
|
||||
@@ -90,7 +90,7 @@ export function ProjectCard({
|
||||
{project.sheetImage ? (
|
||||
<a
|
||||
href={project.sheetImage}
|
||||
className="button-secondary mt-8 w-fit"
|
||||
className="button-secondary w-fit"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
|
||||
@@ -11,16 +11,19 @@ export function SectionHeading({
|
||||
description,
|
||||
align = "left",
|
||||
}: 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 (
|
||||
<div className={alignment}>
|
||||
<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}
|
||||
</h2>
|
||||
{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}
|
||||
</div>
|
||||
);
|
||||
|
||||
المرجع في مشكلة جديدة
حظر مستخدم