rewrite #16
9 changed files with 257 additions and 108 deletions
commit
dd23a3c76e
BIN
public/about/vrchat.webp
Normal file
BIN
public/about/vrchat.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.7 MiB |
|
|
@ -1,12 +1,11 @@
|
||||||
---
|
---
|
||||||
import AboutRow from "@/components/AboutRow.astro";
|
import AboutRow from "@/components/AboutRow.astro";
|
||||||
import DDay from "./DDay.astro";
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<section
|
<section
|
||||||
id="about"
|
id="about"
|
||||||
data-node-id="4:104"
|
data-node-id="4:104"
|
||||||
class="min-h-full snap-start snap-always bg-background text-foreground"
|
class="min-h-[calc(100svh-64px)] snap-start bg-background text-foreground"
|
||||||
aria-labelledby="about-title"
|
aria-labelledby="about-title"
|
||||||
>
|
>
|
||||||
<div class="grid min-h-full grid-cols-1 lg:grid-cols-2">
|
<div class="grid min-h-full grid-cols-1 lg:grid-cols-2">
|
||||||
|
|
@ -14,10 +13,12 @@ import DDay from "./DDay.astro";
|
||||||
class="relative z-10 flex flex-col justify-center px-6 py-16 sm:px-10 lg:px-[clamp(52px,5.208vw,100px)] lg:py-[clamp(58px,9.26vh,100px)]"
|
class="relative z-10 flex flex-col justify-center px-6 py-16 sm:px-10 lg:px-[clamp(52px,5.208vw,100px)] lg:py-[clamp(58px,9.26vh,100px)]"
|
||||||
>
|
>
|
||||||
<h2 id="about-title" class="max-w-xl text-3xl font-semibold tracking-tight sm:text-4xl">
|
<h2 id="about-title" class="max-w-xl text-3xl font-semibold tracking-tight sm:text-4xl">
|
||||||
👋
|
About<span class="text-foreground/35" aria-hidden="true">.</span>
|
||||||
</h2>
|
</h2>
|
||||||
<p class="mt-6 max-w-lg text-base leading-8 text-foreground">
|
<p class="mt-6 max-w-lg text-base leading-8 text-foreground">
|
||||||
안녕하세요. 정보보안과 소프트웨어 엔지니어링을 공부하는 암냥입니다.
|
안녕하세요. 정보보안과 소프트웨어 엔지니어링을 공부하는 암냥입니다.
|
||||||
|
새로운 기술을 배우고, 머릿속의 아이디어를 실제로 작동하는 것으로
|
||||||
|
만드는 일을 좋아해요.
|
||||||
</p>
|
</p>
|
||||||
<section class="mt-16" aria-labelledby="experience-title">
|
<section class="mt-16" aria-labelledby="experience-title">
|
||||||
<div class="mb-5 flex items-baseline justify-between gap-4">
|
<div class="mb-5 flex items-baseline justify-between gap-4">
|
||||||
|
|
@ -70,11 +71,11 @@ import DDay from "./DDay.astro";
|
||||||
</AboutRow>
|
</AboutRow>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<div class="mt-6 flex flex-row items-center text-sm text-foreground/60">
|
<div class="mt-8 flex flex-row items-center text-sm text-foreground/60">
|
||||||
<a
|
<a
|
||||||
href="#experience"
|
href="#experience"
|
||||||
class="flex flex-row items-center underline underline-offset-4"
|
class="flex flex-row items-center underline underline-offset-4 hover:text-foreground"
|
||||||
><span>등등...</span>
|
><span>전체 타임라인 보기</span>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
class="h-4 text-foreground/40"
|
class="h-4 text-foreground/40"
|
||||||
|
|
@ -89,21 +90,26 @@ import DDay from "./DDay.astro";
|
||||||
<path d="M7 7h10v10"></path>
|
<path d="M7 7h10v10"></path>
|
||||||
</svg></a
|
</svg></a
|
||||||
>
|
>
|
||||||
<p class="ml-1"> 많은 여러가지의 활동을 해왔어요.</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="relative order-first h-[min(150vw,720px)] min-h-[600px] overflow-hidden lg:sticky lg:top-0 lg:order-none lg:h-[calc(100svh-64px)] lg:min-h-0 lg:self-start"
|
class="relative order-last h-[min(100vw,480px)] min-h-0 overflow-hidden bg-muted lg:sticky lg:top-0 lg:order-none lg:h-[calc(100svh-64px)] lg:min-h-0 lg:self-start"
|
||||||
aria-label="활동 사진"
|
aria-label="활동 사진"
|
||||||
>
|
>
|
||||||
<!-- <img
|
<img
|
||||||
class="absolute inset-0 h-full w-full select-none pointer-events-none object-contain"
|
class="absolute inset-0 h-full w-full select-none object-cover object-center"
|
||||||
src="/side.avif"
|
src="/about/vrchat.webp"
|
||||||
alt="활동 사진 콜라주"
|
alt="VRChat에서 촬영한 캐릭터 스크린샷"
|
||||||
width="3840"
|
width="1920"
|
||||||
height="4320"
|
height="1080"
|
||||||
/> -->
|
loading="lazy"
|
||||||
|
decoding="async"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
class="pointer-events-none absolute inset-0 bg-gradient-to-t from-background/35 via-transparent to-black/5"
|
||||||
|
aria-hidden="true"
|
||||||
|
></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
||||||
|
|
@ -105,14 +105,14 @@ const groups = [
|
||||||
{
|
{
|
||||||
name: "Project Sekai KR",
|
name: "Project Sekai KR",
|
||||||
value: "7354623251148069648",
|
value: "7354623251148069648",
|
||||||
href: "#",
|
copy: true,
|
||||||
icon: "project-sekai",
|
icon: "project-sekai",
|
||||||
tone: "blue",
|
tone: "blue",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Project Sekai JP",
|
name: "Project Sekai JP",
|
||||||
value: "729310364018688008",
|
value: "729310364018688008",
|
||||||
href: "#",
|
copy: true,
|
||||||
icon: "project-sekai",
|
icon: "project-sekai",
|
||||||
tone: "blue",
|
tone: "blue",
|
||||||
},
|
},
|
||||||
|
|
@ -152,7 +152,7 @@ const paths: Record<string, string> = {
|
||||||
};
|
};
|
||||||
---
|
---
|
||||||
|
|
||||||
<section id="contact" class="contact-section" aria-labelledby="contact-title">
|
<section id="contact" class="contact-section snap-start" aria-labelledby="contact-title">
|
||||||
<div class="contact-content">
|
<div class="contact-content">
|
||||||
<header class="contact-heading">
|
<header class="contact-heading">
|
||||||
<h2 id="contact-title">Contact<span aria-hidden="true">.</span></h2>
|
<h2 id="contact-title">Contact<span aria-hidden="true">.</span></h2>
|
||||||
|
|
@ -174,76 +174,161 @@ const paths: Record<string, string> = {
|
||||||
<ul class="contact-list">
|
<ul class="contact-list">
|
||||||
{group.items.map((item) => (
|
{group.items.map((item) => (
|
||||||
<li class="contact-row">
|
<li class="contact-row">
|
||||||
<a
|
{"copy" in item ? (
|
||||||
class="contact-link"
|
<button
|
||||||
href={item.href}
|
class="contact-link contact-copy-link"
|
||||||
target={
|
type="button"
|
||||||
"email" in item
|
data-contact-copy={item.value}
|
||||||
? undefined
|
aria-label={`${item.name} ${item.value} 복사`}
|
||||||
: "_blank"
|
|
||||||
}
|
|
||||||
rel={
|
|
||||||
"email" in item
|
|
||||||
? undefined
|
|
||||||
: "noopener noreferrer"
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class={`contact-icon tone-${item.tone}`}
|
|
||||||
aria-hidden="true"
|
|
||||||
>
|
>
|
||||||
{imageIcons[item.icon] ? (
|
<span
|
||||||
<img
|
class={`contact-icon tone-${item.tone}`}
|
||||||
src={
|
aria-hidden="true"
|
||||||
imageIcons[item.icon]
|
>
|
||||||
.src
|
{imageIcons[item.icon] ? (
|
||||||
}
|
<img
|
||||||
width="22"
|
src={
|
||||||
height="22"
|
imageIcons[item.icon]
|
||||||
alt=""
|
.src
|
||||||
class:list={{
|
}
|
||||||
"mono-icon":
|
width="22"
|
||||||
imageIcons[
|
height="22"
|
||||||
item.icon
|
alt=""
|
||||||
].monochrome,
|
class:list={{
|
||||||
}}
|
"mono-icon":
|
||||||
/>
|
imageIcons[
|
||||||
) : (
|
item.icon
|
||||||
|
].monochrome,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<svg
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="1.7"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d={paths[item.icon]}
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
<span class="contact-name">
|
||||||
|
{item.name}
|
||||||
|
</span>
|
||||||
|
<span class="contact-value">
|
||||||
|
{item.value}
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="contact-copy-indicator"
|
||||||
|
aria-hidden="true"
|
||||||
|
>
|
||||||
<svg
|
<svg
|
||||||
|
class="copy-symbol"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
fill="none"
|
fill="none"
|
||||||
stroke="currentColor"
|
stroke="currentColor"
|
||||||
stroke-width="1.7"
|
stroke-width="1.5"
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
>
|
>
|
||||||
<path
|
<rect
|
||||||
d={paths[item.icon]}
|
x="8"
|
||||||
|
y="8"
|
||||||
|
width="12"
|
||||||
|
height="12"
|
||||||
|
rx="2"
|
||||||
/>
|
/>
|
||||||
|
<path d="M16 8V4a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h4" />
|
||||||
|
</svg>
|
||||||
|
<svg
|
||||||
|
class="copied-symbol"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="1.8"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
>
|
||||||
|
<path d="m5 12 4 4L19 6" />
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
) : (
|
||||||
|
<a
|
||||||
|
class="contact-link"
|
||||||
|
href={item.href}
|
||||||
|
target={
|
||||||
|
"email" in item
|
||||||
|
? undefined
|
||||||
|
: "_blank"
|
||||||
|
}
|
||||||
|
rel={
|
||||||
|
"email" in item
|
||||||
|
? undefined
|
||||||
|
: "noopener noreferrer"
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class={`contact-icon tone-${item.tone}`}
|
||||||
|
aria-hidden="true"
|
||||||
|
>
|
||||||
|
{imageIcons[item.icon] ? (
|
||||||
|
<img
|
||||||
|
src={
|
||||||
|
imageIcons[item.icon]
|
||||||
|
.src
|
||||||
|
}
|
||||||
|
width="22"
|
||||||
|
height="22"
|
||||||
|
alt=""
|
||||||
|
class:list={{
|
||||||
|
"mono-icon":
|
||||||
|
imageIcons[
|
||||||
|
item.icon
|
||||||
|
].monochrome,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<svg
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="1.7"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d={paths[item.icon]}
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
<span class="contact-name">
|
||||||
|
{item.name}
|
||||||
|
</span>
|
||||||
|
<span class="contact-value">
|
||||||
|
{item.value}
|
||||||
|
</span>
|
||||||
|
{!("email" in item) && (
|
||||||
|
<svg
|
||||||
|
class="contact-arrow"
|
||||||
|
aria-hidden="true"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="1.5"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
>
|
||||||
|
<path d="M7 17 17 7M7 7h10v10" />
|
||||||
</svg>
|
</svg>
|
||||||
)}
|
)}
|
||||||
</span>
|
</a>
|
||||||
<span class="contact-name">
|
)}
|
||||||
{item.name}
|
|
||||||
</span>
|
|
||||||
<span class="contact-value">
|
|
||||||
{item.value}
|
|
||||||
</span>
|
|
||||||
{!("email" in item) && (
|
|
||||||
<svg
|
|
||||||
class="contact-arrow"
|
|
||||||
aria-hidden="true"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-width="1.5"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
>
|
|
||||||
<path d="M7 17 17 7M7 7h10v10" />
|
|
||||||
</svg>
|
|
||||||
)}
|
|
||||||
</a>
|
|
||||||
{"email" in item && (
|
{"email" in item && (
|
||||||
<button
|
<button
|
||||||
class="contact-copy"
|
class="contact-copy"
|
||||||
|
|
@ -309,9 +394,7 @@ const paths: Record<string, string> = {
|
||||||
<style>
|
<style>
|
||||||
.contact-section {
|
.contact-section {
|
||||||
--contact-top-spacing: clamp(48px, 7vw, 88px);
|
--contact-top-spacing: clamp(48px, 7vw, 88px);
|
||||||
min-height: 100%;
|
min-height: calc(100svh - 64px);
|
||||||
/* A viewport-spanning snap area permits free scrolling through the links. */
|
|
||||||
scroll-snap-align: start;
|
|
||||||
padding: var(--contact-top-spacing) clamp(24px, 5.208vw, 100px) 32px;
|
padding: var(--contact-top-spacing) clamp(24px, 5.208vw, 100px) 32px;
|
||||||
}
|
}
|
||||||
.contact-content {
|
.contact-content {
|
||||||
|
|
@ -320,10 +403,6 @@ const paths: Record<string, string> = {
|
||||||
}
|
}
|
||||||
.contact-heading {
|
.contact-heading {
|
||||||
display: flow-root;
|
display: flow-root;
|
||||||
/* Keep the snap target smaller than the viewport so entry stops at the title. */
|
|
||||||
scroll-snap-align: start;
|
|
||||||
scroll-snap-stop: always;
|
|
||||||
scroll-margin-top: var(--contact-top-spacing);
|
|
||||||
padding-bottom: 32px;
|
padding-bottom: 32px;
|
||||||
border-bottom: 1px solid var(--border);
|
border-bottom: 1px solid var(--border);
|
||||||
}
|
}
|
||||||
|
|
@ -393,6 +472,15 @@ const paths: Record<string, string> = {
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
.contact-copy-link {
|
||||||
|
width: 100%;
|
||||||
|
border: 0;
|
||||||
|
background: transparent;
|
||||||
|
color: inherit;
|
||||||
|
font: inherit;
|
||||||
|
text-align: left;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
.contact-row:has(.contact-copy) .contact-link {
|
.contact-row:has(.contact-copy) .contact-link {
|
||||||
grid-template-columns: 22px auto minmax(0, 1fr);
|
grid-template-columns: 22px auto minmax(0, 1fr);
|
||||||
padding-right: 0;
|
padding-right: 0;
|
||||||
|
|
@ -463,6 +551,22 @@ const paths: Record<string, string> = {
|
||||||
color: var(--muted-foreground);
|
color: var(--muted-foreground);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
.contact-copy-indicator {
|
||||||
|
display: grid;
|
||||||
|
place-items: center;
|
||||||
|
width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
color: var(--muted-foreground);
|
||||||
|
transition: color 160ms;
|
||||||
|
}
|
||||||
|
.contact-copy-link:hover .contact-copy-indicator {
|
||||||
|
color: var(--foreground);
|
||||||
|
}
|
||||||
|
.contact-copy-indicator svg {
|
||||||
|
width: 17px;
|
||||||
|
height: 17px;
|
||||||
|
grid-area: 1 / 1;
|
||||||
|
}
|
||||||
.contact-copy:hover {
|
.contact-copy:hover {
|
||||||
color: var(--foreground);
|
color: var(--foreground);
|
||||||
background: color-mix(in srgb, var(--foreground) 7%, transparent);
|
background: color-mix(in srgb, var(--foreground) 7%, transparent);
|
||||||
|
|
@ -472,10 +576,12 @@ const paths: Record<string, string> = {
|
||||||
height: 17px;
|
height: 17px;
|
||||||
}
|
}
|
||||||
.copied-symbol,
|
.copied-symbol,
|
||||||
.contact-copy[data-copied] .copy-symbol {
|
.contact-copy[data-copied] .copy-symbol,
|
||||||
|
.contact-copy-link[data-copied] .copy-symbol {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
.contact-copy[data-copied] .copied-symbol {
|
.contact-copy[data-copied] .copied-symbol,
|
||||||
|
.contact-copy-link[data-copied] .copied-symbol {
|
||||||
display: block;
|
display: block;
|
||||||
color: #46916c;
|
color: #46916c;
|
||||||
}
|
}
|
||||||
|
|
@ -540,6 +646,10 @@ const paths: Record<string, string> = {
|
||||||
grid-column: 3;
|
grid-column: 3;
|
||||||
grid-row: 1 / 3;
|
grid-row: 1 / 3;
|
||||||
}
|
}
|
||||||
|
.contact-copy-link .contact-copy-indicator {
|
||||||
|
grid-column: 3;
|
||||||
|
grid-row: 1 / 3;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@media (prefers-reduced-motion: reduce) {
|
@media (prefers-reduced-motion: reduce) {
|
||||||
.contact-row,
|
.contact-row,
|
||||||
|
|
@ -556,27 +666,30 @@ const paths: Record<string, string> = {
|
||||||
const contactStatus =
|
const contactStatus =
|
||||||
document.querySelector<HTMLElement>(".contact-status");
|
document.querySelector<HTMLElement>(".contact-status");
|
||||||
document
|
document
|
||||||
.querySelectorAll<HTMLButtonElement>("[data-contact-email]")
|
.querySelectorAll<HTMLButtonElement>(
|
||||||
|
"[data-contact-email], [data-contact-copy]",
|
||||||
|
)
|
||||||
.forEach((button) => {
|
.forEach((button) => {
|
||||||
let resetTimer: ReturnType<typeof setTimeout>;
|
let resetTimer: ReturnType<typeof setTimeout>;
|
||||||
button.addEventListener("click", async () => {
|
button.addEventListener("click", async () => {
|
||||||
const email = button.dataset.contactEmail;
|
const value =
|
||||||
if (!email) return;
|
button.dataset.contactEmail ?? button.dataset.contactCopy;
|
||||||
|
if (!value) return;
|
||||||
try {
|
try {
|
||||||
await navigator.clipboard.writeText(email);
|
await navigator.clipboard.writeText(value);
|
||||||
clearTimeout(resetTimer);
|
clearTimeout(resetTimer);
|
||||||
button.dataset.copied = "true";
|
button.dataset.copied = "true";
|
||||||
button.setAttribute("aria-label", `${email} 복사 완료`);
|
button.setAttribute("aria-label", `${value} 복사 완료`);
|
||||||
if (contactStatus)
|
if (contactStatus)
|
||||||
contactStatus.textContent = `${email} 주소를 복사했어요.`;
|
contactStatus.textContent = `${value}를 복사했어요.`;
|
||||||
resetTimer = setTimeout(() => {
|
resetTimer = setTimeout(() => {
|
||||||
delete button.dataset.copied;
|
delete button.dataset.copied;
|
||||||
button.setAttribute("aria-label", `${email} 복사`);
|
button.setAttribute("aria-label", `${value} 복사`);
|
||||||
}, 2000);
|
}, 2000);
|
||||||
} catch {
|
} catch {
|
||||||
if (contactStatus)
|
if (contactStatus)
|
||||||
contactStatus.textContent =
|
contactStatus.textContent =
|
||||||
"복사하지 못했어요. 이메일 주소를 직접 선택해 복사해주세요.";
|
"복사하지 못했어요. 값을 직접 선택해 복사해주세요.";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ const roles = ["Broadcast Manager", "ARG Creator", "Developer"];
|
||||||
|
|
||||||
<section
|
<section
|
||||||
id="projects"
|
id="projects"
|
||||||
class="min-h-full snap-start bg-background text-foreground"
|
class="min-h-[calc(100svh-64px)] snap-start bg-background text-foreground"
|
||||||
aria-labelledby="projects-title"
|
aria-labelledby="projects-title"
|
||||||
>
|
>
|
||||||
<div class="grid min-h-full grid-cols-1 lg:grid-cols-2">
|
<div class="grid min-h-full grid-cols-1 lg:grid-cols-2">
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ const daysUntilYearEnd = Math.ceil(
|
||||||
<section
|
<section
|
||||||
id="experience"
|
id="experience"
|
||||||
data-node-id="4:104"
|
data-node-id="4:104"
|
||||||
class="min-h-full snap-start snap-always bg-background text-foreground"
|
class="min-h-[calc(100svh-64px)] snap-start bg-background text-foreground"
|
||||||
aria-labelledby="experience-title"
|
aria-labelledby="experience-title"
|
||||||
>
|
>
|
||||||
<div class="grid min-h-full grid-cols-1 lg:grid-cols-2">
|
<div class="grid min-h-full grid-cols-1 lg:grid-cols-2">
|
||||||
|
|
@ -130,7 +130,7 @@ const daysUntilYearEnd = Math.ceil(
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="relative order-first h-[min(150vw,720px)] min-h-[600px] overflow-hidden lg:sticky lg:top-0 lg:order-none lg:h-[calc(100svh-64px)] lg:min-h-0 lg:self-start"
|
class="relative order-last h-[min(100vw,480px)] min-h-0 overflow-hidden lg:sticky lg:top-0 lg:order-none lg:h-[calc(100svh-64px)] lg:min-h-0 lg:self-start"
|
||||||
aria-label="활동 사진"
|
aria-label="활동 사진"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ const navigationItems = [
|
||||||
{ label: "Home", href: "#home" },
|
{ label: "Home", href: "#home" },
|
||||||
{ label: "About", href: "#about" },
|
{ label: "About", href: "#about" },
|
||||||
{ label: "Projects", href: "#projects" },
|
{ label: "Projects", href: "#projects" },
|
||||||
{ label: "Timeline", href: "#timeline" },
|
{ label: "Timeline", href: "#experience" },
|
||||||
{ label: "Contact", href: "#contact" },
|
{ label: "Contact", href: "#contact" },
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
id="home"
|
id="home"
|
||||||
data-node-id="1:3"
|
data-node-id="1:3"
|
||||||
data-name="imnyang"
|
data-name="imnyang"
|
||||||
class="flex h-full min-h-0 snap-start snap-always flex-col overflow-hidden"
|
class="flex h-[calc(100svh-64px)] min-h-0 snap-start flex-col overflow-hidden"
|
||||||
>
|
>
|
||||||
<section
|
<section
|
||||||
class="flex h-[250px] min-h-[250px] min-w-0 flex-none basis-[250px] items-center overflow-clip px-[clamp(26px,2.5vw,48px)] max-md:px-6"
|
class="flex h-[250px] min-h-[250px] min-w-0 flex-none basis-[250px] items-center overflow-clip px-[clamp(26px,2.5vw,48px)] max-md:px-6"
|
||||||
|
|
|
||||||
|
|
@ -80,3 +80,37 @@
|
||||||
--mono-filter: invert(1);
|
--mono-filter: invert(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
scroll-behavior: smooth;
|
||||||
|
scroll-padding-top: 64px;
|
||||||
|
}
|
||||||
|
|
||||||
|
html::-webkit-scrollbar {
|
||||||
|
width: 19px;
|
||||||
|
height: 11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
html::-webkit-scrollbar-track {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
html::-webkit-scrollbar-thumb {
|
||||||
|
background: var(--scrollbar);
|
||||||
|
border: 5px solid var(--background);
|
||||||
|
border-radius: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
html::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: var(--scrollbar-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
scrollbar-color: var(--scrollbar) var(--background);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
html {
|
||||||
|
scroll-behavior: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -57,16 +57,12 @@ import "@/globals.css";
|
||||||
|
|
||||||
if (scrollContainer && window.location.hash) {
|
if (scrollContainer && window.location.hash) {
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
requestAnimationFrame(() => {
|
const initialTarget = document.querySelector<HTMLElement>(
|
||||||
const initialTarget = document.querySelector<HTMLElement>(
|
window.location.hash,
|
||||||
window.location.hash,
|
);
|
||||||
);
|
if (initialTarget) {
|
||||||
|
scrollContainer.scrollTop = getTargetScrollTop(initialTarget);
|
||||||
if (initialTarget) {
|
}
|
||||||
scrollContainer.scrollTop =
|
|
||||||
getTargetScrollTop(initialTarget);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue