/* ==========================================================================
   sections.css — 헤더 · 섹션 1~6 레이아웃
   ========================================================================== */

/* --------------------------------------------------------------------------
   헤더 / 네비게이션  (Figma: 높이 80px, 검정 배경)
   -------------------------------------------------------------------------- */

/*
  Figma(1:576): HERO 위에서는 배경 없이 흰 하단 보더만.
  스크롤해서 HERO를 벗어나면 검정 배경으로 전환한다(가독성).
*/
.site-header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  height: var(--header-h);
  background: transparent;
  /* 얇은 실선 — 1px 는 굵어 보여 반투명으로 낮춘다 */
  border-bottom: 1px solid rgba(255, 255, 255, 0.45);
  transition: background-color var(--dur-base) var(--ease-out),
    border-color var(--dur-base) var(--ease-out);
}

.site-header.is-scrolled {
  background: var(--c-black);
  border-bottom-color: transparent;
}

.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 100%;
}

.site-header__logo {
  display: block;
  width: 120px;
  flex-shrink: 0;
}

.site-header__logo img {
  width: 100%;
  height: auto;
}

.site-nav__list {
  display: flex;
  gap: 44px;
}

.site-nav__link {
  position: relative;
  font-family: var(--font-en);
  /* 굵기를 낮추고 자간을 벌려 답답하지 않게 */
  font-weight: 400;
  font-size: var(--fs-20);
  letter-spacing: 1px;
  color: var(--c-white);
  transition: opacity var(--dur-fast) var(--ease-out);
}

/* 활성/호버 시 하단 밑줄 */
.site-nav__link::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -6px;
  width: 100%;
  height: 2px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur-base) var(--ease-out);
}

.site-nav__link:hover::after,
.site-nav__link.is-active::after {
  transform: scaleX(1);
}

.site-nav__link:hover {
  opacity: 0.75;
}

/* 모바일 햄버거 — 데스크탑에서는 숨김 */
.nav-toggle {
  display: none;
  width: 44px;
  height: 44px;
  position: relative;
}

.nav-toggle span,
.nav-toggle span::before,
.nav-toggle span::after {
  position: absolute;
  left: 50%;
  width: 24px;
  height: 2px;
  background: var(--c-white);
  transform: translateX(-50%);
  transition: transform var(--dur-base) var(--ease-out),
    opacity var(--dur-fast) var(--ease-out);
}

.nav-toggle span {
  top: 50%;
  margin-top: -1px;
}

.nav-toggle span::before,
.nav-toggle span::after {
  content: "";
  left: 0;
  transform: none;
}

.nav-toggle span::before { top: -8px; }
.nav-toggle span::after  { top: 8px; }

.nav-toggle[aria-expanded="true"] span {
  background: transparent;
}
.nav-toggle[aria-expanded="true"] span::before {
  transform: translateY(8px) rotate(45deg);
}
.nav-toggle[aria-expanded="true"] span::after {
  transform: translateY(-8px) rotate(-45deg);
}

/* ==========================================================================
   1. HERO
   ========================================================================== */

.hero {
  position: relative;
  height: 100vh;
  min-height: 600px;
  overflow: hidden;
  display: grid;
  place-items: center;
}

/* 배경 하늘 — 풀블리드 */
.hero__sky {
  position: absolute;
  inset: 0;
  z-index: 0;
}

.hero__sky img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* --------------------------------------------------------------------------
   구름 패럴랙스

   깊이 표현: Figma의 opacity 를 원근으로 해석해
   가까운(진한) 구름일수록 빠르게, 먼(흐린) 구름일수록 느리게 흐른다.

   구조: .hero__cloud 는 이미지 2장을 가로로 이어붙인 "레인"이다.
   레인 전체를 -50% 만큼 이동시키면 둘째 장이 정확히 첫 장 자리에 오므로
   그 시점에 처음으로 되돌려도 이음매가 보이지 않는다.
   -------------------------------------------------------------------------- */

.hero__clouds {
  position: absolute;
  inset: 0;
  z-index: 1;
  overflow: hidden;
  pointer-events: none;
}

/*
  레인은 같은 이미지 3장을 이어붙인다(폭 = --w × 3).

  3장인 이유: 한 장 폭(--w)을 -33.333%(=한 장) 만큼 이동시켜 되감으므로,
  이동 중 어느 시점에도 화면(100vw)을 덮으려면 남은 2장이 100vw 이상이어야 한다.
  → --w 를 50vw 이상으로 두면 2장 = 100vw 이상이 보장된다.
*/
.hero__cloud {
  position: absolute;
  left: 0;
  display: flex;
  width: calc(var(--w) * 3);
  animation-name: cloud-flow;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
  will-change: transform;
}

.hero__cloud img {
  width: var(--w);
  height: auto;
  flex-shrink: 0;
}

/*
  한 장 폭만큼(-33.333%) 왼쪽에서 시작해 0 으로 흘러간다.
  3장이 동일하므로 되감기는 순간의 화면이 완전히 같아 이음매가 없다.
*/
@keyframes cloud-flow {
  from { transform: translate3d(-33.3333%, 0, 0); }
  to   { transform: translate3d(0, 0, 0); }
}

/*
  레인마다 폭·위치·속도를 다르게 준다.
  --w 는 구름 한 장의 화면 대비 폭(1920 기준 환산).
*/

/* 가장 가까움 — 크고 빠르다 (Figma cloud4) */
.hero__cloud--near {
  --w: 62vw;
  bottom: -6%;
  opacity: 0.75;
  animation-duration: 50s;
}

/* 가까움 (Figma cloud1) */
.hero__cloud--mid {
  --w: 72vw;
  top: 58%;
  opacity: 0.45;
  animation-duration: 75s;
}

/* 가장 멈 — 흐리고 느리다 (Figma cloud3) */
.hero__cloud--far {
  --w: 55vw;
  top: 8%;
  opacity: 0.3;
  animation-duration: 115s;
}

/* 접근성: 동작 줄이기 설정이면 흐름을 멈춘다 */
@media (prefers-reduced-motion: reduce) {
  .hero__cloud {
    animation: none;
    transform: translate3d(-33.3333%, 0, 0);
  }
}

/* --------------------------------------------------------------------------
   인트로 연출

   하늘만 잠시 보였다가 → 타이틀 → 문구 박스 → 헤더·스크롤 순으로
   흐릿한 상태에서 초점이 맞듯 나타난다.
   .is-intro 는 등장 전 상태이며, JS 가 단계별로 .is-in 을 붙인다.
   -------------------------------------------------------------------------- */

/* 등장 전 상태 — .is-in 이 붙으면 해제된다 */
.is-intro .intro-item:not(.is-in) {
  opacity: 0;
  filter: blur(14px);
  transform: translateY(14px) scale(1.04);
}

.intro-item {
  transition: opacity 900ms var(--ease-out),
    filter 900ms var(--ease-out),
    transform 900ms var(--ease-out);
}

