/* ============================================================
 * styles.css — 윤소율 포트폴리오
 * 톤: 모노크롬 미니멀 — 순백 / 니어블랙 / 코발트 포인트 1색
 * 주의: 전역 규칙 — flex/grid `gap` 사용 금지. 간격은 margin으로.
 * ============================================================ */

:root {
  --bg:      #FFFFFF;
  --bg-2:    #FAFAFB;   /* raised panel */
  --bg-3:    #F3F4F6;   /* deeper panel */
  --line:    #E8EAED;   /* hairline */
  --line-2:  #D6D9DE;
  --ink:     #111318;
  --ink-soft:#697077;   /* cool gray */
  --accent:  #1D4ED8;   /* cobalt — the single point color */
  --accent-2:#1638A8;

  --maxread: 44rem;
  --maxwide: 68rem;

  --r-sm: 4px;
  --r-md: 8px;

  --f-body: "Pretendard", -apple-system, BlinkMacSystemFont, "Apple SD Gothic Neo", system-ui, sans-serif;
  --f-mono: "IBM Plex Mono", ui-monospace, "SFMono-Regular", Menlo, monospace;
}

*, *::before, *::after { box-sizing: border-box; }

html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--f-body);
  font-size: 16.5px;
  line-height: 1.72;
  letter-spacing: -0.005em;
  /* 한글은 어절 단위로만 끊는다 — 없으면 '재구성'이 '재구/성'으로 쪼개진다.
     긴 URL·영문 식별자는 컨테이너를 넘칠 수 있으므로 overflow-wrap으로 예외 처리. */
  word-break: keep-all;
  overflow-wrap: anywhere;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

a { color: var(--accent); text-decoration: none; }
a:hover { color: var(--accent-2); }

img { max-width: 100%; height: auto; display: block; }

::selection { background: rgba(29,78,216,.14); }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 2px;
}

.skip-link {
  position: absolute; left: -999px; top: 0;
  background: var(--ink); color: var(--bg);
  padding: .6rem 1rem; z-index: 100;
}
.skip-link:focus { left: 0; }

/* ---------- Top bar ---------- */
.topbar {
  position: sticky; top: 0; z-index: 50;
  display: flex; align-items: center;
  padding: .75rem clamp(1rem, 4vw, 2.4rem);
  background: rgba(255,255,255,.86);
  backdrop-filter: saturate(150%) blur(10px);
  -webkit-backdrop-filter: saturate(150%) blur(10px);
  border-bottom: 1px solid var(--line);
}
.topbar__brand {
  font-size: 1.02rem; font-weight: 800; color: var(--ink);
  letter-spacing: -0.02em;
}
.topbar__nav {
  display: flex; flex-wrap: wrap; align-items: center;
  margin-left: auto;
}
.topbar__nav a {
  font-size: .82rem; color: var(--ink-soft);
  padding: .3rem .1rem; margin-left: 1.2rem;
  border-bottom: 1.5px solid transparent;
  transition: color .15s, border-color .15s;
}
.topbar__nav a:hover, .topbar__nav a.is-active {
  color: var(--ink); border-color: var(--ink);
}
.lang-toggle {
  margin-left: 1.4rem;
  font-family: var(--f-mono); font-size: .7rem; font-weight: 500;
  letter-spacing: .06em;
  color: var(--ink); background: var(--bg);
  border: 1px solid var(--line-2); border-radius: var(--r-sm);
  padding: .32rem .7rem; cursor: pointer;
  transition: border-color .15s, background .15s;
}
.lang-toggle:hover { border-color: var(--ink); }
.print-btn {
  margin-left: 1.4rem;
  font-family: var(--f-mono); font-size: .7rem; font-weight: 500;
  letter-spacing: .06em;
  color: var(--ink-soft); background: var(--bg);
  border: 1px solid var(--line-2); border-radius: var(--r-sm);
  padding: .32rem .7rem; cursor: pointer;
  transition: border-color .15s, color .15s;
}
.print-btn:hover { border-color: var(--ink); color: var(--ink); }
.lang-toggle { margin-left: .5rem; }
@media (max-width: 680px) {
  .topbar__nav { display: none; }
  .print-btn { margin-left: auto; } /* nav가 사라지면 우측 정렬을 대신 맡는다 */
}
@media (max-width: 460px) {
  .print-btn { display: none; }     /* 모바일에서 PDF 저장은 실효가 없다 */
  .lang-toggle { margin-left: auto; }
}

/* ---------- Section shells ---------- */
main > section[id], .hero { scroll-margin-top: 64px; }

.section {
  padding: clamp(3.2rem, 8vw, 5.6rem) clamp(1.15rem, 5vw, 2.4rem);
  margin: 0 auto;
}
.section--read { max-width: calc(var(--maxread) + 4.8rem); }
.section--wide { max-width: calc(var(--maxwide) + 4.8rem); }

.eyebrow {
  display: inline-flex; align-items: center;
  font-family: var(--f-mono); font-size: .7rem; font-weight: 500;
  letter-spacing: .18em; text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 1.1rem;
}
.eyebrow::before {
  content: ""; width: 1.5rem; height: 1.5px;
  background: var(--accent); margin-right: .7rem; display: inline-block;
}

.section__title {
  font-weight: 800;
  font-size: clamp(1.6rem, 4vw, 2.3rem);
  line-height: 1.2; letter-spacing: -0.03em;
  text-wrap: balance; margin: 0 0 .9rem;
}
.section__lead {
  color: var(--ink-soft); max-width: var(--maxread);
  font-size: 1.02rem; margin: 0 0 2.4rem; white-space: pre-line;
}

/* ---------- Hero ---------- */
.hero {
  max-width: calc(var(--maxwide) + 4.8rem);
  margin: 0 auto;
  padding: clamp(3.5rem, 10vw, 7.5rem) clamp(1.15rem, 5vw, 2.4rem) clamp(3rem, 7vw, 4.6rem);
}
.hero__eyebrow {
  font-family: var(--f-mono); font-size: .74rem; letter-spacing: .18em;
  text-transform: uppercase; color: var(--ink-soft); margin: 0 0 1.4rem;
}
.hero__name {
  font-weight: 800;
  font-size: clamp(2.4rem, 8vw, 4rem); line-height: 1.02;
  margin: 0 0 1.6rem; letter-spacing: -0.045em; white-space: nowrap;
}
.hero__thesis {
  font-size: clamp(1.35rem, 4vw, 2.2rem);
  line-height: 1.34; font-weight: 700; letter-spacing: -0.03em;
  text-wrap: balance; max-width: 26em;
  margin: 0 0 1.6rem;
}
.hero__thesis .accent { color: var(--accent); }
.hero__sub {
  color: var(--ink-soft); max-width: 40rem;
  font-size: 1.05rem; margin: 0 0 2.2rem; text-wrap: pretty;
}
.hero__cta { display: flex; flex-wrap: wrap; align-items: center; margin: 0 0 2.2rem; }
.btn {
  display: inline-flex; align-items: center;
  font-size: .92rem; font-weight: 700;
  padding: .7rem 1.35rem; border-radius: var(--r-sm);
  border: 1.5px solid transparent; cursor: pointer;
  transition: transform .12s, background .15s, border-color .15s, color .15s;
}
.btn:active { transform: translateY(1px); }
.btn--primary { background: var(--ink); color: #fff; }
.btn--primary:hover { background: #000; color: #fff; }
.btn--ghost { color: var(--ink); border-color: var(--line-2); margin-left: .7rem; }
.btn--ghost:hover { border-color: var(--ink); color: var(--ink); }
.hero__role {
  display: inline-flex; align-items: flex-start;
  font-size: .88rem; color: var(--ink-soft);
  border-top: 1px solid var(--line); padding-top: 1.25rem;
  max-width: 42rem;
}
.hero__role::before {
  content: ""; width: 8px; height: 8px; border-radius: 999px;
  background: var(--accent);
  margin: .5rem .6rem 0 0; flex-shrink: 0;
}

/* ---------- Strengths (3열 그리드, gap 미사용) ---------- */
.strengths__grid {
  display: grid; grid-template-columns: repeat(3, 1fr);
}
.strength {
  padding: 1.5rem 1.6rem;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--bg);
}
.strengths__grid > *:nth-child(n+4) { margin-top: 1rem; }
.strengths__grid > *:not(:nth-child(3n+1)) { margin-left: 1rem; }
.strength__k {
  font-weight: 800; letter-spacing: -0.02em;
  font-size: 1.08rem; margin: 0 0 .55rem; line-height: 1.32;
}
.strength__k .idx {
  font-family: var(--f-mono); font-size: .78rem; font-weight: 500;
  color: var(--accent); margin-right: .55rem;
}
.strength__v { color: var(--ink-soft); font-size: .93rem; margin: 0; }
@media (max-width: 900px) {
  .strengths__grid { grid-template-columns: repeat(2, 1fr); }
  .strengths__grid > *:not(:nth-child(3n+1)) { margin-left: 0; }
  .strengths__grid > *:nth-child(even) { margin-left: 1rem; }
  .strengths__grid > *:nth-child(n+3) { margin-top: 1rem; }
}
@media (max-width: 620px) {
  .strengths__grid { grid-template-columns: 1fr; }
  .strengths__grid > *:nth-child(even) { margin-left: 0; }
  .strengths__grid > *:nth-child(n+2) { margin-top: .9rem; }
}

/* ---------- Metrics ---------- */
.metrics__grid {
  display: grid; grid-template-columns: repeat(4, 1fr);
}
.metric {
  padding: 1.3rem 1.1rem 1.3rem 0;
  border-top: 1.5px solid var(--ink);
}
.metric__fig {
  font-family: var(--f-mono); font-weight: 500;
  font-variant-numeric: tabular-nums;
  font-size: clamp(1.3rem, 3.2vw, 1.7rem);
  color: var(--ink); line-height: 1.1; margin: 0 0 .5rem;
  letter-spacing: -0.02em; white-space: nowrap;
}
.metric.is-projected .metric__fig { color: var(--accent); }
.metric__fig .star { font-size: .7em; vertical-align: .35em; margin-right: .1em; }
.metric__label { font-size: .84rem; color: var(--ink-soft); margin: 0; }
.metrics__grid > *:nth-child(n+5) { margin-top: .6rem; }
.metric:not(:nth-child(4n+1)) { margin-left: 1.4rem; }
.metrics__note {
  font-family: var(--f-mono); font-size: .72rem; color: var(--ink-soft);
  margin: 1.6rem 0 0; letter-spacing: .01em;
}
@media (max-width: 820px) {
  .metrics__grid { grid-template-columns: repeat(2, 1fr); }
  .metric:not(:nth-child(4n+1)) { margin-left: 0; }
  .metric:not(:nth-child(2n+1)) { margin-left: 1.4rem; }
  .metrics__grid > *:nth-child(n+3) { margin-top: .6rem; }
}
@media (max-width: 460px) {
  .metrics__grid { grid-template-columns: 1fr; }
  .metric:not(:nth-child(2n+1)) { margin-left: 0; }
  .metrics__grid > *:nth-child(n+2) { margin-top: .4rem; }
}

/* ---------- Journey (timeline) ---------- */
.journey__wrap { position: relative; }
.journey__line {
  position: absolute; left: 6px; top: .4rem; bottom: 2.6rem;
  width: 1.5px; background: var(--line-2);
}
.jstep { position: relative; padding: 0 0 2.1rem 2.4rem; }
.jstep:last-of-type { padding-bottom: .6rem; }
.jstep::before {
  content: ""; position: absolute; left: 0; top: .4rem;
  width: 13px; height: 13px; border-radius: 999px;
  background: var(--bg); border: 2px solid var(--line-2);
}
.jstep:last-of-type::before { border-color: var(--accent); background: var(--accent); }
.jstep__period {
  font-family: var(--f-mono); font-size: .74rem; letter-spacing: .04em;
  color: var(--ink-soft); font-variant-numeric: tabular-nums;
}
.jstep__tag {
  display: inline-block; font-size: .7rem; font-weight: 700;
  color: var(--ink); background: var(--bg-3);
  padding: .12rem .5rem; border-radius: var(--r-sm); margin-left: .6rem;
}
.jstep__title {
  font-weight: 800; font-size: 1.15rem; letter-spacing: -0.02em;
  margin: .35rem 0 .35rem; line-height: 1.3;
}
.jstep__body { color: var(--ink-soft); font-size: .95rem; margin: 0; }
.journey__aside {
  margin: 1.6rem 0 0 2.4rem; padding: 1.05rem 1.25rem;
  background: var(--bg-2); border-left: 2px solid var(--accent);
  color: var(--ink-soft); font-size: .9rem; white-space: pre-line;
}

/* ---------- Status badge ---------- */
/* 성격 배지(.badge)와 대표작·대회 칩은 같은 규격을 쓴다. 따로 두면
   같은 줄에서 높이가 널뛴다. */
.badge {
  display: inline-flex; align-items: center; flex-shrink: 0;
  height: 1.45rem; padding: 0 .4rem; border-radius: var(--r-sm);
  font-family: var(--f-mono); font-size: .62rem; font-weight: 500; letter-spacing: .04em;
  line-height: 1; white-space: nowrap;
  border: 1px solid var(--line-2); color: var(--ink-soft);
}
@supports (text-box: trim-both cap alphabetic) {
  .badge { text-box: trim-both cap alphabetic; }
}
.badge--pub     { color: var(--accent); border-color: var(--accent); }
.badge--priv    { color: var(--ink-soft); }
.badge--local   { color: var(--ink-soft); border-style: dashed; }
.badge--service { color: #fff; background: var(--ink); border-color: var(--ink); }
.fwork__head .badge { margin-left: .7rem; }
/* 이름 옆에 붙인다. auto를 주면 오른쪽 끝으로 밀려 이름과 떨어진다. */
.pcard__top .badge { margin-left: .4rem; flex-shrink: 0; }

/* ---------- Scope pills (참여 범위) ---------- */
.scope { display: inline-flex; flex-wrap: wrap; align-items: center; }
.scope-pill {
  font-family: var(--f-mono); font-size: .66rem; font-weight: 500;
  letter-spacing: .02em;
  padding: .15rem .5rem; border-radius: var(--r-sm);
  background: var(--bg-3); color: var(--ink);
}
.scope-pill:not(:first-child) { margin-left: .35rem; }
.scope-pill--plan { background: rgba(29,78,216,.08); color: var(--accent); }
.fwork__scope { margin: -.4rem 0 1.2rem; }
.pcard__scope { margin: 0 0 .7rem; }

/* ---------- Featured work ---------- */
.featured__list { display: block; }
.fwork {
  border: 1px solid var(--line); border-radius: var(--r-md);
  background: var(--bg);
  padding: clamp(1.5rem, 4vw, 2.2rem);
  margin-top: 1.2rem;
}
.fwork:first-child { margin-top: 0; }
.fwork__head {
  display: flex; flex-wrap: wrap; align-items: baseline;
  border-bottom: 1px solid var(--line); padding-bottom: 1rem; margin-bottom: 1.2rem;
}
.fwork__title {
  font-weight: 800; letter-spacing: -0.025em;
  font-size: clamp(1.2rem, 3vw, 1.5rem); margin: 0; line-height: 1.25;
}
/* 배지는 제목 안에서 마지막 단어를 따라간다 — 제목이 길어져도 혼자 다음 줄로 떨어지지 않게.
   baseline 기준으로 띄우면 제목보다 높이 떠 보여서, 글자 중앙(middle)에 맞춘다. */
.fwork__title .badge {
  margin-left: .5rem; vertical-align: middle;
  position: relative; top: -.06em;
}
.fwork__role {
  font-family: var(--f-mono); font-size: .72rem; color: var(--ink-soft);
  letter-spacing: .02em; line-height: 1.5;
  /* 역할 표기가 짧게는 12자, 길게는 34자다. 제목 줄 오른쪽에 붙이면 길이에 따라
     상태 배지를 다음 줄로 밀어내므로, 제목 아래 줄로 내려 좌측에 정렬한다. */
  order: 3; width: 100%; margin: .45rem 0 0; padding-left: 0;
}
.fwork__grid { display: grid; grid-template-columns: repeat(3, 1fr); }
.fstage:not(:first-child) { margin-left: 1.5rem; }
.fstage__k {
  font-family: var(--f-mono); font-size: .68rem; letter-spacing: .14em;
  text-transform: uppercase; margin: 0 0 .5rem;
  color: var(--ink-soft);
}
.fstage--i .fstage__k { color: var(--accent); }
.fstage__v { font-size: .93rem; margin: 0; color: var(--ink-soft); }
.fstage--i .fstage__v { color: var(--ink); }
.fwork__foot { margin-top: 1.3rem; }
.repo-link {
  display: inline-flex; align-items: center;
  font-family: var(--f-mono); font-size: .76rem; font-weight: 500;
  color: var(--accent); border: 1px solid var(--line-2);
  padding: .35rem .8rem; border-radius: var(--r-sm);
}
.repo-link:hover { border-color: var(--accent); }
.repo-link.is-locked { color: var(--ink-soft); cursor: default; }
/* 비공개 프로젝트 문의는 실제 연락 가능한 링크다. 데모 제공을 약속하지 않는다. */
a.repo-link.is-locked { cursor: pointer; text-decoration: underline; text-underline-offset: 3px; }
a.repo-link.is-locked:hover { color: var(--ink); }
@media (max-width: 700px) {
  .fwork__grid { grid-template-columns: 1fr; }
  .fstage:not(:first-child) { margin-left: 0; margin-top: 1.1rem; }
}

/* ---------- Projects grid ---------- */
.pgroup { margin-top: 2.6rem; }
.pgroup:first-of-type { margin-top: 0; }
.pgroup__name {
  font-weight: 800; font-size: 1.08rem; letter-spacing: -0.02em;
  margin: 0 0 1.1rem; padding-bottom: .5rem;
  border-bottom: 1.5px solid var(--ink);
  display: flex; align-items: baseline;
}
.pgroup__count {
  font-family: var(--f-mono); font-size: .72rem; color: var(--ink-soft);
  margin-left: auto; font-weight: 400;
}
.pgrid { display: grid; grid-template-columns: repeat(2, 1fr); }
.pcard {
  border: 1px solid var(--line); border-radius: var(--r-md);
  background: var(--bg); padding: 1.05rem 1.2rem;
  display: flex; flex-direction: column;
  transition: border-color .15s;
}
a.pcard:hover { border-color: var(--ink); }
.pgrid > *:nth-child(n+3) { margin-top: .9rem; }
.pgrid > *:nth-child(even) { margin-left: .9rem; }
/* 이름이 늘어나면 배지가 오른쪽 끝으로 밀려 이름과 떨어진다.
   늘리지 않고(flex-grow 0) 바로 옆에 붙이되, 좁아지면 줄을 접는다. */
.pcard__top {
  display: flex; flex-wrap: wrap; align-items: center;
  margin-top: calc(var(--r-sm) * -1); margin-bottom: .45rem;
}
.pcard__top > * { margin-top: var(--r-sm); }
.pcard__name { flex: 0 1 auto; min-width: 0; }
.pcard__name {
  font-weight: 700; font-size: .95rem; color: var(--ink);
  font-family: var(--f-mono); letter-spacing: -0.01em;
}
/* 상태는 세 갈래다 — 운영 중 / 진행 중 / 중단 */
/* 상태는 테두리 없이 글자로 둔다. 칩이 넷이면 이름이 묻힌다. */
.pcard__stage {
  flex-shrink: 0; margin-left: auto; padding-left: .6rem; white-space: nowrap;
  font-family: var(--f-mono); font-size: .64rem; font-weight: 500; letter-spacing: .05em;
  color: var(--ink-soft);
}
/* 좁은 화면에서는 margin-left:auto가 상태 표기를 다음 줄 오른쪽 끝으로 혼자
   밀어낸다(제목 옆 배지와 따로 놀아 보인다). 배지 흐름에 그대로 합류시킨다. */
@media (max-width: 560px) {
  .pcard__stage { margin-left: .3rem; padding-left: 0; }
}
.pcard__stage.is-live { color: var(--accent); }

/* 글자가 상자 위로 뜨는 건 폰트가 잡아둔 디센더 자리 탓이다.
   trim으로 그 여백을 걷어내면 매직넘버 없이 광학 중심에 온다. */
/* 작은 칩은 inline-flex로 세로 중앙을 잡는다. text-box는 폰트가 잡아둔
   디센더 자리만 걷어내는 용도이고, 높이는 padding으로 따로 준다.
   (trim만 걸고 padding을 그대로 두면 상자가 cap 높이로 찌부러진다) */
/* 배지는 종류가 넷이다(대표작·대회·상태·공개). 크기와 간격을 한 곳에서
   묶어두지 않으면 카드마다 높이가 널뛴다. */
.pcard__star, .pcard__comp {
  display: inline-flex; align-items: center; flex-shrink: 0;
  height: 1.45rem; padding: 0 .4rem; margin-left: .3rem;
  font-family: var(--f-mono); font-size: .62rem; font-weight: 500; letter-spacing: .04em;
  line-height: 1; border-radius: var(--r-sm); white-space: nowrap;
  border: 1px solid var(--line-2); color: var(--ink-soft); background: var(--bg);
}
@supports (text-box: trim-both cap alphabetic) {
  .pcard__star, .pcard__comp { text-box: trim-both cap alphabetic; }
}
.pcard__star { color: var(--accent); border-color: rgba(29,78,216,.24); background: rgba(29,78,216,.07); }
.pcard__d { font-size: .88rem; color: var(--ink-soft); margin: 0 0 .7rem; }
.pcard__foot {
  display: flex; align-items: center; margin-top: auto;
  padding-top: .3rem;
}
.pcard__tech {
  font-family: var(--f-mono); font-size: .7rem; color: var(--ink-soft);
  min-width: 0;
}
.pcard__tag {
  margin-left: auto; font-family: var(--f-mono); font-size: .66rem;
  color: var(--ink-soft); white-space: nowrap; padding-left: .8rem;
}
.pcard__tag.is-pub { color: var(--accent); }
@media (max-width: 620px) {
  .pgrid { grid-template-columns: 1fr; }
  .pgrid > *:nth-child(n+2) { margin-top: .8rem; }
  .pgrid > *:nth-child(even) { margin-left: 0; }
}

/* Compact ≤599: 구두점 고아와 카드 하단의 강제 압축을 없앤다.
   제목·숫자는 묶고, 긴 본문은 어절 단위로 자연스럽게 흐르게 둔다. */
@media (max-width: 599px) {
  .hero__eyebrow { line-height: 1.65; }
  .hero__sub, .section__lead, .pcard__d, .fwork__role,
  .fstage__v, .jstep__body, .mrow__v, .contact__body { text-wrap: pretty; }

  .pcard__foot { flex-wrap: wrap; align-items: flex-start; }
  .pcard__tech { flex: 1 1 100%; }
  .pcard__tag {
    flex-basis: 100%; margin-left: 0; margin-top: .5rem;
    padding-left: 0;
  }

  .contact__link { min-width: 0; max-width: 100%; }
  .contact__link .clabel { flex-shrink: 0; }
}

/* ---------- Method ---------- */
.mrow {
  display: grid; grid-template-columns: 1fr 1.5fr;
  padding: 1.35rem 0; border-top: 1px solid var(--line);
}
.mrow:last-child { border-bottom: 1px solid var(--line); }
.mrow__k {
  font-weight: 800; font-size: 1.08rem; letter-spacing: -0.02em;
  margin: 0; padding-right: 1.5rem; line-height: 1.4;
}
.mrow__v { color: var(--ink-soft); font-size: .95rem; margin: 0; }
@media (max-width: 640px) {
  .mrow { grid-template-columns: 1fr; }
  .mrow__v { margin-top: .5rem; }
  .mrow__k { padding-right: 0; }
}

/* ---------- Contact ---------- */
.contact__body { color: var(--ink-soft); max-width: 38rem; font-size: 1.02rem; margin: 0 0 2rem; white-space: pre-line; }
.contact__links { display: flex; flex-wrap: wrap; align-items: center; }
.contact__link {
  display: inline-flex; align-items: center;
  font-size: .98rem; font-weight: 700; margin-right: 1.6rem; margin-bottom: .6rem;
  color: var(--ink);
}
.contact__link .clabel {
  font-family: var(--f-mono); font-size: .64rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--accent);
  margin-right: .6rem;
}
.contact__link:hover { color: var(--accent); }

/* ---------- Footer ---------- */
.footer {
  border-top: 1px solid var(--line);
  padding: 2rem clamp(1.15rem, 5vw, 2.4rem);
  max-width: calc(var(--maxwide) + 4.8rem); margin: 0 auto;
  display: flex; flex-wrap: wrap; align-items: center;
  color: var(--ink-soft); font-size: .82rem;
}
.footer__note { margin: 0; }
.footer__top {
  margin-left: auto;
  font-family: var(--f-mono); font-size: .74rem; color: var(--ink);
}

/* ---------- Featured card (compact, links to detail) ---------- */
.fwork--card { display: block; color: inherit; cursor: pointer; }
a.fwork--card:hover { border-color: var(--ink); }
.fwork__hook {
  font-size: 1.02rem; color: var(--ink); margin: .2rem 0 1.1rem;
  line-height: 1.5; letter-spacing: -0.01em;
}
.fwork__stage { order: 2; margin-left: auto; padding-left: .9rem; align-self: baseline; flex-shrink: 0; }
.fwork__more {
  font-family: var(--f-mono); font-size: .78rem; color: var(--accent);
}
a.fwork--card:hover .fwork__more { color: var(--accent-2); }

/* ---------- Detail 4-section story ---------- */
.dsec { margin: 0 0 1.6rem; }
.dsec__k {
  font-family: var(--f-mono); font-size: .72rem; font-weight: 500;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--accent); margin: 0 0 .55rem;
}
.dsec__v { font-size: .96rem; color: var(--ink-soft); margin: 0 0 .5rem; line-height: 1.65; }
.dsec__v:last-child { margin-bottom: 0; }
.dsec__list { margin: 0; padding: 0; list-style: none; }
.dsec__list li {
  position: relative; padding-left: 1.1rem; margin-bottom: .55rem;
  font-size: .96rem; color: var(--ink); line-height: 1.55;
}
.dsec__list li::before {
  content: ""; position: absolute; left: 0; top: .6rem;
  width: 5px; height: 5px; border-radius: 999px; background: var(--accent);
}
.dsec__list li:last-child { margin-bottom: 0; }

