Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/app/pages/home/sections/about/about.css
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,9 @@
top: calc(50% - 3.404cqw);
}
}

@media (min-width: 90rem) {
.about-section {
min-height: clamp(49.125rem, 50vw, 60rem);
}
}
2 changes: 1 addition & 1 deletion src/app/pages/home/sections/about/about.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<section
id="about"
class="scroll-mt-20 bg-foreground px-4 py-22 text-canvas lg:min-h-180 lg:px-30 lg:py-36"
class="about-section scroll-mt-20 bg-foreground px-4 py-22 text-canvas lg:min-h-180 lg:px-30 lg:py-36"
aria-labelledby="about-title"
>
<div
Expand Down
11 changes: 6 additions & 5 deletions src/app/pages/home/sections/contact/contact.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,21 @@
class="contact__inner relative mx-auto w-full max-w-2xl lg:grid lg:min-h-140 lg:max-w-300 lg:grid-cols-[minmax(0,560px)_minmax(0,480px)]"
>
<app-brand-stamp
class="contact__stamp absolute -top-8.5 right-0 z-1 w-30 min-[40rem]:right-6 lg:top-0 lg:right-0 lg:w-42"
class="contact__stamp absolute -top-4 right-0 z-1 w-30 min-[40rem]:-top-8.5 min-[40rem]:right-6 lg:-top-12 lg:right-0 lg:w-42 min-[75rem]:top-0"
/>

<div class="contact__intro pt-19 lg:flex lg:flex-col lg:pt-0">
<div class="contact__intro @container pt-19 lg:flex lg:flex-col lg:pt-0">
<p class="contact__eyebrow text-base leading-none font-medium uppercase">
{{ 'contact.eyebrow' | translate }}
</p>
<h2
id="contact-title"
class="contact__title mt-4 text-[clamp(40px,12.8vw,48px)] leading-none font-bold whitespace-pre-line lg:text-[64px]"
class="contact__title mt-4 text-[clamp(40px,12.8vw,48px)] leading-none font-bold whitespace-pre-line [&:lang(de)]:text-[clamp(32px,11.2cqw,48px)] min-[40rem]:[&:lang(en)]:text-[clamp(40px,5vw,48px)] lg:text-[64px] lg:[&:lang(en)]:text-[clamp(40px,11.2cqw,64px)] lg:[&:lang(de)]:text-[clamp(40px,11.2cqw,64px)]"
>
{{ 'contact.heading' | translate }}
</h2>

<div class="contact__copy mt-8 text-justify text-base leading-[1.2] lg:max-w-140 lg:text-lg">
<div class="contact__copy mt-8 text-start text-base leading-[1.2] lg:max-w-140 lg:text-lg">
<p class="mt-4">
{{ 'contact.paragraphs.projects' | translate }}
</p>
Expand Down Expand Up @@ -129,8 +129,9 @@
height="44"
draggable="false"
/>
<label class="contact-consent__label" for="contact-privacy">
<label class="contact-consent__label group" for="contact-privacy">
<input
class="cursor-pointer transition-[background-color,box-shadow,transform] duration-180 ease-out checked:shadow-[0_0_0_4px_color-mix(in_srgb,var(--color-primary)_18%,transparent)] active:scale-90 active:-rotate-4 group-hover:scale-108 group-hover:rotate-2 group-hover:shadow-[0_0_0_5px_color-mix(in_srgb,var(--color-primary)_16%,transparent)] motion-reduce:transition-none"
id="contact-privacy"
type="checkbox"
formControlName="privacyAccepted"
Expand Down
6 changes: 3 additions & 3 deletions src/app/pages/home/sections/hero/hero.css
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@
.hero__polaroid {
position: absolute;
top: clamp(8px, 0.902vw, 13px);
right: clamp(8px, 1.111vw, 16px);
right: clamp(-48px, calc(0.2333 * (100vw - 1200px) + 8px), 16px);
width: clamp(160px, 14.137vw, 203.567px);
padding: clamp(11px, 0.972vw, 14px) clamp(11px, 0.972vw, 14px) 0;
}
Expand All @@ -249,8 +249,8 @@

