/* ===== 전역 ===== */
* { box-sizing: border-box; }
body {
  margin: 0;
  font-family: 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
  background: #fff;
  color: #111;
}

/* ===== 섹션 1: 히어로 ===== */
.MainBack {
  /* 히어로 높이: PC는 화면 전체(100vh). 폰은 1024px 레이아웃을 줄여 보여 세로로 아주 길어지는데(약 2000px),
     그대로 100vh면 줄만 커져 사진 위아래가 비므로 가로의 70%(가로로 넓은 PC 비율)까지만 쓴다 */
  --hero-h: min(100vh, 70vw);
  position: relative;
  height: var(--hero-h);
  overflow: hidden;
}

/* 어두운 오버레이 — 마퀴 위에 살짝 깔아 텍스트 가독성 확보 */
.MainBack::before {
  content: '';
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.45);
  z-index: 1;
}

/* ===== 마퀴 전체 영역: 히어로 높이를 꽉 채움 ===== */
.photo-marquee-area {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  z-index: 0; /* 텍스트·오버레이보다 뒤 */
}
/* 마퀴 한 줄: 4줄이 히어로 높이를 균등 분할 */
.photo-marquee-row {
  height: calc(var(--hero-h) / 4);
  display: flex;
  width: max-content;
  animation: marqueeLeft 40s linear infinite;
}
/* 2번 줄: 반대 방향으로 흐름 */
.photo-marquee-row--reverse {
  animation-direction: reverse;
}
/* 트랙: 사진 박스들을 가로로 나열 */
.photo-marquee-track {
  display: flex;
  gap: 14px;
  padding-right: 14px;
}
/* 사진 박스: 줄 높이를 꽉 채우고 가로세로 1.6:1 비율 유지 */
.photo-marquee-card {
  width: calc((var(--hero-h) / 4 - 14px) * 1.6);
  height: calc(var(--hero-h) / 4 - 14px); /* 줄 사이 간격 14px을 뺀 값 */
  border-radius: 8px;
  object-fit: cover;
  flex-shrink: 0;
  opacity: 0.8;
  align-self: center; /* 50vh 행 안에서 세로 중앙 */
  transition: opacity 0.3s ease, transform 0.3s ease;
}
.photo-marquee-card:hover {
  opacity: 1;
  transform: translateY(-6px);
}