/* ---------- 2depth detail panel ---------- */
.detail { position: fixed; inset: 0; z-index: 80; display: none; }
.detail.is-open { display: block; }
.detail__scrim {
  position: absolute; inset: 0;
  background: rgba(17,19,24,.44);
}
.detail__panel {
  position: absolute; top: 0; right: 0; bottom: 0;
  width: min(680px, 100%);
  background: var(--bg);
  border-left: 1px solid var(--line);
  overflow-y: auto;
  padding: clamp(1.6rem, 4vw, 2.6rem);
  animation: detail-in .22s ease;
}
@keyframes detail-in {
  from { transform: translateX(24px); opacity: 0; }
  to   { transform: none; opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .detail__panel { animation: none; }
}
.detail__back {
  display: inline-block;
  font-family: var(--f-mono); font-size: .78rem; color: var(--ink-soft);
  margin-bottom: 1.6rem;
}
.detail__back:hover { color: var(--ink); }
.detail__title {
  font-weight: 800; letter-spacing: -0.03em;
  font-size: clamp(1.4rem, 3.4vw, 1.9rem); line-height: 1.22;
  margin: 0 0 .7rem;
}
.detail__title .pcard__stage { font-size: .7rem; vertical-align: .35em; }
.detail__badges { margin: 0 0 .6rem; }
.detail__scope { margin: 0 0 1.2rem; }
.dmeta {
  border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
  padding: .8rem 0; margin: 0 0 1.5rem;
}
.dmeta__row { display: flex; font-size: .88rem; padding: .18rem 0; }
.dmeta__k {
  font-family: var(--f-mono); font-size: .68rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--ink-soft);
  width: 5.2rem; flex-shrink: 0; padding-top: .18rem;
}
.detail__desc { color: var(--ink); font-size: .96rem; margin: 0 0 1.4rem; }
.dstage { margin: 0 0 1.3rem; }
.dstage__v { font-size: .94rem; color: var(--ink-soft); margin: 0; }
.dstage--i .dstage__v { color: var(--ink); }
/* 방향 자동감지 갤러리 — 세로(폰)컷은 나란히, 가로컷은 풀폭 */
.dshots { display: flex; flex-wrap: wrap; align-items: flex-start; margin: 1.6rem 0 .8rem; }
.dshot {
  margin: 0 .7rem .7rem 0; border: 1px solid var(--line); border-radius: var(--r-md);
  overflow: hidden; background: var(--bg-3);
  display: flex; flex-direction: column; align-items: stretch;
  min-width: 190px;   /* 캡션이 한 글자씩 끊기지 않을 최소 폭 */
}
.dshot img { margin: 0 auto; }
.dshot__cap {
  font-size: .78rem; line-height: 1.5; color: var(--ink-soft);
  padding: .5rem .65rem; background: var(--bg);
  border-top: 1px solid var(--line);
}
.dshot img { display: block; height: auto; }
/* 기본(로드 전) 및 가로컷: 한 줄 풀폭 */
.dshot { width: 100%; }
.dshot img { width: 100%; max-height: 74vh; object-fit: contain; }
/* 세로(폰)컷: 높이 고정, 자연 너비 → 여러 장 나란히 */
/* 세로컷은 폭을 묶는다. 높이를 고정하면 9:19.5 폰 화면이 폭 94px까지
   줄어 글자가 사라진다(실측 31건). 폭 기준이면 비율과 무관하게 읽힌다. */