.hero__socials {
position: absolute;
/* Tracks the width-driven cover scale of the bottom-anchored artwork. */
bottom: max(110px, 5.882vw);
/* Tracks both axes of the bottom-anchored 1440 × 900 cover artwork. */
bottom: max(110px, 5.882vw, 12.222svh);
left: max(72px, calc((100% - var(--hero-desktop-content-width)) / 2 + 72px));
display: flex;
width: 40px;
Expand Down
2 changes: 1 addition & 1 deletion src/app/pages/home/sections/hero/hero.html
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ <h1 id="hero-title" class="hero__title" [attr.aria-label]="'hero.roleAria' | tra
</a>

<a
href="mailto:kamyar.zamanfar@gmail.com"
href="mailto:contact@kamycoding.com"
[attr.aria-label]="'social.emailKamyarAria' | translate"
>
<img src="/assets/icons/social/email.svg" alt="" aria-hidden="true" draggable="false" />
Expand Down
2 changes: 1 addition & 1 deletion src/app/pages/home/sections/projects/projects.html
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ <h2 id="projects-title" class="text-5xl leading-none font-bold lg:text-[4rem]">

<div class="col-start-1 row-start-2 mt-4">
<h3 class="text-xl leading-none font-bold lg:text-2xl">{{ project.title }}</h3>
<p class="mt-4 text-justify text-base leading-normal lg:text-lg">
<p class="mt-4 text-start text-base leading-normal lg:text-lg">
{{ project.descriptionKey | translate }}
</p>
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/app/pages/home/sections/skills/skills.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<section
id="skills"
class="skills-section flex min-h-290 scroll-mt-20 items-center overflow-hidden px-4 pt-22 pb-40 text-foreground lg:min-h-200 lg:px-8 lg:py-36 min-[90rem]:px-30"
class="skills-section flex min-h-290 scroll-mt-20 items-center overflow-hidden px-4 pt-22 pb-40 text-foreground lg:min-h-200 lg:px-8 lg:py-36 min-[90rem]:min-h-[clamp(50rem,30vw,68.75rem)] min-[90rem]:px-30"
aria-labelledby="skills-title"
>
<div
Expand Down
35 changes: 26 additions & 9 deletions src/app/pages/home/sections/testimonials/testimonials.css
Original file line number Diff line number Diff line change
Expand Up @@ -109,15 +109,18 @@
height: auto;
}

.testimonial-card:focus-within {
.testimonial-card:focus-within,
.testimonial-card--active {
z-index: 4;
}

.testimonial-card:focus-within .testimonial-card__highlight {
.testimonial-card:focus-within .testimonial-card__highlight,
.testimonial-card--active .testimonial-card__highlight {
opacity: 1;
}

.testimonial-card:focus-within .testimonial-card__identity {
.testimonial-card:focus-within .testimonial-card__identity,
.testimonial-card--active .testimonial-card__identity {
color: var(--color-foreground);
}
}
Expand Down Expand Up @@ -191,23 +194,37 @@
width: clamp(20px, 1.667vw, 24px);
height: clamp(20px, 1.667vw, 24px);
}

.testimonial-card:focus-within,
.testimonial-card--active {
z-index: 3;
filter: drop-shadow(0 12px 16px rgb(14 16 19 / 18%));
scale: 1.02;
}

.testimonial-card:focus-within .testimonial-card__highlight,
.testimonial-card--active .testimonial-card__highlight {
opacity: 1;
}

.testimonial-card:focus-within .testimonial-card__identity,
.testimonial-card--active .testimonial-card__identity {
color: var(--color-foreground);
}
}