/*
  :not(.is-in) 규칙들보다 우선하도록 선택자를 맞춘다.

  filter 는 blur(0) 이라도 남아 있으면 자식의 backdrop-filter 가
  페이지 배경 대신 이 레이어를 샘플링해 굴절이 사라진다.
  → 등장이 끝나면 filter 를 완전히 없앤다.
*/
.is-intro .intro-item.is-in,
.intro-item.is-in {
  opacity: 1;
  filter: none;
  transform: none;
}

/*
  유리 박스처럼 자식이 backdrop-filter 를 쓰는 요소는
  blur 없이 투명도·이동으로만 등장시킨다.
*/
.is-intro .intro-item--noblur:not(.is-in) {
  filter: none;
}

.intro-item--noblur {
  transition: opacity 900ms var(--ease-out),
    transform 900ms var(--ease-out);
}

/*
  헤더는 position:fixed 라 transform 이 남으면 위치가 어긋난다.
  이동 없이 흐림·투명도로만 등장시킨다.
*/
.is-intro .site-header.intro-item:not(.is-in) {
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  .is-intro .intro-item,
  .intro-item {
    opacity: 1;
    filter: none;
    transform: none;
    transition: none;
  }
}

/* 중앙 컨텐츠 */
.hero__inner {
  position: relative;
  z-index: 2;
  text-align: center;
  padding-inline: 20px;
}

/* 타이핑 커서 */
.hero__lead-text .type-caret {
  display: inline-block;
  width: 2px;
  height: 1em;
  margin-left: 2px;
  translate: 0 0.12em;
  background: currentColor;
  animation: caret-blink 900ms steps(1) infinite;
}

@keyframes caret-blink {
  50% { opacity: 0; }
}

/* "MOVE TO THE NEXT" — 이미지 배경을 글자에 clip */
.hero__title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(2.5rem, 5vw, var(--fs-hero));
  /* 자간을 좁혀 글자를 모아준다 */
  letter-spacing: -0.045em;
  line-height: 1;
  background-image: url("../assets/images/hero-title-fill.webp");
  background-size: cover;
  background-position: center;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  /*
    background-clip:text 사용 시 text-shadow 는 글자가 아닌 박스에 걸려
    Figma의 그림자를 재현할 수 없다 → drop-shadow 필터로 대체.
    번짐(blur)을 줄이고 불투명도를 올려 또렷한 그림자로.
  */
  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.3));
}

/* 배경 이미지가 로드되지 않을 때를 대비한 폴백 */
@supports not ((-webkit-background-clip: text) or (background-clip: text)) {
  .hero__title {
    color: var(--c-white);
    background: none;
  }
}

/* --------------------------------------------------------------------------
   알약형 유리(glass) 문구 박스

   3겹 구조로 유리를 표현한다.
     1) .hero__lead        — 테두리 하이라이트 + 그림자 (유리의 두께)
     2) .hero__lead-glass  — 배경을 굴절·블러 (유리를 통과한 빛)
     3) .hero__lead-text   — 텍스트 (왜곡되지 않아야 하므로 분리)
   -------------------------------------------------------------------------- */

/*
  타이핑 중에도 박스 크기가 변하지 않도록 폭을 고정한다.
  (폭이 변하면 굴절 변위맵과 어긋나 이음매가 보인다)
*/
.hero__lead {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* 글자가 늘어나는 만큼 박스도 함께 넓어진다 */
  max-width: min(calc(974px * var(--fs-scale)), 100%);
  min-height: calc(100px * var(--fs-scale));
  margin-top: calc(26px * var(--fs-scale));
  padding: calc(18px * var(--fs-scale)) calc(44px * var(--fs-scale));
  border-radius: var(--radius-pill);
  color: var(--c-white);
  font-weight: 300;
  font-size: clamp(1rem, 1.7vw, var(--fs-32));
  letter-spacing: -0.02em;
  line-height: 1.35;
  isolation: isolate;

  /*
    inset 하이라이트는 알약 안쪽 가장자리를 따라 얇은 선을 그려
    "굴절 띠"처럼 보이게 만든다. 바깥 그림자만 남긴다.
  */
  box-shadow: 0 6px 20px rgba(31, 74, 138, 0.13);
}

/* 유리 몸통 — 굴절 레이어를 담고 표면 하이라이트를 얹는다 */
.hero__lead-glass {
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  overflow: hidden;

  /*
    유리 자체는 거의 무색이어야 한다.
    흰 그라디언트를 진하게 깔면 뿌연 플라스틱이 되므로 아주 옅게만.
  */
  background: linear-gradient(
    160deg,
    rgba(255, 255, 255, 0.14) 0%,
    rgba(255, 255, 255, 0.04) 38%,
    rgba(255, 255, 255, 0.02) 62%,
    rgba(255, 255, 255, 0.1) 100%
  );

  /*
    변위맵 기반 굴절 + 약한 블러/채도.
    url() 필터가 배경을 실제로 밀어내므로 테두리에서 상이 휘어 보인다.
  */
  backdrop-filter: url("#glass-refraction") blur(0.5px) saturate(125%) brightness(1.02);
  -webkit-backdrop-filter: url("#glass-refraction") blur(0.5px) saturate(125%) brightness(1.02);
}

/* 필터 미지원 브라우저 폴백 — 굴절 대신 블러만 */
@supports not (backdrop-filter: url("#glass-refraction")) {
  .hero__lead-glass {
    backdrop-filter: blur(6px) saturate(150%);
    -webkit-backdrop-filter: blur(6px) saturate(150%);
  }
}

/*
  상단 스페큘러 — 유리 윗면을 스치는 얇은 빛.
  넓은 띠로 깔면 플라스틱처럼 보이므로, 위쪽 곡면에만 얇게 얹는다.
*/
.hero__lead-glass::after {
  content: "";
  position: absolute;
  inset: 1px 8% auto;
  height: 30%;
  border-radius: 999px;
  background: linear-gradient(
    to bottom,
    rgba(255, 255, 255, 0.34),
    rgba(255, 255, 255, 0.05) 55%,
    rgba(255, 255, 255, 0)
  );
  /* 가운데가 가장 밝고 양끝으로 사라지게 */
  -webkit-mask-image: linear-gradient(
    to right, transparent, #000 22%, #000 78%, transparent
  );
  mask-image: linear-gradient(
    to right, transparent, #000 22%, #000 78%, transparent
  );
  pointer-events: none;
}

/* 유리가 옅어진 만큼 글자는 그림자로 가독성을 확보한다 */
.hero__lead-text {
  position: relative;
  z-index: 1;
  /* 비어 있어도 한 줄 높이를 유지해 박스가 찌그러지지 않는다 */
  min-height: 1em;
  /* 한 줄로 유지 (줄바꿈되면 박스 높이가 변해 변위맵과 어긋난다) */
  white-space: nowrap;
  text-shadow: 0 1px 6px rgba(16, 52, 104, 0.5);
}

