diff --git a/public/apple-touch-icon.png b/public/apple-touch-icon.png new file mode 100644 index 0000000..17b5626 Binary files /dev/null and b/public/apple-touch-icon.png differ diff --git a/public/assets/hero/portrait-default.webp b/public/assets/hero/portrait-default.webp index fc9fe30..f9f7dc2 100644 Binary files a/public/assets/hero/portrait-default.webp and b/public/assets/hero/portrait-default.webp differ diff --git a/public/favicon-96x96.png b/public/favicon-96x96.png new file mode 100644 index 0000000..10055b4 Binary files /dev/null and b/public/favicon-96x96.png differ diff --git a/public/favicon.ico b/public/favicon.ico index 57614f9..3c9341b 100644 Binary files a/public/favicon.ico and b/public/favicon.ico differ diff --git a/public/favicon.svg b/public/favicon.svg new file mode 100644 index 0000000..625c60f --- /dev/null +++ b/public/favicon.svg @@ -0,0 +1,8 @@ +RealFaviconGeneratorhttps://realfavicongenerator.net + + + + + + + \ No newline at end of file diff --git a/public/site.webmanifest b/public/site.webmanifest new file mode 100644 index 0000000..e318eb5 --- /dev/null +++ b/public/site.webmanifest @@ -0,0 +1,26 @@ +{ + "id": "/", + "name": "Kamy Coding Portfolio", + "short_name": "Kamy Coding", + "description": "Portfolio of Kamyar Zamanfar, Full-Stack Developer.", + "lang": "en", + "start_url": "/", + "scope": "/", + "icons": [ + { + "src": "/web-app-manifest-192x192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "any maskable" + }, + { + "src": "/web-app-manifest-512x512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "any maskable" + } + ], + "theme_color": "#0e1013", + "background_color": "#0e1013", + "display": "standalone" +} diff --git a/public/web-app-manifest-192x192.png b/public/web-app-manifest-192x192.png new file mode 100644 index 0000000..dad2c43 Binary files /dev/null and b/public/web-app-manifest-192x192.png differ diff --git a/public/web-app-manifest-512x512.png b/public/web-app-manifest-512x512.png new file mode 100644 index 0000000..202cb17 Binary files /dev/null and b/public/web-app-manifest-512x512.png differ diff --git a/src/app/pages/home/home.html b/src/app/pages/home/home.html index 5c08f9a..dcf2668 100644 --- a/src/app/pages/home/home.html +++ b/src/app/pages/home/home.html @@ -1,92 +1,3 @@
-
- - -
- - -
-
-

- Hello world -

-
- -

- Frontend - DEVELOPER -