.dshot.is-phone { width: 244px; }
.dshot.is-phone img { width: 100%; height: auto; max-height: 620px; object-fit: contain; }
/* 넓은 화면에서는 보통 가로컷을 2장씩 — 한 장씩 쌓으면 세로로만 길어진다.
   가로:세로 2배가 넘는 도표(.is-wide)는 좁히면 글자가 죽으므로 한 줄을 다 쓴다. */
@media (min-width: 900px) {
  /* 2열(≈370px)에 넣으면 1200px 캡처가 31%로 줄어 표·코드가 안 읽힌다.
     읽을 글자가 있는 컷은 .is-doc으로 한 줄을 다 쓴다. */
  .dshot:not(.is-phone):not(.is-wide):not(.is-doc) { width: calc(50% - .7rem); }
}
@media (max-width: 560px) {
  .dshot.is-phone img { height: 300px; }
}
.detail__links { display: flex; flex-wrap: wrap; padding-bottom: 1rem; }
.detail__links .repo-link { margin-right: .6rem; margin-bottom: .6rem; }
.repo-link--detail { margin-right: .6rem; }

/* ---------- Scroll reveal ---------- */
.reveal { opacity: 0; transform: translateY(14px); transition: opacity .5s ease, transform .5s ease; }
.reveal.is-in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
}

/* ============================================================
 * 인쇄 / PDF
 * 화면에서는 .pdetails를 항상 숨기고, 인쇄할 때만 모든 상세를 펼친다.
 * ============================================================ */
@media screen {
  .pdetails { display: none; }
}

@media print {
  /* 색은 잉크비용이 아니라 가독성 기준으로 남긴다 */
  * { -webkit-print-color-adjust: exact; print-color-adjust: exact; }

  html, body { background: #fff; font-size: 10.5pt; }

  /* 화면 전용 크롬 제거 */
  .topbar, .skip-link, .detail, .print-btn, .lang-toggle,
  .repo-link.is-locked { display: none !important; }

  /* 스크롤 등장 애니메이션이 인쇄에서 빈 화면으로 남지 않게 강제 표출 */
  .reveal, .reveal.is-in { opacity: 1 !important; transform: none !important; }

  /* 종이 여백은 @page가 잡는다. 섹션은 좌우 패딩을 버리되 폭만 넓힌다. */
  @page { margin: 14mm 13mm; }
  .section, .hero {
    padding-left: 0; padding-right: 0;
    max-width: none; margin-left: 0; margin-right: 0;
  }
  .section { padding-top: 0; padding-bottom: 1.6rem; }
  .hero { padding-top: 0; padding-bottom: 1.8rem; }
  .hero__name { font-size: 2.1rem; margin-bottom: .8rem; }
  .hero__thesis { font-size: 1.25rem; margin-bottom: .9rem; }
  .hero__cta { display: none; }        /* 종이에서 버튼은 누를 수 없다 */
  .section__title { font-size: 1.45rem; }
  .section__lead { margin-bottom: 1.4rem; }

  /* 섹션(=상단 탭) 단위로 페이지를 끊는다. 히어로만 첫 장에 남는다 */
  /* 강점은 히어로와, 상세는 앞 섹션과 한 흐름이라 붙여 둔다 */
  #metrics, #journey, #work, #projects, #method, #contact {
    break-before: page; page-break-before: always;
  }
  /* 대표작 상세는 하나씩 새 장에서 시작한다 (한 건이 두 장에 걸치지 않게) */
  .pdetails .pdetail + .pdetail { break-before: page; page-break-before: always; }
  h1, h2, h3 { break-after: avoid; page-break-after: avoid; }
  .fwork, .pcard, .jstep { break-inside: avoid; page-break-inside: avoid; }

  /* --- 펼쳐진 프로젝트 상세 --- */
  .pdetails { display: block; }
  .pdetails__h {
    font-size: 1.5rem; font-weight: 800; letter-spacing: -0.02em;
    padding-bottom: .6rem; margin-bottom: 1.4rem;
    border-bottom: 2px solid var(--ink);
  }
  .pdetails__note { font-size: 8.5pt; color: var(--ink-soft); margin: 0 0 .8rem; }
  .pdetail {
    break-inside: avoid-page;
    padding: 1.1rem 0 1.3rem;
    border-bottom: 1px solid var(--line);
  }
  .pdetail .detail__title { font-size: 1.12rem; margin-bottom: .5rem; }
  .pdetail .dsec { margin-top: .7rem; }
  .pdetail .dsec__k { font-size: .74rem; letter-spacing: .04em; }
  .pdetail .dsec__v, .pdetail .dsec__list li { font-size: .84rem; line-height: 1.6; }


  /* 스크린샷은 종이에서 과하게 커지지 않게 묶어 넣는다 */
  .pdetail .dshots {
    display: flex; flex-wrap: wrap;
    margin-top: .8rem;
  }
  .pdetail .dshot {
    width: 31%; margin-right: 2%; margin-top: 2%;
    /* 화면용 min-width(190px)가 종이 폭에서는 3장을 넘치게 만들어 캡션이 겹쳤다 */
    min-width: 0;
    break-inside: avoid; page-break-inside: avoid;
  }
  /* 세로컷은 비율이 제각각이라 높이를 묶지 않으면 캡션 줄이 어긋난다 */
  .pdetail .dshot.is-phone { width: 31%; }
  .pdetail .dshot.is-phone img { width: auto; height: 265px; margin: 0 auto; object-fit: contain; }
  /* IA·플로우처럼 가로로 긴 도표는 좁히면 글자가 안 읽힌다. 한 줄을 다 준다 */
  .pdetail .dshot.is-wide { width: 100%; margin-right: 0; }
  .pdetail .dshot img { width: 100%; height: auto; border: 1px solid var(--line); }
  .pdetail .dshot__cap { font-size: 7.5pt; padding: .25rem 0 0; border-top: 0; }
  .pdetail .dshots__more { font-size: 7.5pt; color: var(--ink-soft); margin: .2rem 0 0; }

  /* 링크는 인쇄물에서 목적지가 보여야 쓸모가 있다 */
  .pdetail .detail__links a[href^="http"]::after {
    content: " (" attr(href) ")";
    font-size: .68rem; color: var(--ink-soft); word-break: break-all;
  }

  /* 인쇄에서는 그림자·라운드가 잉크만 먹는다 */
  .fwork, .pcard, .mcard, .pdetail { box-shadow: none !important; }
}


/* ---------- 이미지 확대 ----------
   목록은 작게 훑고, 글자를 읽어야 할 때만 원본 크기로 연다. */
.dshot img { cursor: zoom-in; }
.lightbox {
  position: fixed; inset: 0; z-index: 200; display: none;
  align-items: center; justify-content: center;
  background: rgba(17,17,17,.92); padding: 3vh 3vw;
  cursor: zoom-out;
}
.lightbox.is-open { display: flex; }
.lightbox__fig { margin: 0; max-width: 100%; max-height: 94vh; display: flex; flex-direction: column; }
.lightbox__img {
  max-width: 100%; max-height: 86vh; object-fit: contain;
  border-radius: var(--r-md); background: #fff; display: block; margin: 0 auto;
}
.lightbox__cap {
  color: rgba(255,255,255,.82); font-size: .84rem; line-height: 1.6;
  text-align: center; margin-top: .9rem; max-width: 46rem; margin-left: auto; margin-right: auto;
}
.lightbox__close {
  position: absolute; top: 1.1rem; right: 1.3rem;
  width: 2.4rem; height: 2.4rem; border: 0; border-radius: 50%;
  background: rgba(255,255,255,.14); color: #fff; font-size: 1.5rem; line-height: 1;
  cursor: pointer;
}
.lightbox__close:hover { background: rgba(255,255,255,.24); }
body.lb-open { overflow: hidden; }

@media (max-width: 560px) {
  .dshot.is-phone { width: calc(50% - .7rem); }
}
@media print {
  .lightbox { display: none !important; }
}