.hero__lead strong {
  font-weight: 700;
}

/* backdrop-filter 미지원 브라우저 폴백 */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .hero__lead-glass {
    background: rgba(255, 255, 255, 0.26);
  }
}

/* 하단 스크롤 인디케이터 */
.hero__scroll {
  position: absolute;
  left: 50%;
  bottom: 6.5%;
  z-index: 2;
  translate: -50% 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  color: var(--c-white);
}

.hero__mouse {
  position: relative;
  width: 34px;
  height: 54px;
  border: 3px solid var(--c-white);
  border-radius: 40px;
}

/* 마우스 휠 — 위아래로 반복 이동 */
.hero__mouse::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 10px;
  width: 3px;
  height: 10px;
  margin-left: -1.5px;
  background: var(--c-white);
  border-radius: 2px;
  animation: mouse-wheel 1.8s ease-in-out infinite;
}

@keyframes mouse-wheel {
  0%, 100% { transform: translateY(0);    opacity: 1; }
  50%      { transform: translateY(10px); opacity: 0.3; }
}

.hero__scroll-text {
  font-family: var(--font-mont);
  font-weight: 500;
  font-size: var(--fs-16);
  letter-spacing: 0.02em;
}

/* ==========================================================================
   섹션 2~6 공통 — 격자 배경
   ========================================================================== */

.section {
  position: relative;
  padding-block: 120px;
  overflow: hidden;
}

/*
  격자 배경.

  섹션마다 깔면 섹션 높이가 제각각이라 cover 배율이 달라져
  칸 크기가 섹션마다 바뀌고 경계에서 어긋난다.
  → ABOUT~PROJECTS 를 감싸는 래퍼에 한 장만 깔아 전체를 하나로 잇는다.

  fixed 로 뷰포트에 고정하면 스크롤 중에도 격자가 흔들리지 않고,
  섹션 경계에서 이어지지 않는 문제 자체가 사라진다.
*/
.grid-bg {
  position: relative;
}

.grid-bg::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  /*
    이음매 없는 타일(원본에서 정수 칸만큼 잘라낸 것)을 반복한다.
    칸 크기가 px 로 고정되므로 섹션 높이와 무관하게 항상 일정하고,
    래퍼 하나에만 깔리므로 섹션 경계에서도 끊기지 않는다.
  */
  background-image: url("../assets/images/grid-tile.webp");
  background-size: 58px 58px; /* 타일 = 격자 한 칸 */
  background-position: top center;
  background-repeat: repeat;
  mix-blend-mode: lighten;
  pointer-events: none;
}

.section > .container {
  position: relative;
  z-index: 1;
}

/* 섹션 타이틀 영역 */
/*
  섹션 헤드 — 타이틀은 왼쪽, 설명 문구는 오른쪽 끝에 붙는다.
  문구가 없는 섹션은 타이틀만 있으므로 그대로 왼쪽 정렬된다.
*/
.section__head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 40px;
  margin-bottom: 60px;
}

.section__lead {
  text-align: right;
  /* 타이틀 아래쪽 선에 맞춰 보이도록 살짝 올린다 */
  padding-bottom: 6px;
}

.section__lead-en {
  font-family: var(--font-en);
  font-weight: 500;
  font-size: var(--fs-24);
  letter-spacing: 0.02em;
  color: var(--theme);
  line-height: 1;
}

.section__lead-kr {
  margin-top: 14px;
  font-size: var(--fs-16);
  letter-spacing: -0.02em;
  line-height: 1.6;
  color: var(--c-text);
}

/* ==========================================================================
   2. ABOUT
   ========================================================================== */

.about { --theme: var(--c-about); --theme-rgb: 51, 80, 175; }

/* 타이틀 우측의 무한 롤링 띠 */
.about__head {
  display: flex;
  align-items: stretch;
  gap: 60px;
  margin-bottom: 60px;
}

/* 타이틀은 고정 폭, 마퀴가 남은 공간을 차지 */
.about__head .section-title {
  flex-shrink: 0;
}

.marquee {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  /* 타이틀 박스(120px)보다 낮게 잡아 가볍게 보이도록 */
  height: 84px;
  align-self: center;
  background: var(--c-white);
  border: 2px solid var(--theme);
  overflow: hidden;
}

.marquee__track {
  display: flex;
  flex-shrink: 0;
  gap: 40px;
  padding-right: 40px;
  white-space: nowrap;
  animation: marquee 18s linear infinite;
}

.marquee__track span {
  font-family: var(--font-en);
  font-weight: 300;
  font-size: clamp(1.5rem, 2.6vw, calc(46px * var(--fs-scale)));
  color: var(--theme);
  line-height: 1;
}

/* 왼쪽 → 오른쪽 흐름 (트랙 2개가 서로를 메운다) */
@keyframes marquee {
  from { transform: translateX(-100%); }
  to   { transform: translateX(0); }
}

@media (prefers-reduced-motion: reduce) {
  .marquee__track { animation: none; }
}

/* 본문 2단 그리드 */
.about__body {
  display: grid;
  grid-template-columns: calc(410px * var(--fs-scale)) 1fr;
  gap: calc(60px * var(--fs-scale));
  /* 좌우 열 높이를 맞춰 LINK 를 설명 박스 하단에 정렬한다 */
  align-items: stretch;
}

/* 사진은 위, LINK 는 아래로 밀어붙인다 */
.about__aside {
  display: flex;
  flex-direction: column;
}

.about__profile {
  width: 100%;
  aspect-ratio: 1;
  border-radius: var(--radius-card);
  object-fit: cover;
}

/* LINK 영역 */
.about__links {
  /* 남는 공간을 위로 몰아 설명 박스 본문 하단과 맞춘다 */
  margin-top: auto;
  padding-top: calc(50px * var(--fs-scale));
}

.about__links-title {
  font-family: var(--font-mont);
  font-weight: 700;
  font-size: var(--fs-40);
  letter-spacing: -0.03em;
  color: var(--theme);
  line-height: 1;
}

/* LINK 라벨 + 화살표를 한 덩어리로 묶어 아이콘 왼쪽에 세운다 */
.about__links {
  display: flex;
  align-items: center;
  gap: 24px;
}

.about__links-label {
  flex-shrink: 0;
}

.about__links-arrow {
  width: 110px;
  margin-top: 8px;
}

.about__links-list {
  display: flex;
  gap: 16px;
}

.about__link-item {
  display: grid;
  place-items: center;
  width: 68px;
  height: 68px;
  border-radius: 10px;
  overflow: hidden;
  transition: transform var(--dur-base) var(--ease-out),
    box-shadow var(--dur-base) var(--ease-out);
}

.about__link-item:hover {
  transform: translateY(-4px);
  box-shadow: 0 4px 10px rgba(51, 80, 175, 0.25);
}

.about__link-item--github { background: var(--c-black); }

.about__link-item img {
  width: 54px;
  height: 54px;
  object-fit: contain;
}

/* 벨로그 아이콘은 자체 배경이 있어 꽉 채운다 */
.about__link-item--velog img {
  width: 100%;
  height: 100%;
}

/* 우측 유리 카드 */
.about__card {
  padding: calc(56px * var(--fs-scale)) calc(60px * var(--fs-scale));
}

.about__intro {
  font-weight: 300;
  font-size: clamp(1.75rem, 2.9vw, var(--fs-56));
  letter-spacing: -0.03em;
  line-height: 1.2;
}

/* 롤링 문구 + "웹 퍼블리셔 입니다." 한 줄 */
/* Figma: 롤링 박스와 "웹 퍼블리셔 입니다."가 한 줄에 나란히 */
.about__rolling-line {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 20px;
  margin-top: 20px;
}

/* 세로로 롤링되는 파란 박스 */
.rolling {
  position: relative;
  /* 넓은 화면에서는 Figma의 410px, 좁아지면 함께 줄어든다 */
  width: clamp(240px, 28vw, calc(410px * var(--fs-scale)));
  height: 100px;
  background: var(--theme);
  border-radius: 10px;
  overflow: hidden;
  flex-shrink: 1;
  min-width: 0;
}

.rolling__list {
  animation: rolling 5s cubic-bezier(0.7, 0, 0.3, 1) infinite;
}

.rolling__list li {
  display: grid;
  place-items: center;
  height: 100px;
  color: var(--c-white);
  font-weight: 500;
  font-size: clamp(1.5rem, 2.6vw, var(--fs-50));
  letter-spacing: -0.03em;
  white-space: nowrap;
}

/*
  3개 항목(원본 2개 + 첫 항목 복제)을 순환시켜
  마지막에서 처음으로 끊김 없이 이어지게 한다.
*/
@keyframes rolling {
  0%,   40%  { transform: translateY(0); }
  50%,  90%  { transform: translateY(-100px); }
  100%       { transform: translateY(-200px); }
}

@media (prefers-reduced-motion: reduce) {
  .rolling__list { animation: none; }
}

.about__role {
  font-weight: 300;
  font-size: clamp(1.75rem, 2.9vw, var(--fs-56));
  letter-spacing: -0.03em;
  line-height: 1.2;
  white-space: nowrap;
}

.about__role b {
  font-weight: 500;
  color: var(--theme);
}

.about__divider {
  height: 2px;
  margin-top: 44px;
  background: var(--theme);
  border: 0;
}

.about__desc {
  margin-top: 44px;
  font-size: var(--fs-20);
  letter-spacing: -0.03em;
  line-height: 1.4;
}

.about__desc p + p {
  margin-top: 1.4em;
}

/* ==========================================================================
   3. EXPERIENCE
   ========================================================================== */

.experience { --theme: var(--c-experience); --theme-rgb: 216, 105, 8; }

/*
  EDUCATION 은 항목명이 길어 좁으면 단어가 끊긴다.
  → LICENCE 보다 넉넉하게 배분한다.
*/
.experience__grid {
  display: grid;
  grid-template-columns: 1.6fr 1fr;
  gap: 16px 36px;
}

.experience__card {
  padding: 30px 40px 32px;
  min-height: 0;
}

/* CAREER 카드는 전체 폭 */
.experience__card--full {
  grid-column: 1 / -1;
}

/* 라벨 + 한글 보조 텍스트 */
.experience__head {
  display: flex;
  align-items: center;
  gap: 16px;
}

.experience__head-kr {
  font-weight: 500;
  font-size: var(--fs-24);
  letter-spacing: -0.02em;
  color: var(--theme);
}

/* 타임라인 */
.timeline {
  /* 점 지름 — 선 위치 계산에 함께 쓰인다 */
  --dot: calc(30px * var(--fs-scale));

  position: relative;
  display: flex;
  justify-content: space-between;
  margin-top: calc(34px * var(--fs-scale));
  /* 항목 텍스트가 줄바꿈되지 않도록 여백을 줄인다 */
  padding-inline: 14px;
}

/*
  가로 연결선 — 첫 점부터 마지막 점까지.
  화면에 들어오면 왼쪽에서 오른쪽으로 그어진다.
*/
.timeline::before {
  content: "";
  position: absolute;
  /* 첫 점 ~ 마지막 점 중심 (JS 가 실측해 넣는다) */
  left: var(--line-left, 30px);
  right: var(--line-right, 30px);
  /* 점 중심에서 위로 올린다 */
  top: calc(var(--line-top, 47px) - calc(23px * var(--fs-scale)));
  height: 3px;
  translate: 0 -50%;
  background: var(--theme);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 900ms var(--ease-out);
}

.timeline.is-drawn::before {
  transform: scaleX(1);
}

@media (prefers-reduced-motion: reduce) {
  .timeline::before {
    transform: none;
    transition: none;
  }
}

.timeline__item {
  position: relative;
  z-index: 1;
  /* 날짜 / 점 / 이름 3행 — 점 행 높이를 고정해 선과 항상 맞춘다 */
  display: grid;
  grid-template-rows: auto var(--dot) auto;
  justify-items: center;
  align-items: center;
  gap: calc(8px * var(--fs-scale));
  /* 항목 사이 여백을 확보해 긴 학교명이 서로 겹치지 않게 한다 */
  padding-inline: 2px;
  text-align: center;
  color: var(--theme);
  flex: 1;
  min-width: 0;
}

.timeline__date {
  font-size: var(--fs-20);
  letter-spacing: -0.02em;
  white-space: nowrap;
}

.timeline__dot {
  width: var(--dot);
  height: var(--dot);
}

/* --------------------------------------------------------------------------
   CAREER 항목 hover — 가운데 원이 가로로 늘어나며 업무 내용을 보여준다
   -------------------------------------------------------------------------- */

.timeline__item--job {
  cursor: pointer;
}

/*
  원과 확장 박스를 담는 자리.
  박스가 커져도 주변 항목이 밀리지 않도록 원 크기를 그대로 유지하고,
  넓어지는 부분은 absolute 로 띄운다.
*/
.timeline__marker {
  position: relative;
  display: grid;
  place-items: center;
  width: var(--dot);
  height: var(--dot);
}

.timeline__marker .timeline__dot {
  transition: opacity var(--dur-base) var(--ease-out);
}

/* 늘어나는 알약 — 기본은 원 크기, hover 시 가로로 확장 */
.timeline__detail {
  position: absolute;
  top: 50%;
  left: 50%;
  z-index: 2;
  translate: -50% -50%;

  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  width: var(--dot);
  height: var(--dot);
  padding: 0;
  border-radius: 999px;
  background: var(--theme);
  color: var(--c-white);

  font-size: var(--fs-16);
  letter-spacing: -0.02em;
  line-height: 1.4;
  text-align: left;
  white-space: nowrap;

  /* 접힌 상태에서는 글자를 감춘다 */
  opacity: 0;
  overflow: hidden;

  transition: width var(--dur-base) var(--ease-out),
    height var(--dur-base) var(--ease-out),
    padding var(--dur-base) var(--ease-out),
    opacity var(--dur-fast) var(--ease-out);
}

.timeline__item--job:hover .timeline__detail,
.timeline__item--job:focus-visible .timeline__detail {
  width: max-content;
  max-width: 380px;
  height: auto;
  min-height: 54px;
  padding: 18px 22px;
  border-radius: 20px;
  opacity: 1;
  white-space: normal;
}

/* 업무 목록 — 불릿 있는 리스트 */
/* 상세 제목 — '교육사항 :' 라벨 + 과정명 */
.timeline__detail-title {
  margin-bottom: 12px;
  font-weight: 700;
  font-size: var(--fs-18);
  letter-spacing: -0.02em;
  line-height: 1.3;
}

/* 배운 내용 목록 */
.timeline__detail-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.timeline__detail li {
  position: relative;
  padding-left: 14px;
}

.timeline__detail li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.6em;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: currentColor;
}

/* 확장되는 동안 원과 기존 텍스트는 사라진다 */
.timeline__item--job:hover .timeline__dot,
.timeline__item--job:focus-visible .timeline__dot,
.timeline__item--job:hover .timeline__date,
.timeline__item--job:focus-visible .timeline__date,
.timeline__item--job:hover .timeline__name,
.timeline__item--job:focus-visible .timeline__name {
  opacity: 0;
}

.timeline__item--job .timeline__date,
.timeline__item--job .timeline__name {
  transition: opacity var(--dur-fast) var(--ease-out);
}

.timeline__name {
  font-weight: 500;
  font-size: var(--fs-20);
  letter-spacing: -0.02em;
  line-height: 1.3;
  /* 한글 단어가 중간에서 끊기지 않게 */
  word-break: keep-all;
}

/* LICENCE 태그 목록 */
.licence-list {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 20px;
  margin-top: 34px;
}

.licence-list li {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 45px;
  padding: 10px 24px;
  background: var(--c-white);
  border: 1px solid var(--theme);
  /* Figma: 좌상단만 각지고 나머지는 둥근 형태 */
  border-radius: 0 20px 20px 20px;
  transition: transform var(--dur-fast) var(--ease-out);
}

.licence-list li:hover {
  transform: translateY(-3px);
}

.licence-list__name {
  font-weight: 500;
  font-size: var(--fs-20);
  letter-spacing: -0.02em;
  color: var(--theme);
  white-space: nowrap;
}

.licence-list__date {
  font-weight: 500;
  font-size: var(--fs-16);
  letter-spacing: -0.02em;
  color: var(--c-experience-light);
}

/* ==========================================================================
   4. SKILLS
   ========================================================================== */

.skills { --theme: var(--c-skills); --theme-rgb: 95, 8, 216; }

.skills__card {
  display: grid;
  grid-template-columns:
    calc(581px * var(--fs-scale))
    calc(60px * var(--fs-scale))
    calc(626px * var(--fs-scale));
  gap: 40px;
  align-items: center;
  justify-content: center;
  padding: 40px 80px;
}

/* 맥 윈도우풍 툴 패널 */
/* 우측 패널과 같은 높이로 맞춘다 */
.tool-window {
  display: flex;
  flex-direction: column;
  /* 오른쪽 패널과 같은 높이 기준 (키캡을 내린 만큼 여유 확보) */
  height: calc(545px * var(--fs-scale));
  background: linear-gradient(180deg, #f2f2f2 0%, #d9d9d9 100%);
  border-radius: 14px;
  padding: calc(22px * var(--fs-scale)) calc(26px * var(--fs-scale)) calc(26px * var(--fs-scale));
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.18);
}

.tool-window__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-bottom: 14px;
  border-bottom: 2px solid var(--c-gray-line);
}

.tool-window__title {
  font-family: var(--font-en);
  font-size: var(--fs-36);
  letter-spacing: -0.03em;
  color: var(--c-gray);
  line-height: 1;
}

.tool-window__dots {
  width: 65px;
}

/* 아이콘 키캡 그리드 */
/*
  키캡은 정사각에 가깝게 유지한다.
  grid-auto-rows:1fr 로 두면 남는 세로 공간을 행이 나눠 가져
  키가 세로로 길쭉해진다.
*/
.keycaps {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: calc(14px * var(--fs-scale));
  /* 키캡을 아래로 내린다 */
  margin-top: calc(56px * var(--fs-scale));
  margin-bottom: 0;
}

/*
  키캡 — Figma(1:213) 참고.

  구조: 바깥 요소가 "측면 벽"(--key-side), 안의 img 가 "윗면"이다.
  윗면을 살짝 위로 띄우면 아래쪽에 벽이 드러나 실제 키처럼 보인다.
  누르면 윗면이 내려앉아 벽이 얇아진다.
*/
.keycap {
  --key-depth: calc(9px * var(--fs-scale));
  /*
    transform 에 들어갈 값은 미리 확정해 둔다.
    transform:translateY(calc(var(--변수) * -0.15)) 처럼
    계산식을 중첩하면 시작·끝값이 모두 변수 의존이 되어
    브라우저가 중간 단계를 계산하지 못하고 전환을 건너뛴다.
  */
  --key-rest: calc(-9px * var(--fs-scale));
  --key-press: calc(-1.35px * var(--fs-scale));
  position: relative;
  display: block;
  width: 100%;
  /* 정사각에 가까운 비율 유지 */
  aspect-ratio: 110 / 100;
  padding: 0;
  background: var(--key-side, #999);
  border: 0;
  border-radius: 12px;
  cursor: pointer;
  /* 키보드 바닥에 드리우는 그림자 */
  box-shadow: 0 3px 5px rgba(0, 0, 0, 0.28);
  /*
    .reveal 의 opacity/transform 전환을 덮어쓰지 않도록 함께 선언한다.
    (transition 은 나중 선언이 앞의 것을 통째로 대체한다)
  */
  transition: box-shadow var(--dur-fast) var(--ease-out),
    opacity var(--dur-slow) var(--ease-out) var(--reveal-delay, 0ms),
    transform var(--dur-slow) var(--ease-out) var(--reveal-delay, 0ms);
}

/* 윗면 — 이미지가 키 전체를 채운다 */
.keycap img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 11px;
  /* 위로 띄워 아래에 측면 벽을 노출 */
  transform: translateY(var(--key-rest));
  /* 윗면 가장자리 광택 */
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.35),
    inset 0 -1px 0 rgba(0, 0, 0, 0.2);
  transition: transform var(--dur-fast) var(--ease-out);
}

/* 눌림 — 윗면이 내려앉는다 */
.keycap:hover img {
  transform: translateY(-2px);
}

.keycap:hover {
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
}

/*
  선택된 키는 눌린 상태로 고정.
  .keycap img / :hover img 보다 뒤에 와야 transform 이 덮이지 않는다.
*/
.keycap.is-active img {
  transform: translateY(var(--key-press));
}

.keycap.is-active {
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
}

/* gnuboard — 스페이스바 형태의 넓은 키 */
.tool-window__foot {
  --key-depth: calc(8px * var(--fs-scale));
  --key-rest: calc(-8px * var(--fs-scale));
  --key-press: calc(-1.2px * var(--fs-scale));
  /* 스페이스바처럼 가로 전체를 채운다 (flex 자식은 기본이 축소) */
  width: 100%;
  align-self: stretch;
  /* 키캡의 정사각 비율을 해제하고 납작한 바로 */
  aspect-ratio: auto;
  height: calc(96px * var(--fs-scale));
  flex-shrink: 0;
  /* 키캡과 최소 간격 확보 */
  margin-top: calc(26px * var(--fs-scale));
  --key-side: #c9c6c3;
}

/*
  로고가 키 아래쪽으로 치우쳐 보여 위로 올린다.
  contain 상태에서는 object-position 이 거의 듣지 않으므로
  아래쪽에 패딩을 줘 그리는 영역을 위로 밀어낸다.
*/
.tool-window__foot img {
  object-fit: contain;
  padding-bottom: 15px;
  background: var(--c-white);
}

/* 가운데 화살표 */
.skills__arrow {
  width: 60px;
  height: 60px;
}

/* --------------------------------------------------------------------------
   우측 패널 — 기본 안내 ↔ 스킬 상세를 같은 크기로 교차 전환
   -------------------------------------------------------------------------- */

.skills__panel {
  position: relative;
  height: calc(545px * var(--fs-scale));
  background: var(--c-white);
  border: 2px solid var(--theme);
  border-radius: var(--radius-card);
  overflow: hidden;
}

/* 두 화면 모두 카드를 꽉 채운다 */
.skills__panel > [data-panel] {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity var(--dur-base) var(--ease-out);
}

.skills__panel > [data-panel].is-shown {
  opacity: 1;
}

/* hidden 이어도 자리를 차지하지 않도록 */
.skills__panel > [data-panel][hidden] {
  display: none;
}

.skills__next {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 30px;
  padding: 40px;
}

.skills__next img {
  width: 327px;
  max-width: 100%;
  height: auto;
}

/* --------------------------------------------------------------------------
   스킬 상세 (Figma 1:517)
   -------------------------------------------------------------------------- */

.skill-detail {
  display: flex;
  flex-direction: column;
  gap: calc(30px * var(--fs-scale));
  padding: calc(46px * var(--fs-scale)) calc(50px * var(--fs-scale));
}

/*
  설명 목록이 남는 공간을 모두 차지해, 아래 구분선이 카드 하단
  패딩(46px) 바로 위에 놓인다. → 위쪽 여백과 대칭을 이루고,
  내용 길이가 달라도 모든 스킬에서 선 위치가 같다.
*/
.skill-detail__list {
  flex: 1;
  justify-content: flex-start;
}

.skill-detail__head {
  display: flex;
  align-items: center;
  gap: 32px;
}

.skill-detail__icon {
  width: 150px;
  height: 150px;
  flex-shrink: 0;
  border-radius: var(--radius-card);
  overflow: hidden;
}

.skill-detail__icon img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}


.skill-detail__name {
  font-family: var(--font-en);
  font-weight: 500;
  font-size: var(--fs-48);
  letter-spacing: -0.01em;
  line-height: 1;
}

.skill-detail__meta {
  min-width: 0;
}

.skill-detail__label {
  margin-top: 18px;
  font-weight: 500;
  font-size: var(--fs-16);
  letter-spacing: -0.02em;
}

/*
  별점 — 회색 별 위에 테마색 별을 --rating 비율만큼 겹쳐 보여준다.
  0.5 단위 반쪽 별도 자연스럽게 표현된다.
*/
.skill-detail__stars {
  --star: "★★★★★";
  position: relative;
  margin-top: 8px;
  font-size: calc(26px * var(--fs-scale));
  line-height: 1;
  letter-spacing: 2px;
  color: #ddd;
}

.skill-detail__stars::before {
  content: "★★★★★";
}

.skill-detail__stars-fill {
  position: absolute;
  inset: 0;
  overflow: hidden;
  width: calc(var(--rating, 0) / 5 * 100%);
  color: var(--theme);
  white-space: nowrap;
}

.skill-detail__stars-fill::before {
  content: "★★★★★";
}

/* 설명 목록 — 위아래 구분선 */
.skill-detail__list {
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding-block: 26px;
  border-top: 1px solid #777;
  border-bottom: 1px solid #777;
}

.skill-detail__list li {
  position: relative;
  padding-left: 20px;
  font-weight: 500;
  font-size: var(--fs-16);
  letter-spacing: -0.02em;
  line-height: 1.4;
}

/* 불릿 */
.skill-detail__list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.55em;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--theme);
}

.skills__next-text {
  font-family: var(--font-en);
  font-size: clamp(1.5rem, 2.5vw, var(--fs-48));
  letter-spacing: -0.01em;
  text-align: center;
}

/* ==========================================================================
   5. PROJECTS
   ========================================================================== */

.projects { --theme: var(--c-projects); --theme-rgb: 83, 180, 64; }

.projects__card {
  padding: 40px 50px;
}

/* 흰 카드 안에 탭 + 갤러리 */
.projects__inner {
  display: grid;
  grid-template-columns: 250px 1fr;
  min-height: 500px;
  background: var(--c-white);
  border: 2px solid var(--theme);
  border-radius: var(--radius-card);
  overflow: hidden;
}

/* 좌측 탭 — 오른쪽에 곧게 뻗은 세로 구분선 */
.projects__tabs {
  display: flex;
  flex-direction: column;
  border-right: 2px solid var(--theme);
}

.projects__tabs-label {
  display: grid;
  place-items: center;
  height: calc(100px * var(--fs-scale));
  background: var(--c-projects-bg);
  /* 아래 탭들과 같은 구분선 */
  border-bottom: 2px solid var(--theme);
  font-family: var(--font-en);
  font-size: calc(30px * var(--fs-scale));
  letter-spacing: -0.02em;
  color: var(--theme);
}

/*
  탭 — Figma(1:383): 텍스트 위, 화살표 아래로 세로 배치.
  높이 124px 로 넉넉하게.
*/
.tab {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: calc(15px * var(--fs-scale));
  height: calc(124px * var(--fs-scale));
  padding: calc(20px * var(--fs-scale)) calc(30px * var(--fs-scale));
  background: var(--c-white);
  border: 0;
  border-bottom: 2px solid var(--theme);
  border-radius: 0;
  font-family: var(--font-en);
  font-weight: 700;
  font-size: calc(25px * var(--fs-scale));
  letter-spacing: -0.02em;
  color: var(--theme);
  transition: background-color var(--dur-fast) var(--ease-out),
    color var(--dur-fast) var(--ease-out);
}

.tab__name {
  line-height: 1;
}

.tab + .tab {
  margin-top: 0;
}

.tab__arrow {
  width: 30px;
  height: 30px;
  flex-shrink: 0;
  transition: transform var(--dur-fast) var(--ease-out);
}

.tab:hover .tab__arrow {
  transform: translateX(4px);
}

.tab[aria-selected="true"] {
  background: var(--theme);
  color: var(--c-white);
}

/*
  화살표는 흰색/초록 두 파일을 JS 가 상태에 맞춰 교체한다.
  (필터로 색을 바꾸면 원형 아이콘이 뭉개진다)
*/

/* 우측 썸네일 갤러리 */
/*
  갤러리 — 페이지 영역 + 하단 페이지네이션 세로 배치.
  그리드는 각 페이지(.projects__page)가 담당한다.
*/
.projects__gallery {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: calc(36px * var(--fs-scale)) calc(40px * var(--fs-scale));
}

.projects__pages {
  flex: 1;
  display: flex;
  align-items: center;
}

/* 3 x 2 = 6개 */
.projects__page {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
  width: 100%;
}

.projects__page[hidden] {
  display: none;
}

/* 페이지네이션 — 탭 아래 빈 공간에 배치 */
.projects__pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: calc(14px * var(--fs-scale));
  /* 탭 아래로 충분히 내린다 */
  margin-top: auto;
  margin-bottom: 0;
  padding: calc(24px * var(--fs-scale)) calc(12px * var(--fs-scale));
}

.projects__nav {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border: 1px solid var(--theme);
  border-radius: 50%;
  color: var(--theme);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-out),
    color var(--dur-fast) var(--ease-out),
    opacity var(--dur-fast) var(--ease-out);
}

.projects__nav:hover:not(:disabled) {
  background: var(--theme);
  color: var(--c-white);
}

.projects__nav:disabled {
  opacity: 0.3;
  cursor: default;
}

.projects__dots {
  display: flex;
  align-items: center;
  gap: 10px;
}

.projects__page-dot {
  width: 9px;
  height: 9px;
  border: 2px solid var(--theme);
  border-radius: 50%;
  background: transparent;
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-out),
    scale var(--dur-fast) var(--ease-out);
}

.projects__page-dot:hover,
.projects__page-dot.is-active {
  background: var(--theme);
  scale: 1.2;
}

.project-item {
  position: relative;
  aspect-ratio: 330 / 200;
  border-radius: 10px;
  overflow: hidden;
  background: var(--c-projects-bg);
}

.project-item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--dur-slow) var(--ease-out);
}

.project-item:hover img {
  transform: scale(1.06);
}

/* 호버 시 어두운 오버레이 */
.project-item::after {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(70, 153, 53, 0.35);
  opacity: 0;
  transition: opacity var(--dur-base) var(--ease-out);
  pointer-events: none;
}

.project-item:hover::after {
  opacity: 1;
}

/* 탭 패널 전환 */
.tabpanel[hidden] {
  display: none;
}

/* 준비중 안내 */
.projects__empty {
  grid-column: 1 / -1;
  display: grid;
  place-items: center;
  min-height: 300px;
  font-family: var(--font-en);
  font-size: var(--fs-28);
  color: var(--theme);
}

/* ==========================================================================
   6. CONTACT
   ========================================================================== */

/*
  아래쪽은 푸터(padding-top 60px)가 더해지므로
  위아래가 같아 보이도록 하단 여백을 줄인다.
*/
.contact {
  position: relative;
  padding-block: 140px 70px;
  overflow: hidden;
  color: var(--c-white);
  /* 이미지 로드 전에도 어두운 배경이 보이도록 */
  background: #0a2a5e;
}

.contact::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  background-image: url("../assets/images/contact-bg.webp");
  background-size: cover;
  background-position: center;
}

/* 어둡게 덮는 오버레이 */
.contact::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  background: rgba(0, 0, 0, 0.3);
}

.contact > .container {
  position: relative;
  z-index: 1;
}

/* 좌측 정렬 1단 — 이메일 주소가 주인공이다 */
.contact__inner {
  padding: 60px;
  border: 1px solid rgba(255, 255, 255, 0.25);
  border-radius: 10px;
}

/* CONTACT — 캡슐 테두리를 두른 라벨 */
.contact__title {
  display: inline-flex;
  align-items: center;
  padding: 12px 30px;
  border: 2px solid rgba(255, 255, 255, 0.55);
  border-radius: 999px;
  font-family: var(--font-en);
  font-weight: 600;
  font-size: var(--fs-32);
  letter-spacing: -1px;
  line-height: 1;
}

.contact__lead {
  margin-top: 24px;
  font-size: var(--fs-20);
  letter-spacing: -0.02em;
  color: rgba(255, 255, 255, 0.8);
}

/* 둘째 줄은 첫 줄에 바짝 붙인다 */
.contact__lead--sub {
  margin-top: 6px;
}

/* 이메일 줄 — 주소 + 복사 버튼 */
.contact__mail-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 24px;
  margin-top: 40px;
}

/* 이 섹션에서 가장 큰 요소 */
.contact__mail {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(2rem, 4.4vw, calc(72px * var(--fs-scale)));
  letter-spacing: -0.03em;
  line-height: 1;
  color: var(--c-white);
  text-decoration: none;
  word-break: break-all;
  transition: opacity var(--dur-fast) var(--ease-out);
}

.contact__mail:hover {
  opacity: 0.75;
  text-decoration: underline;
  text-underline-offset: 4px;
}

/* 복사 버튼 */
.contact__copy {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  flex-shrink: 0;
  padding: 6px 14px;
  border: 1px solid rgba(255, 255, 255, 0.5);
  border-radius: 999px;
  color: var(--c-white);
  font-family: var(--font-en);
  font-size: var(--fs-16);
  letter-spacing: 0.04em;
  line-height: 1;
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-out),
    border-color var(--dur-fast) var(--ease-out);
}

.contact__copy:hover {
  background: rgba(255, 255, 255, 0.16);
  border-color: var(--c-white);
}

/* 문서 아이콘 두 장이 겹친 모양 */
.contact__copy-icon {
  position: relative;
  width: 13px;
  height: 15px;
  border: 1.5px solid currentColor;
  border-radius: 3px;
}

.contact__copy-icon::before {
  content: "";
  position: absolute;
  top: -4px;
  left: 2px;
  width: 100%;
  height: 100%;
  border: 1.5px solid currentColor;
  border-radius: 3px;
  border-right: 0;
  border-bottom: 0;
}

/* 복사 완료 상태 */
.contact__copy.is-copied {
  background: var(--c-projects-alt);
  border-color: var(--c-projects-alt);
}