@media (min-width: 64rem) and (hover: hover) and (pointer: fine) {
.testimonial-card:hover,
.testimonial-card:focus-within {
.testimonial-card:hover {
z-index: 3;
filter: drop-shadow(0 12px 16px rgb(14 16 19 / 18%));
scale: 1.02;
}

.testimonial-card:hover .testimonial-card__highlight,
.testimonial-card:focus-within .testimonial-card__highlight {
.testimonial-card:hover .testimonial-card__highlight {
opacity: 1;
}

.testimonial-card:hover .testimonial-card__identity,
.testimonial-card:focus-within .testimonial-card__identity {
.testimonial-card:hover .testimonial-card__identity {
color: var(--color-foreground);
}

Expand Down
4 changes: 4 additions & 0 deletions src/app/pages/home/sections/testimonials/testimonials.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@
@for (testimonial of testimonials; track testimonial.id) {
<li
class="testimonial-card relative z-1 grid aspect-square w-full min-w-0 origin-center text-canvas isolate"
[class.testimonial-card--active]="activeTestimonialId() === testimonial.id"
tabindex="0"
(click)="activateTestimonial($event, testimonial.id)"
(keydown.enter)="activateTestimonial($event, testimonial.id)"
(keydown.space)="activateTestimonial($event, testimonial.id)"
>
Comment on lines 31 to 38
<picture class="testimonial-card__paper" aria-hidden="true">
<source
Expand Down
24 changes: 23 additions & 1 deletion src/app/pages/home/sections/testimonials/testimonials.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { Component } from '@angular/core';
import { Component, HostListener, signal } from '@angular/core';
import { TranslatePipe } from '@ngx-translate/core';

import {
TESTIMONIAL_PAPER_ASSETS,
TESTIMONIALS,
} from '../../../../features/testimonials/testimonials.data';
import type { TestimonialId } from '../../../../features/testimonials/testimonials.model';

@Component({
selector: 'app-testimonials',
Expand All @@ -15,4 +16,25 @@ import {
export class Testimonials {
protected readonly paperAssets = TESTIMONIAL_PAPER_ASSETS;
protected readonly testimonials = TESTIMONIALS;
protected readonly activeTestimonialId = signal<TestimonialId | null>(null);

protected activateTestimonial(event: Event, testimonialId: TestimonialId): void {
if (event instanceof KeyboardEvent) {
event.preventDefault();
}
Comment on lines +22 to +24

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Ignore Enter events from nested profile links

When keyboard focus is on the nested LinkedIn link, its Enter keydown bubbles to the card's new handler, and this unconditional preventDefault() suppresses the link's native activation. As a result, keyboard users cannot open testimonial profiles; handle the key only when the card itself is the event target, or avoid preventing the default for descendant controls.

Useful? React with 👍 / 👎.


event.stopPropagation();
this.activeTestimonialId.set(testimonialId);
}
Comment on lines +21 to +28

@HostListener('document:click', ['$event'])
protected clearActiveTestimonial(event: MouseEvent): void {
this.activeTestimonialId.set(null);

const activeElement = (event.currentTarget as Document).activeElement;

if (activeElement instanceof HTMLElement && activeElement.closest('.testimonial-card')) {
activeElement.blur();
}
}
}
5 changes: 0 additions & 5 deletions src/app/pages/legal-notice/legal-notice.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
}

app-legal-page-layout {
--legal-content-min-height: 430px;
--legal-content-line-height: 1.2;
}

Expand Down Expand Up @@ -49,10 +48,6 @@ a:focus-visible {
}

@media (min-width: 64rem) {
app-legal-page-layout {
--legal-content-min-height: 475px;
}

h2 {
font-size: 24px;
}
Expand Down
11 changes: 7 additions & 4 deletions src/app/pages/project-detail/project-detail.css
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
display: grid;
min-height: max(900px, 100svh);
overflow: hidden;
padding: 96px 72px 24px;
grid-template-rows: auto auto auto;
padding: clamp(96px, 8svh, 160px) 72px 24px;
grid-template-rows: auto auto minmax(max-content, 1fr);
background-color: var(--color-canvas);
background-image: url('/assets/project-detail/project-detail-header-bg.webp');
background-repeat: no-repeat;
Expand All @@ -32,6 +32,8 @@
}

.project-detail__back {
width: min(1296px, 100%);
margin-inline: auto;
grid-row: 1;
justify-self: start;
color: var(--color-canvas);
Expand All @@ -46,7 +48,7 @@

.project-detail__layout {
display: grid;
width: min(1200px, 100%);
width: min(1296px, 100%);
margin: 38px auto 0;
grid-row: 2;
grid-template-columns: minmax(0, 488px) minmax(0, 560px);
Expand Down Expand Up @@ -105,7 +107,7 @@
}

.project-detail__copy section p {
text-align: justify;
text-align: start;
}

.project-detail__technologies {
Expand Down Expand Up @@ -181,6 +183,7 @@
width: min(1296px, 100%);
margin: 48px auto 0;
grid-row: 3;
align-self: start;
justify-content: flex-end;
color: var(--color-foreground);
}
Expand Down
2 changes: 1 addition & 1 deletion src/app/shared/data/social-links.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const SOCIAL_LINKS = {
email: {
id: 'email',
labelKey: 'social.emailLabel',
href: 'mailto:kamyar.zamanfar@gmail.com',
href: 'mailto:contact@kamycoding.com',
accessibleLabelKey: 'social.emailAria',
iconSrc: '/assets/icons/social/email.svg',
opensInNewTab: false,
Expand Down
22 changes: 14 additions & 8 deletions src/app/shared/legal-page-layout/legal-page-layout.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,19 @@
}

.legal-page {
display: flex;
min-height: 100svh;
flex-direction: column;
background-color: var(--color-foreground);
color: var(--color-canvas);
}

@supports (height: 100dvh) {
.legal-page {
min-height: 100dvh;
}
}

.legal-page__hero {
height: 271px;
background-color: var(--color-foreground);
Expand Down Expand Up @@ -35,8 +43,11 @@
}

.legal-page__page {
display: flex;
width: min(1440px, 100%);
margin-inline: auto;
flex: 1;
flex-direction: column;
}

.legal-page__back {
Expand Down Expand Up @@ -69,8 +80,7 @@
.legal-page__content {
display: flex;
width: min(1200px, calc(100% - 40px));
min-height: var(--legal-content-min-height, auto);
margin: 20px auto 0;
margin: 20px auto 64px;
flex-direction: column;
gap: 32px;
font-size: 16px;
Expand All @@ -79,7 +89,7 @@

.legal-page app-footer {
display: block;
margin-top: 64px;
margin-top: auto;
}

@media (min-width: 64rem) {
Expand All @@ -102,11 +112,7 @@

.legal-page__content {
width: min(1200px, calc(100% - 64px));
margin-top: 80px;
margin: 80px auto;
gap: 40px;
}

.legal-page app-footer {
margin-top: 80px;
}
}
11 changes: 10 additions & 1 deletion src/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,16 @@ html {

@media (min-width: 64rem) {
.project-detail-active app-header .site-header__desktop {
max-width: none;
grid-template-columns: auto auto auto minmax(96px, 1fr) auto auto;
column-gap: clamp(28px, 3.25vw, 52px);
}

.project-detail-active app-header .site-header__desktop nav li:nth-child(3) {
justify-self: end;
}

.project-detail-active app-header .site-header__desktop > button {
margin-inline-start: clamp(20px, 2.25vw, 36px);
}

.project-detail-active .project-detail__copy {
Expand Down