- - - -
- Portrait of Kamyar Zamanfar - -
- Kamy :) -
-
-
-
-
+
diff --git a/src/app/pages/home/home.ts b/src/app/pages/home/home.ts index 7c2e48d..f4a2728 100644 --- a/src/app/pages/home/home.ts +++ b/src/app/pages/home/home.ts @@ -1,8 +1,10 @@ import { Component } from '@angular/core'; +import { Hero } from './sections/hero/hero'; + @Component({ selector: 'app-home', - imports: [], + imports: [Hero], templateUrl: './home.html', styleUrl: './home.css', }) diff --git a/src/app/pages/home/sections/hero/hero.css b/src/app/pages/home/sections/hero/hero.css new file mode 100644 index 0000000..e0c9232 --- /dev/null +++ b/src/app/pages/home/sections/hero/hero.css @@ -0,0 +1,296 @@ +:host { + display: block; +} + +.hero { + position: relative; + min-height: 812px; + overflow: hidden; + background: var(--color-canvas); + color: var(--color-foreground); +} + +.hero__background { + position: absolute; + inset: 0; + width: 100%; + height: 100%; + object-fit: cover; + object-position: bottom center; + pointer-events: none; + user-select: none; +} + +.hero__stage { + position: relative; + width: 100%; + min-height: 812px; + margin-inline: auto; +} + +.hero__composition { + position: absolute; + top: 137px; + left: 50%; + display: flex; + width: min(343px, calc(100% - 32px)); + transform: translateX(-50%); + flex-direction: column; + align-items: flex-end; + gap: 32px; +} + +.hero__top-row, +.hero__intro { + display: contents; +} + +.hero__greeting { + position: relative; + width: min(284px, 100%); + align-self: flex-start; +} + +.hero__greeting p { + display: flex; + height: 40px; + align-items: center; + justify-content: center; + margin: 0; + padding-inline: clamp(12px, 6.4vw, 24px); + border: 1px solid currentColor; + border-radius: 100px; + font-size: clamp(14px, 4.8vw, 18px); + font-weight: 500; + line-height: 1.2; + white-space: nowrap; +} + +.hero__wave { + position: absolute; + width: clamp(34px, 10.667vw, 40px); + height: clamp(34px, 10.667vw, 40px); + transform: translateY(8px); + opacity: 0; +} + +.hero__title { + display: contents; + margin: 0; +} + +.hero__title > .hero__title-line { + display: flex; + align-self: flex-start; + font-size: clamp(38px, 13.5vw, 64px); + font-weight: 700; + line-height: 1; + white-space: nowrap; +} + +.hero__title > .hero__title-line:first-child { + margin-top: -16px; +} + +.hero__title > .hero__title-line:nth-child(2) { + margin-top: -16px; +} + +.hero__cta { + display: inline-flex; + order: 1; + width: 156px; + height: 44px; + align-items: flex-start; + justify-content: center; + padding-top: 9px; + border: 1px solid currentColor; + border-radius: 100px; + box-shadow: 2px 4px 0 currentColor; + color: inherit; + font-size: 18px; + font-weight: 500; + line-height: 1.2; + text-decoration: none; +} + +.hero__polaroid { + box-sizing: border-box; + order: 2; + width: 203.567px; + height: 244px; + margin: 0 auto; + padding: 14px 14px 0; + transform: rotate(8deg); + background: var(--color-foreground); + color: var(--color-canvas); + flex: 0 0 auto; +} + +.hero__portrait { + position: relative; + width: 100%; + height: 176px; + overflow: hidden; + background: #777; +} + +.hero__portrait-image { + position: absolute; + inset: 0; + width: 100%; + height: 100%; + object-fit: cover; + object-position: center 22%; +} + +.hero__portrait-image--hover { + opacity: 0; +} + +.hero__polaroid:hover .hero__portrait-image--default { + opacity: 0; +} + +.hero__polaroid:hover .hero__portrait-image--hover { + opacity: 1; +} + +.hero__polaroid figcaption { + display: flex; + height: 54px; + align-items: center; + justify-content: center; + font-family: var(--font-hand); + font-size: 24px; + font-weight: 700; + line-height: 1.2; + white-space: nowrap; +} + +.hero__socials { + display: none; +} + +.hero :is(a, button):focus-visible { + outline: 2px solid var(--color-primary); + outline-offset: 4px; +} + +@media (min-width: 64rem) { + .hero { + min-height: 0; + } + + .hero__stage { + container-type: inline-size; + width: min(100%, 1440px); + min-height: 0; + aspect-ratio: 8 / 5; + max-height: 900px; + } + + .hero__composition { + top: 12.778cqw; + left: 20cqw; + display: flex; + width: 60.038cqw; + transform: none; + flex-direction: column; + align-items: flex-end; + gap: 1.667cqw; + } + + .hero__top-row { + position: relative; + display: block; + width: 100%; + height: 18.747cqw; + } + + .hero__intro { + display: block; + } + + .hero__greeting { + position: absolute; + top: 4.858cqw; + left: 0; + } + + .hero__greeting p { + height: 2.778cqw; + padding-inline: 1.667cqw; + font-size: 1.25cqw; + } + + .hero__wave { + width: 2.778cqw; + height: 2.778cqw; + } + + .hero__title { + display: block; + } + + .hero__title > .hero__title-line { + position: absolute; + display: flex; + margin: 0; + font-size: 8.889cqw; + } + + .hero__title > .hero__title-line:first-child { + top: 9.858cqw; + left: 0; + } + + .hero__title > .hero__title-line:nth-child(2) { + top: calc(100% + 1.667cqw); + right: 0; + } + + .hero__polaroid { + position: absolute; + top: 0.902cqw; + right: 1.111cqw; + width: 14.137cqw; + height: 16.944cqw; + padding: 0.972cqw 0.972cqw 0; + } + + .hero__portrait { + height: 12.222cqw; + } + + .hero__polaroid figcaption { + height: 3.75cqw; + font-size: 1.667cqw; + } + + .hero__cta { + width: 10.833cqw; + height: 3.056cqw; + margin-top: 10.556cqw; + padding-top: 0.625cqw; + box-shadow: 0.139cqw 0.278cqw 0 currentColor; + font-size: 1.25cqw; + } + + .hero__socials { + position: absolute; + bottom: 7.639cqw; + left: 5cqw; + display: flex; + width: 2.778cqw; + flex-direction: column; + gap: 0.556cqw; + } + + .hero__socials a, + .hero__socials img { + display: block; + width: 2.778cqw; + height: 2.778cqw; + } +} diff --git a/src/app/pages/home/sections/hero/hero.html b/src/app/pages/home/sections/hero/hero.html new file mode 100644 index 0000000..7557eb9 --- /dev/null +++ b/src/app/pages/home/sections/hero/hero.html @@ -0,0 +1,106 @@ +
+ + +
+
+
+
+
+

+ Hello world + Hi, I'm Kamyar Zamanfar + +

+
+ +

+ + +

+
+ +
+
+ Portrait of Kamyar Zamanfar + +
+
+ Kamy :) + Kamy :D +
+
+
+ + Get in Touch +
+ + +
+
diff --git a/src/app/pages/home/sections/hero/hero.spec.ts b/src/app/pages/home/sections/hero/hero.spec.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/app/pages/home/sections/hero/hero.ts b/src/app/pages/home/sections/hero/hero.ts new file mode 100644 index 0000000..bf97a16 --- /dev/null +++ b/src/app/pages/home/sections/hero/hero.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; +import { RouterLink } from '@angular/router'; + +@Component({ + selector: 'app-hero', + imports: [RouterLink], + templateUrl: './hero.html', + styleUrl: './hero.css', +}) +export class Hero {} diff --git a/src/index.html b/src/index.html index 68bc202..04ff2d6 100644 --- a/src/index.html +++ b/src/index.html @@ -1,13 +1,20 @@ - - - Portfolio - - - - - - - + + + Kamyar Zamanfar | Full-Stack Developer + + + + + + + + + + + + + + diff --git a/src/styles.css b/src/styles.css index edb7b3c..0f9d727 100644 --- a/src/styles.css +++ b/src/styles.css @@ -78,3 +78,243 @@ --font-sans: 'Bricolage Grotesque', sans-serif; --font-hand: 'Kalam', cursive; } + +.hero__cta { + transition: + background-color 180ms ease-out, + transform 180ms cubic-bezier(0.2, 0.8, 0.2, 1), + box-shadow 180ms ease-out; +} + +@media (hover: hover) and (pointer: fine) { + a.hero__cta:hover { + transform: translate(2px, 4px); + box-shadow: none; + border-color: #f8f9fa; + background-color: #f87a55; + color: #f8f9fa; + } +} + +a.hero__cta:active { + transform: translate(2px, 4px); + box-shadow: none; + border-color: #f8f9fa; + background-color: #f87a55; + color: #f8f9fa; + transition-duration: 80ms; +} + +.hero__socials a { + position: relative; + overflow: hidden; + border-radius: 50%; + isolation: isolate; +} + +.hero__socials a::before { + position: absolute; + z-index: 0; + inset: 0; + border-radius: inherit; + background-color: #3355ff; + content: ''; + transform: scaleY(0); + transform-origin: bottom; + transition: transform 220ms cubic-bezier(0.22, 1, 0.36, 1); +} + +.hero__socials a img { + position: relative; + z-index: 1; +} + +@media (hover: hover) and (pointer: fine) { + .hero__socials a:hover::before { + transform: scaleY(1); + } +} + +.hero__socials a:focus-visible::before, +.hero__socials a:active::before { + transform: scaleY(1); +} + +@media (prefers-reduced-motion: reduce) { + .hero__socials a::before { + transition: none; + } +} + +.hero__greeting p { + position: relative; + width: 128px; + transition: + width 340ms cubic-bezier(0.16, 1, 0.3, 1), + background-color 260ms ease-out; +} + +.hero__greeting p span { + position: absolute; + inset: 0; + display: flex; + align-items: center; + justify-content: center; + white-space: nowrap; + transition: + opacity 190ms ease-out, + transform 300ms cubic-bezier(0.16, 1, 0.3, 1); +} + +.hero__greeting-hover { + opacity: 0; + transform: translateX(12px); + text-transform: uppercase; +} + +.hero__wave { + right: 0; + bottom: calc(100% + 8px); + transition: + opacity 200ms ease-out 100ms, + transform 300ms cubic-bezier(0.16, 1, 0.3, 1) 80ms; +} + +@media (max-width: 63.999rem) { + .hero__greeting p { + width: 100%; + background-color: #3355ff; + } + + .hero__greeting .hero__greeting-default { + opacity: 0; + transform: translateX(-12px); + } + + .hero__greeting .hero__greeting-hover, + .hero .hero__greeting .hero__wave { + opacity: 1; + transform: translateX(0); + } + + .hero .hero__polaroid .hero__portrait-image--default { + opacity: 0; + } + + .hero .hero__polaroid .hero__portrait-image--hover { + opacity: 1; + } +} + +@media (hover: hover) and (pointer: fine) { + .hero__greeting:hover p { + width: min(284px, 100%); + background-color: #3355ff; + } + + .hero__greeting:hover .hero__greeting-default { + opacity: 0; + transform: translateX(-12px); + } + + .hero__greeting:hover .hero__greeting-hover, + .hero__greeting:hover .hero__wave { + opacity: 1; + transform: translateX(0); + } +} + +@media (min-width: 64rem) { + .hero__greeting p { + width: 8.889cqw; + } +} + +@media (min-width: 64rem) and (hover: hover) and (pointer: fine) { + .hero__greeting:hover p { + width: 19.722cqw; + } +} + +@media (prefers-reduced-motion: reduce) { + .hero__greeting p, + .hero__greeting p span, + .hero__wave { + transition: none; + } +} + +.hero__letter { + position: relative; + display: inline-block; + cursor: default; + transition: + color 180ms ease-out, + transform 260ms cubic-bezier(0.16, 1, 0.3, 1); +} + +.hero__letter::after { + position: absolute; + top: 0; + left: 50%; + width: max-content; + color: #f7c518; + content: attr(data-hover); + opacity: 0; + transform: translateX(-50%) scale(0.82); + transform-origin: center 70%; + transition: + opacity 180ms ease-out, + transform 260ms cubic-bezier(0.16, 1, 0.3, 1); +} + +@media (hover: hover) and (pointer: fine) { + .hero__letter:hover { + color: transparent; + transform: scale(0.96); + } + + .hero__letter:hover::after { + opacity: 1; + transform: translateX(-50%) scale(1); + } +} + +@media (prefers-reduced-motion: reduce) { + .hero__letter, + .hero__letter::after { + transition: none; + } +} + +.hero__polaroid figcaption { + position: relative; +} + +.hero__polaroid figcaption span { + position: absolute; + transition: + opacity 180ms ease-out, + transform 260ms cubic-bezier(0.16, 1, 0.3, 1); +} + +.hero__caption-hover { + opacity: 0; + transform: translateY(5px) scale(0.96); +} + +.hero__polaroid:hover .hero__caption-default { + opacity: 0; + transform: translateY(-5px) scale(0.96); +} + +.hero__polaroid:hover .hero__caption-hover { + opacity: 1; + transform: translateY(0) scale(1); +} + +@media (prefers-reduced-motion: reduce) { + .hero__polaroid figcaption span { + transition: none; + } +}