/* 완료되면 아이콘을 체크 모양으로 바꾼다 */
.contact__copy.is-copied .contact__copy-icon {
  width: 8px;
  height: 14px;
  border: 0;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  border-radius: 0;
  rotate: 45deg;
  translate: 0 -2px;
}

.contact__copy.is-copied .contact__copy-icon::before {
  display: none;
}

/* 저작권 */
.site-footer {
  position: relative;
  z-index: 1;
  padding-top: 60px;
  text-align: center;
  font-family: var(--font-en);
  font-size: var(--fs-16);
  color: rgba(255, 255, 255, 0.7);
}

/* ==========================================================================
   좌측 섹션 인디케이터
   ========================================================================== */

.section-dots {
  position: fixed;
  left: 24px;
  top: 50%;
  z-index: 90;
  translate: 0 -50%;

  /* HERO 에서는 숨김 */
  opacity: 0;
  visibility: hidden;
  transform: translateX(-12px);
  transition: opacity var(--dur-base) var(--ease-out),
    transform var(--dur-base) var(--ease-out),
    visibility var(--dur-base);
}

.section-dots.is-shown {
  opacity: 1;
  visibility: visible;
  transform: none;
}

.section-dots__list {
  display: flex;
  flex-direction: column;
  gap: 22px;
}

.section-dots__item {
  display: flex;
  align-items: center;
  gap: 12px;
}

/* 점 — 기본은 테두리만, 활성화되면 채워진다 */
.section-dots__dot {
  position: relative;
  display: block;
  width: 10px;
  height: 10px;
  flex-shrink: 0;
  border: 2px solid var(--c-about);
  border-radius: 50%;
  background: transparent;
  transition: background-color var(--dur-fast) var(--ease-out),
    scale var(--dur-fast) var(--ease-out);
}

.section-dots__item:hover .section-dots__dot,
.section-dots__item.is-active .section-dots__dot {
  background: var(--c-about);
  scale: 1.25;
}

/*
  이름표 — 평소엔 숨겼다가 호버·활성 시 나타난다.
  absolute 로 띄워 자리를 차지하지 않게 해야 본문과 겹치지 않는다.
*/
.section-dots__item {
  position: relative;
}

.section-dots__label {
  position: absolute;
  left: 22px;
  top: 50%;
  translate: 0 -50%;

  font-family: var(--font-en);
  font-weight: 500;
  font-size: 12px;
  letter-spacing: 0.08em;
  white-space: nowrap;
  color: var(--c-about);
  pointer-events: none;

  opacity: 0;
  transform: translateX(-6px);
  transition: opacity var(--dur-fast) var(--ease-out),
    transform var(--dur-fast) var(--ease-out);
}

/*
  이름표는 호버할 때만 띄운다.
  (활성 상태에서 항상 띄우면 본문 위로 겹친다)
*/
.section-dots__item:hover .section-dots__label,
.section-dots__item:focus-visible .section-dots__label {
  opacity: 1;
  transform: none;
}

/* 호버 시에는 배경을 깔아 본문 위에서도 읽히게 한다 */
.section-dots__label {
  padding: 4px 10px;
  border-radius: 999px;
  background: var(--c-white);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.16);
}

.section-dots.is-dark .section-dots__label {
  background: rgba(0, 0, 0, 0.72);
}

/* CONTACT 은 어두운 배경이라 색을 뒤집는다 */
.section-dots.is-dark .section-dots__dot {
  border-color: var(--c-white);
}

.section-dots.is-dark .section-dots__item:hover .section-dots__dot,
.section-dots.is-dark .section-dots__item.is-active .section-dots__dot {
  background: var(--c-white);
}

.section-dots.is-dark .section-dots__label {
  color: var(--c-white);
}

/* ==========================================================================
   맨 위로 버튼
   ========================================================================== */

.to-top {
  position: fixed;
  right: 40px;
  bottom: 40px;
  z-index: 90;
  display: grid;
  place-items: center;
  width: 56px;
  height: 56px;
  background: var(--c-black);
  color: var(--c-white);
  border-radius: 50%;
  font-size: 22px;
  opacity: 0;
  visibility: hidden;
  transform: translateY(12px);
  transition: opacity var(--dur-base) var(--ease-out),
    transform var(--dur-base) var(--ease-out),
    visibility var(--dur-base);
}

.to-top.is-shown {
  opacity: 1;
  visibility: visible;
  transform: none;
}

.to-top:hover {
  background: var(--c-about);
}

/* ==========================================================================
   프로젝트 상세 보기 모달

   상세 이미지는 세로가 매우 길어(최대 13000px+) 전체를 한 번에 보여주면
   아무것도 읽히지 않는다. → 상단 일부만 보이고 안에서 스크롤한다.
   ========================================================================== */

.project-modal {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: grid;
  place-items: center;
  padding: 40px 20px;
}

.project-modal[hidden] {
  display: none;
}

.project-modal__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(10, 20, 16, 0.6);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  cursor: pointer;
}

.project-modal__panel {
  position: relative;
  display: flex;
  flex-direction: column;
  /*
    넓은 화면에서도 화면 대비 비율을 유지한다.
    1920 에서 940px(49%) → 그 위로는 vw 기준으로 함께 커지고
    최대 1600px 에서 멈춘다.
  */
  width: min(max(940px, 46vw), 1600px, 100%);
  /* 화면 높이의 대부분을 쓰되 넘치지 않게 */
  max-height: min(86vh, 1400px);
  background: var(--c-white);
  border-radius: var(--radius-card);
  overflow: hidden;
  box-shadow: 0 20px 50px rgba(0, 0, 0, 0.3);
}

.project-modal__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding: calc(18px * var(--fs-scale)) calc(24px * var(--fs-scale));
  border-bottom: 1px solid #e6e6e6;
  flex-shrink: 0;
}

.project-modal__title {
  font-weight: 500;
  font-size: var(--fs-18);
  letter-spacing: -0.02em;
}

.project-modal__close {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  flex-shrink: 0;
  border-radius: 50%;
  font-size: 26px;
  line-height: 1;
  color: #666;
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-out),
    color var(--dur-fast) var(--ease-out);
}

.project-modal__close:hover {
  background: #f0f0f0;
  color: #111;
}

/* 스크롤되는 영역 — 상단부터 보이고 아래로 내려간다 */
.project-modal__body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  background: #f7f7f7;
}

.project-modal__img {
  display: block;
  width: 100%;
  height: auto;
}

/* 스크롤바를 얇게 */
.project-modal__body::-webkit-scrollbar {
  width: 10px;
}

.project-modal__body::-webkit-scrollbar-thumb {
  background: rgba(0, 0, 0, 0.25);
  border-radius: 999px;
  border: 3px solid #f7f7f7;
}

/* 썸네일이 버튼이 되면서 필요한 보정 */
.project-item {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  cursor: pointer;
}

/* 모달이 열린 동안 배경 스크롤 잠금 */
.is-modal-open {
  overflow: hidden;
}