/* 왼쪽으로 흐르는 애니메이션 */
@keyframes marqueeLeft {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

/* 히어로 텍스트: 마퀴 위에 absolute로 화면 정중앙 배치 */
.hero-content {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 2;
  text-align: center;
  color: #fff;
  white-space: nowrap;
}
.hero-eyebrow {
  margin: 0 0 1rem;
  font-size: 0.8rem;
  letter-spacing: 0.35em;
  color: rgba(255,255,255,0.7);
  font-weight: 600;
}
.hero-title {
  margin: 0 0 1.2rem;
  font-family: 'Bebas Neue', sans-serif;
  font-size: clamp(3.5rem, 9vw, 7rem);
  font-weight: 400; /* Bebas Neue는 단일 웨이트라 400으로 */
  line-height: 0.95;
  letter-spacing: 0.03em;
}
.hero-title span { color: #fff; }
.hero-sub {
  margin: 0;
  font-size: clamp(0.9rem, 1.8vw, 1.15rem);
  color: rgba(255,255,255,0.7);
  letter-spacing: 0.06em;
}

/* 스크롤 힌트 */
.scroll-hint {
  position: absolute;
  bottom: 2rem;
  left: 50%;
  transform: translateX(-50%);
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.4rem;
  color: rgba(255,255,255,0.45);
  font-size: 0.6rem;
  letter-spacing: 0.3em;
}
.scroll-line {
  width: 1px;
  height: 48px;
  background: linear-gradient(to bottom, rgba(255,255,255,0.45), transparent);
  animation: lineDown 1.6s ease-in-out infinite;
}
@keyframes lineDown {
  0%   { transform: scaleY(0); transform-origin: top; }
  50%  { transform: scaleY(1); transform-origin: top; }
  100% { transform: scaleY(1); transform-origin: bottom; opacity: 0; }
}

/* ===== 기술 스택 섹션 ===== */
.tech-wrap {
  max-width: 1100px;
  margin: 0 auto;
}
/* 분류 제목 (FRONTEND / BACKEND / DEPLOY / DEV TOOLS · AI) */
.tech-group-title {
  margin: 3rem 0 1rem;
  font-size: 0.75rem;
  letter-spacing: 0.3em;
  font-weight: 700;
  color: rgba(255,255,255,0.55);
}
.tech-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.5rem;
}
.tech-item {
  border: 1px solid rgba(255,255,255,0.15);
  border-radius: 10px;
  padding: 1.5rem 1.8rem;
  display: flex;
  flex-direction: row;   /* 아이콘(좌) + 텍스트(우) 가로 배치 */
  align-items: center;
  gap: 1.2rem;
  transition: border-color 0.3s, background 0.3s;
}
.tech-item:hover {
  border-color: rgba(255,255,255,0.5);
  background: rgba(255,255,255,0.05);
}
/* devicon <i> 태그 공통 크기 */
.tech-icon {
  font-size: 2.4rem;
  flex-shrink: 0;
  width: 2.6rem;
  text-align: center;
  /* devicon colored가 없는 아이콘(express 등)은 흰색으로 */
  color: #fff;
}
/* img 태그 아이콘 (OpenAI, Claude 등 devicon 미지원 브랜드) */
.tech-icon--img {
  width: 2.4rem;
  height: 2.4rem;
  object-fit: contain;
}
/* 로고를 브랜드 색 둥근 네모 배지에 담아 모든 아이콘 모양·크기를 통일 (배지 색은 인라인 --badge)
   cafe24·Vercel은 로고 파일 자체가 배지 모양이라 감싸지 않는다 */
.tech-badge {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.4rem;
  height: 2.4rem;
  flex-shrink: 0;
  border-radius: 22%;     /* cafe24·Vercel 아이콘 모서리와 같은 둥글기 */
  background: var(--badge, #000);
}
/* 검정 배지는 어두운 카드와 구분되도록 옅은 테두리 (Vercel 아이콘과 같은 색) */
.tech-badge--dark {
  box-shadow: inset 0 0 0 1px #3a3a3a;
}
/* 배지 안의 로고는 배지보다 작게 */
.tech-badge .tech-icon {
  font-size: 1.7rem;
  width: auto;
}
.tech-badge .tech-icon--img {
  width: 1.6rem;
  height: 1.6rem;
}
/* 색이 들어 있는 SVG(Vultr·Claude)를 배지 위에서 흰색으로 */
.tech-icon--white {
  filter: brightness(0) invert(1);
}
.tech-text {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}
.tech-name {
  font-size: 1.1rem;
  font-weight: 700;
  color: #fff;
}
.tech-role {
  font-size: 0.78rem;
  color: rgba(255,255,255,0.45);
  letter-spacing: 0.08em;
}
/* 폰처럼 좁은 화면: 3열이면 카드가 너무 좁아 글자가 잘리고 화면 밖으로 밀리므로 1열로 쌓는다 */
@media (max-width: 640px) {
  .tech-grid { grid-template-columns: 1fr; }
}

/* ===== 좌우로 넘기는 영역 공통 (개발 과정 · ROADMAP) ===== */
/* 세로로는 일반 섹션처럼 그냥 지나가고, .pin 상자 안에서만 좌우로 넘긴다(손가락 스와이프·마우스 끌기). pinscroll.js가 끌기·버튼·진행 알림을 맡는다 */
.pin {
  position: relative;
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;       /* Firefox */
  -ms-overflow-style: none;    /* 구형 Edge */
  cursor: grab;
  -webkit-overflow-scrolling: touch;
}
.pin::-webkit-scrollbar { display: none; } /* Chrome·Safari */
.pin.dragging { cursor: grabbing; user-select: none; }

/* 제목 줄: 왼쪽에 영문 제목(히어로와 같은 Bebas Neue), 오른쪽에 넘김 버튼 */
.pin-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 2rem;
  padding: 0 8vw;
  margin-bottom: 1.8rem;
}
.pin-eyebrow {
  margin: 0 0 0.7rem;
  font-size: 0.72rem;
  letter-spacing: 0.35em;
  font-weight: 600;
  color: rgba(0, 0, 0, 0.45);
}
/* 섹션 제목: 뒤에 나오는 공통 .section-label(작은 글씨)을 이기도록 선택자를 높였다 */
.rm-section .pin-label {
  margin: 0;
  padding: 0;
  font-family: 'Bebas Neue', sans-serif;
  font-size: clamp(3.2rem, 7vw, 5.5rem);
  font-weight: 400; /* Bebas Neue는 단일 웨이트라 400으로 */
  letter-spacing: 0.04em;
  line-height: 0.95;
}
.pin-nav {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding-bottom: 0.3rem;
}
/* 이전/다음 둥근 버튼: 끝에 닿으면 흐려진다 */
.pin-btn {
  width: 42px;
  height: 42px;
  border: 1px solid currentColor;
  border-radius: 50%;
  background: transparent;
  color: inherit;
  font-size: 1.05rem;
  line-height: 1;
  cursor: pointer;
  opacity: 0.7;
  transition: opacity 0.25s, background 0.25s, color 0.25s;
}
.pin-btn:hover:not(:disabled) { opacity: 1; }
.pin-btn:disabled { opacity: 0.2; cursor: default; }

/* ===== 로드맵 섹션 ===== */
.rm-section {
  position: relative;
  padding: 100px 0 48px; /* 아래쪽은 타임라인 높이(680px)가 이미 여유를 주므로 짧게 */
  /* 왼쪽 위에 아주 옅은 초록 빛을 깔아 평평한 검정이 되지 않게. 아래 기술 스택(#1b1c20)보다 한 톤 더 어둡다 */
  background: radial-gradient(ellipse 60% 50% at 12% 0%, rgba(46, 204, 113, 0.1), transparent 70%), #0b0b0d;
  color: #fff;
}
.rm-section .pin-label { color: #fff; }
.rm-section .pin-eyebrow { color: rgba(255, 255, 255, 0.45); }
/* 제목 줄 범례: 완료 · 진행 중 · 예정 개수 */
.rm-legend {
  display: flex;
  gap: 1.1rem;
  margin: 0 0.9rem 0 0;
  padding: 0;
  list-style: none;
  font-size: 0.78rem;
  color: rgba(255, 255, 255, 0.55);
}
.rm-legend li::before {
  content: '';
  display: inline-block;
  width: 8px;
  height: 8px;
  margin-right: 0.45rem;
  border-radius: 50%;
}
.rm-legend b { margin-left: 0.2rem; color: #fff; }
.rm-legend--done::before { background: #2ecc71; }
.rm-legend--wip::before { background: #f39c12; }
.rm-legend--todo::before { border: 1.5px solid rgba(255, 255, 255, 0.55); }
/* 트랙: 항목들이 가로로 늘어선 긴 띠. 높이를 고정해야 축(50%)과 위·아래 글상자 위치가 정해진다 */
.rm-track {
  position: relative; /* .rm-axis(absolute)의 기준 */
  height: 680px; /* 펼친 카드(상세 포함)가 축 위·아래 한쪽 절반에 들어갈 높이. 가장 큰 카드(도메인 구입, 약 285px)가 잘리지 않도록 — 상세글·캡처를 늘리면 전 항목을 펼쳐 다시 확인 */
  width: max-content; /* 화면 폭에 갇히지 않고 항목 전체 길이만큼 늘어나야 한다 */
  display: flex;
  /* 오른쪽 여백 = 왼쪽 시작 여백(8vw)과 같게 + 마지막 카드가 칸 밖으로 튀어나온 60px. 예전엔 축이 끝 너머로 뻗어 30vw를 줬지만
     지금은 축이 마지막 점에서 끝나므로 크게 둘 이유가 없다(창이 넓을수록 빈 공간만 커졌다) */
  padding: 0 calc(8vw + 60px) 0 8vw;
}
/* 축(가로선): 흐린 바탕선 위로 채움선이 스크롤만큼 길어지고, 끝에 빛나는 머리가 달린다 */
.rm-axis {
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  height: 2px;
  margin-top: -1px;
  background: rgba(255, 255, 255, 0.1);
}
.rm-axis-fill {
  position: relative;
  width: 0;
  height: 100%;
  /* 위층: 선을 따라 앞으로 흐르는 밝은 빛 조각(160px), 아래층: 초록 그라데이션 */
  background:
    linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.85), transparent) 0 0 / 160px 100% no-repeat,
    linear-gradient(90deg, rgba(46, 204, 113, 0.15), #2ecc71);
  box-shadow: 0 0 14px rgba(46, 204, 113, 0.5);
  animation: rmShimmer 2.6s linear infinite;
}
@keyframes rmShimmer {
  from { background-position: -160px 0, 0 0; }
  to   { background-position: calc(100% + 160px) 0, 0 0; }
}
.rm-axis-fill::after {
  content: '';
  position: absolute;
  /* 머리 점은 채움선 안쪽 끝에 둔다. 바깥(right: -5px)으로 내밀면 띠가 5px 길어지고, roadmap.js는 그 늘어난 폭(scrollWidth)으로
     채움선을 다시 늘려 스크롤 끝에서 띠가 한없이 길어진다 */
  right: 0;
  top: 50%;
  width: 10px;
  height: 10px;
  margin-top: -5px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 0 0 4px rgba(46, 204, 113, 0.25), 0 0 18px #2ecc71;
  animation: rmHead 1.8s ease-in-out infinite; /* 숨 쉬듯 커졌다 작아지는 빛 */
}
@keyframes rmHead {
  50% { box-shadow: 0 0 0 8px rgba(46, 204, 113, 0.12), 0 0 28px #2ecc71; }
}
/* 항목 한 칸 */
.rm-slot {
  --rm-base: 220px; /* 펼치지 않았을 때의 칸 폭. 펼칠 때 roadmap.js가 이 값에 상세 폭을 더해 flex-basis로 준다 */
  position: relative;
  flex: 0 0 var(--rm-base);
  transition: flex-basis var(--rm-dur) var(--rm-ease); /* 폭이 바뀌면 뒤쪽 칸들도 같은 곡선으로 부드럽게 밀려난다 */
}
.rm-slot--multi { --rm-base: 250px; } /* 한 묶음(최대 3개)의 항목이 쌓이는 칸 */
.rm-slot--wip,
.rm-slot--todo { --rm-base: 270px; }
/* 축 위의 점 */
.rm-dot {
  position: absolute;
  top: 50%;
  left: 0;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  transform: translate(0, -50%) scale(0);
  transition: transform 0.4s ease;
  background: #2ecc71;
  box-shadow: 0 0 0 4px rgba(46, 204, 113, 0.18);
}
.rm-slot--wip .rm-dot { background: #f39c12; box-shadow: none; animation: rmPulse 1.8s ease-out infinite; }
.rm-slot--todo .rm-dot { background: #0b0b0d; box-shadow: none; border: 2px solid rgba(255, 255, 255, 0.5); }
/* 축이 닿아 점이 나타날 때 바깥으로 퍼지는 물결 고리 (색은 상태색 --rm-c) */
.rm-slot { --rm-c: #2ecc71; }
.rm-slot--wip { --rm-c: #f39c12; }
.rm-slot--todo { --rm-c: rgba(255, 255, 255, 0.6); }
.rm-dot::before {
  content: '';
  position: absolute;
  inset: -3px;
  border-radius: 50%;
  border: 2px solid var(--rm-c);
  opacity: 0;
}
.rm-slot.reached .rm-dot::before { animation: rmRing 0.9s 0.2s ease-out; }
@keyframes rmRing {
  from { transform: scale(1);   opacity: 0.9; }
  to   { transform: scale(3.4); opacity: 0; }
}
@keyframes rmPulse {
  0%   { box-shadow: 0 0 0 0 rgba(243, 156, 18, 0.6); }
  100% { box-shadow: 0 0 0 14px rgba(243, 156, 18, 0); }
}
/* 항목 글상자(카드). 칸이 짝수번째면 축 위, 홀수번째면 축 아래에 번갈아 놓고, ::after 줄기가 축의 점과 이어 준다.
   카드 폭은 칸보다 넓게(+60px) 잡는다 — 같은 쪽 이웃 카드는 두 칸 건너라서 겹치지 않는다 */
.rm-node {
  position: absolute;
  left: 0;
  width: calc(100% + 60px);
  padding: 1rem 1.1rem 1.1rem;
  border: 1px solid rgba(46, 204, 113, 0.22);
  border-radius: 14px;
  background: linear-gradient(160deg, rgba(255, 255, 255, 0.07), rgba(255, 255, 255, 0.02));
  opacity: 0;
  filter: blur(6px); /* 흐릿한 채로 나타나 또렷해진다 */
  /* transform은 살짝 넘쳤다 돌아오는 곡선으로 통통 튀며 자리 잡는다. 호버로 들어 올리는 translate는 따로 빠르게 */
  transition: opacity 0.6s ease, filter 0.6s ease, transform 0.8s cubic-bezier(0.2, 0.9, 0.3, 1.15), translate 0.25s ease, border-color 0.3s ease;
}
.rm-node:hover { border-color: rgba(255, 255, 255, 0.4); translate: 0 -4px; }
/* 마우스를 따라다니는 빛: 좌표(--mx, --my)는 roadmap.js가 넘긴다. 카드 배경 위·글자 아래(z-index -1)에 깐다 */
.rm-node::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: radial-gradient(180px circle at var(--mx, 50%) var(--my, 50%), rgba(255, 255, 255, 0.12), transparent 70%);
  opacity: 0;
  transition: opacity 0.3s ease;
  pointer-events: none;
}
.rm-node:hover::before { opacity: 1; }
/* 줄기: 처음엔 접혀 있다가 점에서 카드 쪽으로 쭉 그려진다 */
.rm-node::after {
  content: '';
  position: absolute;
  left: 7px; /* 점(폭 14px)의 가운데 */
  width: 1px;
  height: 30px;
  background: rgba(46, 204, 113, 0.5);
  transform: scaleY(0);
  transition: transform 0.5s ease 0.25s;
}
.rm-slot--up .rm-node   { bottom: calc(50% + 36px); transform: translateY(16px); border-bottom-left-radius: 3px; }
.rm-slot--down .rm-node { top: calc(50% + 36px);    transform: translateY(-16px); border-top-left-radius: 3px; }
.rm-slot--up .rm-node::after   { top: 100%;    transform-origin: bottom; } /* 점은 줄기 아래 */
.rm-slot--down .rm-node::after { bottom: 100%; transform-origin: top; }    /* 점은 줄기 위 */
/* 축이 이 칸에 닿으면 점이 커지고 카드가 떠오른다 */
.rm-slot.reached .rm-dot   { transform: translate(0, -50%) scale(1); }
.rm-slot.reached .rm-node  { opacity: 1; filter: none; transform: translateY(0); }
.rm-slot.reached .rm-node::after { transform: scaleY(1); }

/* 카드 안 항목들은 위에서부터 차례로 올라온다 (--i는 roadmap.js가 넣은 순번) */
.rm-entry {
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 0.5s ease, transform 0.5s ease;
  transition-delay: calc(0.3s + var(--i, 0) * 0.13s);
}
.rm-slot.reached .rm-entry { opacity: 1; transform: none; }

/* "NOW" 구분선: 여기까지 한 일, 여기부터 할 일. 축이 닿으면 나타난다 */
.rm-now {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 0;
  border-left: 1px dashed rgba(243, 156, 18, 0.45);
  opacity: 0;
  transition: opacity 0.6s ease;
  pointer-events: none;
}
.rm-now.reached { opacity: 1; }
.rm-now span {
  position: absolute;
  bottom: 4px;
  left: 8px;
  font-size: 0.64rem;
  font-weight: 700;
  letter-spacing: 0.28em;
  color: #f39c12;
}
/* 움직임을 줄이도록 설정한 사용자는 흐르는 빛·물결·숨쉬기를 끄고 카드도 바로 나타나게 한다 */
@media (prefers-reduced-motion: reduce) {
  .rm-axis-fill,
  .rm-axis-fill::after,
  .rm-slot--wip .rm-dot,
  .rm-slot.reached .rm-dot::before { animation: none; }
  .rm-node,
  .rm-node::after,
  .rm-entry { filter: none; transition-duration: 0.01s; transition-delay: 0s; }
}

/* 한 묶음 칸 안의 항목 하나. 날짜는 칸 맨 위에 한 번만 쓰고 항목들을 가는 선으로 나눠 쌓는다 */
.rm-entry + .rm-entry {
  margin-top: 0.8rem;
  padding-top: 0.8rem;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}
.rm-date {
  display: block;
  margin-bottom: 0.55rem;
  font-size: 0.66rem;
  letter-spacing: 0.16em;
  color: rgba(46, 204, 113, 0.85);
  font-weight: 700;
}
.rm-slot--done .rm-date::before { content: '✓ '; }
.rm-title {
  display: block;
  margin: 0 0 0.3rem;
  font-size: 0.92rem;
  font-weight: 700;
  line-height: 1.4;
  color: rgba(255, 255, 255, 0.92);
}
.rm-desc {
  display: block;
  font-size: 0.76rem;
  line-height: 1.55;
  color: rgba(255, 255, 255, 0.5);
}
/* 진행 중: 호박색 테두리와 은은한 빛 */
.rm-slot--wip .rm-node {
  border-color: rgba(243, 156, 18, 0.6);
  background: linear-gradient(160deg, rgba(243, 156, 18, 0.14), rgba(243, 156, 18, 0.03));
  box-shadow: 0 0 36px -10px rgba(243, 156, 18, 0.45);
}
.rm-slot--wip .rm-node::after { background: rgba(243, 156, 18, 0.6); }
.rm-slot--wip .rm-date { color: #f39c12; }
/* 예정: 점선 테두리로 아직 비어 있음을 */
.rm-slot--todo .rm-node {
  border-style: dashed;
  border-color: rgba(255, 255, 255, 0.22);
  background: rgba(255, 255, 255, 0.025);
}
.rm-slot--todo .rm-node::after { background: rgba(255, 255, 255, 0.3); }
.rm-slot--todo .rm-date { color: rgba(255, 255, 255, 0.5); }
.rm-slot--todo .rm-title { color: rgba(255, 255, 255, 0.85); }

/* ===== ROADMAP 항목 클릭 → 카드가 옆으로 펼쳐지며 상세가 열린다 ===== */
/* 펼침의 모든 움직임(카드 폭 · 상세 칸의 폭과 높이 · 접히는 항목 · 뒤쪽 칸의 이동)이 아래 같은 시간·곡선(--rm-dur · --rm-ease)을 쓴다.
   그래서 따로 놀지 않고 한 덩어리로 숨 쉬듯 커지고 줄어든다. 값은 roadmap.js도 읽어 쓰므로 여기서만 바꾼다 */
.rm-section {
  --rm-dur: 650ms;
  --rm-ease: cubic-bezier(0.45, 0, 0.2, 1); /* 천천히 출발해 부드럽게 멈춘다 */
  --rm-detail-w: 400px;                     /* 펼쳤을 때 상세 칸의 폭 */
  --rm-detail-gap: 20px;                    /* 제목·설명 칸과 상세 칸 사이 간격 */
}

/* 상세가 있는 항목은 눌러 볼 수 있다는 표시: 손가락 커서 + 제목 옆 화살표 */
.rm-entry--link { cursor: pointer; }
.rm-entry--link .rm-title::after {
  content: ' \2192';
  margin-left: -4px;
  color: var(--rm-c);
  opacity: 0;
  transition: opacity 0.2s ease, margin-left 0.2s ease;
}
.rm-entry--link:hover .rm-title::after,
.rm-entry--link:focus-visible .rm-title::after { margin-left: 0; opacity: 1; }
.rm-entry--link:focus-visible { outline: 2px solid var(--rm-c); outline-offset: 4px; border-radius: 4px; }
.rm-entry.is-current .rm-title::after { display: none; } /* 열려 있는 항목에는 화살표가 필요 없다 */
/* 터치 화면은 마우스를 올릴 수 없으니 "누를 수 있음" 화살표를 항상 보여준다 */
@media (hover: none) {
  .rm-entry--link:not(.is-current) .rm-title::after { margin-left: 0; opacity: 1; }
}

/* 펼쳐진 카드는 이웃 카드 위로 */
.rm-slot.is-open,
.rm-slot.is-open .rm-node { z-index: 4; }

/* 펼친 카드: 왼쪽 = 날짜 + 항목들(그대로 남는다. 폭은 펼치기 전 그대로 고정해 글이 다시 줄바꿈되지 않게), 오른쪽 = 눌린 항목의 상세 */
.rm-node.is-expanded {
  display: grid;
  grid-template-columns: var(--rm-col) auto; /* --rm-col은 roadmap.js가 펼치기 직전의 왼쪽 칸 폭으로 넣는다 */
  align-items: start;
}
/* 지금 열려 있는 항목은 제목 색으로 표시 */
.rm-entry.is-current .rm-title { color: var(--rm-c); }

/* 상세 칸: 처음엔 폭·높이 0으로 접혀 있다가 같은 곡선으로 펼쳐진다. 안쪽(-inner)은 폭을 고정해 글이 다시 줄바꿈되지 않고, 바깥이 열리며 드러난다.
   (--rm-h는 roadmap.js가 안쪽의 실제 높이로 넣는다) */
.rm-entry-detail {
  grid-column: 2;
  grid-row: 1;
  width: 0;
  max-height: 0;
  margin-left: 0;
  opacity: 0;
  overflow: hidden;
  transition:
    width var(--rm-dur) var(--rm-ease),
    max-height var(--rm-dur) var(--rm-ease),
    margin-left var(--rm-dur) var(--rm-ease),
    opacity 0.25s ease;
}
.rm-node.is-expanded:not(.is-closing) .rm-entry-detail {
  width: var(--rm-detail-w);
  max-height: var(--rm-h);
  margin-left: var(--rm-detail-gap);
  opacity: 1;
  transition-delay: 0s, 0s, 0s, 0.2s; /* 폭이 절반쯤 열린 뒤에 글이 나타난다. 접을 때는 지연 없이 바로 사라진다 */
}
.rm-entry-detail-inner {
  position: relative;
  width: var(--rm-detail-w);
  padding-left: 20px;
  border-left: 1px solid rgba(255, 255, 255, 0.14);
}
.rm-entry-close {
  position: absolute;
  top: 0;                  /* 음수로 두면 위쪽이 상세 칸의 overflow: hidden에 잘린다 */
  right: 0;
  width: 26px;
  height: 26px;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.08);
  color: rgba(255, 255, 255, 0.7);
  font-size: 1.05rem;
  line-height: 1;
  cursor: pointer;
  transition: background 0.2s, color 0.2s;
}
.rm-entry-close:hover { background: #fff; color: #111; }

/* 상세 안의 글 */
.rm-detail-name {
  display: block;
  margin-bottom: 0.55rem;
  padding-right: 2rem; /* 닫기 버튼과 겹치지 않게 */
  font-size: 0.95rem;
  font-weight: 800;
  color: var(--rm-c);
}
.rm-story {
  margin: 0;
  font-size: 0.9rem;
  font-weight: 600;
  line-height: 1.75;
  color: rgba(255, 255, 255, 0.92);
}
.rm-points {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin: 0.9rem 0 0;
  padding: 0;
  list-style: none;
}
.rm-points li {
  position: relative;
  padding-left: 0.95rem;
  font-size: 0.82rem;
  line-height: 1.65;
  color: rgba(255, 255, 255, 0.68);
}
.rm-points li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.68em;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--rm-c);
}
/* 상세 안의 바깥 링크(예: 유튜브). 글 아래에 줄을 바꿔 한 줄로 놓는다 */
.rm-link {
  display: inline-block;
  margin-top: 0.9rem;
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--rm-c);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.rm-link:hover { color: #fff; }
/* 화면 캡처 썸네일: 상세 글 아래 한 줄. 장수가 늘어도 상세 칸 폭(400px) 안에 들어가도록 칸이 똑같이 줄어들고(flex: 1 1 0),
   높이는 64px로 고정해 사진이 불러지기 전에도 카드 높이를 미리 잴 수 있다. 칸보다 큰 사진은 가운데만 보이게 자른다. 누르면 크게 뜬다 */
.rm-shots {
  display: flex;
  gap: 8px;
  margin-top: 0.9rem;
}
.rm-shot { display: block; flex: 1 1 0; min-width: 0; max-width: 114px; cursor: zoom-in; }
.rm-shot img {
  display: block;
  height: 64px;
  width: 100%;
  object-fit: cover;
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 6px;
  transition: border-color 0.2s;
}
.rm-shot:hover img { border-color: rgba(255, 255, 255, 0.5); }

/* 캡처 크게 보기: 화면 위에 어둡게 깔리고 사진이 커지며 나타난다. body에 붙으므로 .rm-section의 변수를 못 써서 곡선을 직접 적었다 */
html.rm-lock { overflow: hidden; }
.rm-lightbox {
  position: fixed;
  inset: 0;
  z-index: 3000; /* 메뉴바(최대 2000)보다 위 */
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(5, 5, 7, 0);
  backdrop-filter: blur(0);
  cursor: zoom-out;
  transition: background 0.35s ease, backdrop-filter 0.35s ease;
}
.rm-lightbox.open { background: rgba(5, 5, 7, 0.88); backdrop-filter: blur(8px); }
.rm-lightbox-fig {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.8rem;
  max-width: 92vw;
  margin: 0;
  opacity: 0;
  transform: scale(0.94);
  transition: opacity 0.35s ease, transform 0.45s cubic-bezier(0.45, 0, 0.2, 1);
}
.rm-lightbox.open .rm-lightbox-fig { opacity: 1; transform: none; }
.rm-lightbox-fig img {
  max-width: 92vw;
  max-height: 80vh;
  border-radius: 10px;
  box-shadow: 0 30px 80px -20px #000;
}
.rm-lightbox-cap {
  max-width: 80vw;
  font-size: 0.95rem;
  line-height: 1.6;
  text-align: center;
  color: rgba(255, 255, 255, 0.8);
}
.rm-lightbox-close,
.rm-lightbox-nav {
  position: absolute;
  border: 1px solid rgba(255, 255, 255, 0.3);
  border-radius: 50%;
  background: rgba(11, 11, 13, 0.6);
  color: #fff;
  line-height: 1;
  cursor: pointer;
  transition: background 0.2s, color 0.2s;
}
.rm-lightbox-close { top: 20px; right: 26px; width: 44px; height: 44px; font-size: 1.6rem; }
.rm-lightbox-nav { top: 50%; width: 48px; height: 48px; margin-top: -24px; font-size: 2rem; padding-bottom: 4px; }
.rm-lightbox-prev { left: 26px; }
.rm-lightbox-next { right: 26px; }
.rm-lightbox-close:hover,
.rm-lightbox-nav:hover:not(:disabled) { background: #fff; color: #111; }
.rm-lightbox-nav:disabled { opacity: 0.25; cursor: default; }
.rm-lightbox-count {
  position: absolute;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%);
  font-family: 'Bebas Neue', sans-serif;
  font-size: 1.3rem;
  letter-spacing: 0.1em;
  color: rgba(255, 255, 255, 0.6);
}
@media (prefers-reduced-motion: reduce) {
  .rm-lightbox, .rm-lightbox-fig { transition-duration: 0.01s; }
}
/* 글이 열린 뒤 한 덩어리씩 살짝 떠오른다 (--k는 roadmap.js가 매긴 순번) */
.rm-entry-detail-inner > * {
  animation: rmFadeUp 0.5s ease backwards;
  animation-delay: calc(0.35s + var(--k, 0) * 0.07s);
}
@keyframes rmFadeUp {
  from { opacity: 0; transform: translateY(8px); }
}
/* 움직임을 줄이도록 설정한 사용자는 펼침도 바로 끝난다 */
@media (prefers-reduced-motion: reduce) {
  .rm-section { --rm-dur: 1ms; }
  .rm-entry-detail-inner > * { animation: none; }
}

/* ===== 콘텐츠 섹션 공통 ===== */
.content-section {
  padding: 120px 8vw;
  background: #fff;
}
.content-section--dark {
  background: #111;
  color: #fff;
}
.content-section--dark .section-label { color: #fff; }
/* 기술 스택: 바로 위 ROADMAP(#0b0b0d)과 배경이 같아 이어 보이지 않도록 한 톤 밝은 색 + 윗선 */
.content-section.tech-section {
  background: #1b1c20;
  border-top: 1px solid rgba(255, 255, 255, 0.1);
}

/* ===== 공통 텍스트 ===== */
.section-label {
  margin: 0 0 0.8rem;
  font-size: 0.75rem;
  letter-spacing: 0.3em;
  color: #111;
  font-weight: 700;
}
h2 {
  margin: 0 0 1.2rem;
  font-size: clamp(2rem, 4vw, 3rem);
  font-weight: 800;
  line-height: 1.2;
}

/* ===== 스크롤 애니메이션 ===== */
/* 초기 상태: 숨김 */
.reveal {
  opacity: 0;
  transition: opacity 0.8s ease, transform 0.8s ease;
}
/* (left·right 방향은 쓰는 섹션이 없어져 지웠다 — 지금은 기술 스택의 up 하나뿐) */
.reveal[data-dir="up"]    { transform: translateY(50px); }

/* 뷰포트 진입 시: 보임 */
.reveal.visible {
  opacity: 1;
  transform: translate(0, 0);
}

/* 히어로 자체 페이드업 */
.fade-up {
  opacity: 0;
  transform: translateY(30px);
  transition: opacity 1s ease 0.3s, transform 1s ease 0.3s;
}
.fade-up.visible {
  opacity: 1;
  transform: translateY(0);
}

/* hero-content는 translate(-50%,-50%) 중앙 정렬 사용 중이라
   fade-up의 transform이 덮어쓰지 않도록 별도로 정의 */
.hero-content.fade-up {
  transform: translate(-50%, calc(-50% + 30px));
}
.hero-content.fade-up.visible {
  transform: translate(-50%, -50%);
}
