/* microlab 디자인 시스템 전역 스타일 — website 레포에서 이식.
   FOUC 방지를 위해 index.html <head> 에서 <link> 로 로드한다. JS 에서 import 금지. */

@import url('/fonts/pretendard/pretendard-variable.css');

@font-face {
  font-family: 'Press Start 2P';
  font-style: normal;
  font-weight: 400;
  font-display: block;
  src: url('/fonts/press-start-2p/press-start-2p-latin-400-normal.woff2') format('woff2');
  /* U+0020 만 빼고 전부. 이 한 줄이 픽셀 폰트 한글 제목의 낱말 사이가 한 글자만큼
     벌어지던 원인을 없앤다 — 한글 글리프는 Galmuri11 로 떨어지는데 공백은 목록
     첫 폰트인 여기서 그려졌고, 그 공백이 1em 이라 한글 한 글자와 폭이 거의 같았다.
     unicode-range 는 "이 폰트를 쓸 수 있는 코드포인트" 지 "이 폰트가 가진 글리프"가
     아니라서, 범위를 넓게 두어도 없는 글리프는 다음 폰트로 넘어간다. */
  unicode-range: U+0-1F, U+21-10FFFF;
}

/* 한글 픽셀 폰트 — 픽셀 컨텍스트의 한글 폴백 */
@font-face {
  font-family: 'Galmuri11';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/galmuri/Galmuri11.woff2') format('woff2');
  /* U+0020 포함 — 위 Press Start 2P 가 공백을 내려놓았으므로 여기서 받는다. */
  unicode-range: U+0020, U+1100-11FF, U+3000-303F, U+3130-318F, U+A960-A97F, U+AC00-D7A3, U+D7B0-D7FF;
}

:root {
  color-scheme: dark;

  /* surface */
  --color-bg: #0a0e17;
  --color-bg-alt: #111827;
  --color-bg-card: #1a1f2e;
  --color-border: #2a3142;

  /* <video>·썸네일의 레터박스. 영상을 다루는 이 레포에만 필요한 토큰이라 여기서 정한다
     (라이트 테마의 --color-danger 와 같은 자리).
     **두 테마 모두 검정이고 라이트에서 덮어쓰지 않는다** — 이건 표면색이 아니라 "영상
     프레임 바깥" 이고, 밝은 색을 깔면 영상의 실제 가장자리가 어디까지인지 안 보인다.
     CLAUDE.md 의 "색 하드코딩 금지" 를 지키면서 그 의도를 한 자리에 적어 두려고 만들었다
     — 예전에는 여섯 군데에 `background: #000` 이 흩어져 있었다. */
  --color-letterbox: #000;

  /* brand */
  --color-primary: #7dffb3;
  --color-primary-dim: #5ce396;
  --color-accent: #7dd3fc;

  /* text */
  --color-text: #e2e8f0;
  --color-text-dim: #94a3b8;
  --color-text-muted: #64748b;

  /* status */
  --color-danger: #f87171;

  /* type */
  --font-pixel: 'Press Start 2P', 'Galmuri11', monospace;
  --font-body: 'Pretendard Variable', Pretendard, system-ui, sans-serif;
  /* 한글 폴백(Pretendard)이 마지막에 있어야 한다 — 앞의 세 폰트는 전부 한글
     글리프가 없어서, 한국어 시스템 폰트가 없는 환경(리눅스 서버, 일부
     외국 사용자 기기)에서 mono 컨텍스트의 한글이 통째로 사라진다. 폭 0 도
     tofu 도 아니고 그냥 안 보여서, 색만 남고 글자가 없는 화면이 된다.
     자체호스팅이라 시스템에 무엇이 깔려 있든 항상 그려진다.

     generic monospace **뒤에** 둔다. 앞에 두면 ui-monospace·SFMono·Menlo 가
     하나도 없는 환경(리눅스·윈도우)에서 숫자까지 Pretendard 비례폭으로
     떨어져 자릿수 정렬이 깨진다. CSS 폰트 매칭은 글자 단위라, generic
     monospace 가 못 그리는 한글만 뒤의 Pretendard 로 넘어간다. */
  --font-mono: ui-monospace, SFMono-Regular, Menlo, monospace, 'Pretendard Variable', Pretendard;

  /* effects */
  --grid-line: color-mix(in srgb, var(--color-primary) 4%, transparent);
  --t-color: 0.2s;
  --t-transform: 0.15s ease;

  /* angled-cut */
  --ac-cut: 20px;
  --ac-border: 1px;
  --ac-border-color: var(--color-border);
  --ac-bg: var(--color-bg-card);
  --ac-diagonal-adjust: -0.7;
}

/* ── 라이트 테마 ──
   헤더 토글로 옵트인한다(html[data-theme="light"]). 다크가 기본이다.
   단순 반전이 아니라 브랜드 색을 어둡게 옮긴다 — 민트 #7dffb3 는 흰 배경에서
   대비가 안 나온다. 값은 website 레포의 라이트 팔레트와 동일하다. */
:root[data-theme='light'] {
  color-scheme: light;

  /* surface */
  --color-bg: #f6f9f7;
  --color-bg-alt: #eaf0ec;
  --color-bg-card: #ffffff;
  --color-border: #d3ddd5;

  /* brand */
  --color-primary: #087a4b;
  --color-primary-dim: #06603b;
  --color-accent: #0270a8;

  /* text */
  --color-text: #1d2733;
  --color-text-dim: #4a5a6e;
  --color-text-muted: #6d7b8c;

  /* status — website 에 없는 토큰이라 여기서 정한다.
     다크의 #f87171 은 밝은 배경에서 AA 대비를 못 맞춘다. */
  --color-danger: #b91c1c;

  /* effects */
  --grid-line: color-mix(in srgb, var(--color-primary) 6%, transparent);
}

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

html {
  word-spacing: 0.02em;
  letter-spacing: 0.02em;
  /* 스크롤바 자리를 항상 비워둔다. 내용이 길어져 스크롤바가 생기는 순간
     뷰포트가 좁아지면서 화면 전체가 좌우로 밀리는 레이아웃 시프트(CLS)가
     발생하는데, 이걸로 막는다. website 레포와 동일한 처리. */
  scrollbar-gutter: stable;
}

body {
  font-family: var(--font-body);
  background-color: var(--color-bg);
  /* signature: 아주 옅은 민트 그래프 배경 */
  background-image:
    linear-gradient(to right, var(--grid-line) 1px, transparent 1px),
    linear-gradient(to bottom, var(--grid-line) 1px, transparent 1px);
  background-size: 32px 32px;
  color: var(--color-text);
  line-height: 1.6;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
}

/* scrollbar-gutter 미지원 브라우저(구형 Safari) 폴백.
   overflow-y: scroll 은 스크롤바 자리를 항상 차지하게 만든다. 단점처럼 보이지만
   이 블록이 켜지는 환경과 단점이 나타나는 환경이 겹치지 않는다 — 클래식 스크롤바를
   쓰는 Chrome·Firefox·Edge 는 scrollbar-gutter 를 지원하므로 여기 들어오지 않고,
   여기 들어오는 구형 Safari 는 macOS·iOS 기본이 오버레이 스크롤바라 자리를 안 먹는다.
   즉 CLS 가 실제로 일어나는 환경(스크롤바 항상 표시 설정)에서만 효과가 있다. */
@supports not (scrollbar-gutter: stable) {
  html {
    overflow-y: scroll;
  }
}

::selection { background: var(--color-primary); color: var(--color-bg); }

a { color: var(--color-primary); text-decoration: none; transition: color var(--t-color); }
a:hover { color: var(--color-accent); }
img { max-width: 100%; height: auto; }

footer { padding: 2.5rem 0; margin-top: auto; }

/* ── label: 픽셀 대문자 캡션 ── */
.label {
  font-family: var(--font-pixel);
  font-size: 0.65rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--color-text-dim);
  display: inline-block;
}

/* ── angled-cut 시스템 (website 이식) ──
   .angled-cut / -sm / -xs / -lg 를 요소에 추가. --ac-bg 로 채움색,
   --ac-border-color 로 테두리색 조정. .angled-cut-interactive 는 hover 강조. */
.angled-cut,
.angled-cut-sm,
.angled-cut-xs,
.angled-cut-lg,
.angled-cut-interactive {
  --ac-cut: 20px;
  --ac-border: 1px;
  --ac-border-color: var(--color-border);
  --ac-bg: var(--color-bg-card);
  position: relative;
  background: transparent !important;
  border: none !important;
  border-radius: 0 !important;
  isolation: isolate;
}

.angled-cut-sm { --ac-cut: 10px; }
.angled-cut-xs { --ac-cut: 5px; }
.angled-cut-lg { --ac-cut: 32px; }

.angled-cut::before, .angled-cut::after,
.angled-cut-sm::before, .angled-cut-sm::after,
.angled-cut-xs::before, .angled-cut-xs::after,
.angled-cut-lg::before, .angled-cut-lg::after,
.angled-cut-interactive::before, .angled-cut-interactive::after {
  content: '';
  position: absolute;
  pointer-events: none;
  transition: background 0.25s ease, inset 0.25s ease;
}

.angled-cut::before,
.angled-cut-sm::before,
.angled-cut-xs::before,
.angled-cut-lg::before,
.angled-cut-interactive::before {
  inset: 0;
  background: var(--ac-border-color);
  clip-path: polygon(
    0 0,
    calc(100% - var(--ac-cut)) 0,
    100% var(--ac-cut),
    100% 100%,
    var(--ac-cut) 100%,
    0 calc(100% - var(--ac-cut))
  );
  z-index: -2;
}

.angled-cut::after,
.angled-cut-sm::after,
.angled-cut-xs::after,
.angled-cut-lg::after,
.angled-cut-interactive::after {
  top: var(--ac-border);
  left: var(--ac-border);
  right: var(--ac-border);
  bottom: var(--ac-border);
  background: var(--ac-bg);
  clip-path: polygon(
    0 0,
    calc(100% - var(--ac-cut) - var(--ac-border) * var(--ac-diagonal-adjust)) 0,
    100% calc(var(--ac-cut) + var(--ac-border) * var(--ac-diagonal-adjust)),
    100% 100%,
    calc(var(--ac-cut) + var(--ac-border) * var(--ac-diagonal-adjust)) 100%,
    0 calc(100% - var(--ac-cut) - var(--ac-border) * var(--ac-diagonal-adjust))
  );
  z-index: -1;
}

.angled-cut-interactive {
  cursor: pointer;
  transition: transform 0.15s ease;
}
.angled-cut-interactive:hover {
  --ac-border: 2px;
  --ac-border-color: var(--color-primary);
}
.angled-cut-interactive:active { transform: translateY(1px); }

/* ── buttons ── */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.7rem 1.4rem;
  font-family: var(--font-body);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.5px;
  color: var(--color-text-dim);
  cursor: pointer;
  transition: transform var(--t-transform), color var(--t-color);
}
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: 0.5; cursor: not-allowed; }

.btn-primary {
  --ac-bg: var(--color-primary);
  --ac-border-color: var(--color-primary);
  color: var(--color-bg);
}
.btn-primary:hover {
  --ac-bg: var(--color-primary-dim);
  --ac-border-color: var(--color-primary-dim);
}

.btn-ghost:hover {
  --ac-border-color: var(--color-primary);
  color: var(--color-primary);
}

/* ── tools 레이아웃 ── */
.wrap {
  width: 100%;
  max-width: 56rem;
  margin: 0 auto;
  padding: 0 1.25rem;
}

/* 스크린리더 전용 텍스트. 화면에서는 안 보이지만 접근성 이름에는 들어간다.
   display:none 이나 visibility:hidden 은 접근성 트리에서도 빠지므로 쓸 수 없다. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.site-header {
  /* 도구 패널(position:absolute)의 기준 박스. 패널이 <details> 안에 있어도
     <details> 자체는 static 이라 여기에 붙는다 → 패널 폭이 헤더 폭과 같아진다. */
  position: relative;
  border-bottom: 1px solid var(--color-border);
  padding: 1rem 0;
}
/* 자식 결합자여야 한다 — 패널 안쪽에서도 .wrap 을 쓰므로 후손 선택자면 패널까지 flex 가 된다. */
.site-header > .wrap {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
}
.site-header .home {
  font-family: var(--font-pixel);
  /* 사이트 이름이 한글이라 Press Start 2P 에 글리프가 없고 Galmuri11 로 떨어진다.
     예전 값(0.7rem / letter-spacing 0.18em / uppercase)은 라틴 로고 'microlab image'
     에 맞춘 것이었다: uppercase 는 한글에 아무 일도 하지 않고, 0.18em 자간은 한글
     8자를 낱글자처럼 흩어놓는다. 0.75rem 은 12px 정수라 Galmuri11(11px 설계)이
     덜 뭉개지고, 자간은 픽셀 폰트의 답답함만 풀 만큼만 남긴다. */
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  line-height: 1.4;
  white-space: nowrap;
}

/* ── 도구 전체 패널 ── */
.site-nav {
  /* 트리거와 테마 토글을 오른쪽에 붙여 둔다. margin-left:auto 가 둘 다에 있으면
     남는 공간이 나뉘어 사이가 벌어지므로 여기에만 둔다. */
  margin-left: auto;
}

.site-nav-trigger {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  height: 34px;
  padding: 0 0.65rem;
  border: 1px solid var(--color-border);
  color: var(--color-text-dim);
  font-size: 0.78rem;
  cursor: pointer;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  transition: color var(--t-color), border-color var(--t-color);
  /* 기본 삼각형 마커 제거 — 아이콘을 직접 그린다. */
  list-style: none;
}
.site-nav-trigger::-webkit-details-marker { display: none; }
.site-nav-trigger::marker { content: ''; }
.site-nav-trigger:hover,
.site-nav-trigger:focus-visible,
.site-nav[open] > .site-nav-trigger {
  color: var(--color-primary);
  border-color: var(--color-primary);
}
.site-nav-trigger svg { flex: none; }
.site-nav .icon-close { display: none; }
.site-nav[open] .icon-menu { display: none; }
.site-nav[open] .icon-close { display: block; }

.site-nav-panel {
  position: absolute;
  top: calc(100% + 1px); /* 헤더 아래 테두리 바로 밑 */
  left: 0;
  right: 0;
  /* 본문 위에 뜬다. .site-header 는 z-index 가 auto 라 쌓임 맥락을 만들지 않으므로
     이 값은 루트에서 비교되고, 위치 지정되지 않은 <main> 보다 항상 위에 그려진다. */
  z-index: 50;
}
.site-nav-sheet {
  --ac-bg: var(--color-bg-alt);
  display: block;
  padding: 1.25rem;
}
/* 스크롤은 반드시 안쪽 요소가 맡는다. angled-cut 은 ::before/::after 를 inset:0 으로
   깔기 때문에, 스크롤 컨테이너가 되면 그 배경이 내용과 함께 밀려 올라간다. */
.site-nav-scroll {
  /* 시트 아래끝이 항상 뷰포트 안에 들어오도록 뷰포트에 묶고, 아주 큰 화면에서는
     한 덩어리가 지나치게 길어지지 않게 상한을 둔다. */
  /* 헤더 아래 남은 공간 전부. 헤더 높이는 사이트 이름 길이와 화면 폭에 따라 한 줄이
     되기도 두 줄이 되기도 해서(360px 에서 67px → 113px) 상수로 못 맞춘다 —
     SiteHeader 의 스크립트가 재서 --site-header-h 로 넘긴다. 3rem 은 시트
     패딩(1.25rem x 2)과 아래 여백이다. JS 가 없으면 7rem 으로 떨어지는데,
     그건 한 줄 헤더에서 맞는 값이다. */
  max-height: min(calc(100svh - var(--site-header-h, 7rem) - 3rem), 44rem);
  overflow-y: auto;
  overscroll-behavior: contain;
  /* 더 있다는 걸 알려야 한다 — 오버레이 스크롤바만 있는 환경에서는 잘린 것처럼 보인다. */
  scrollbar-width: thin;
  scrollbar-color: var(--color-border) transparent;
}

.nav-group + .nav-group {
  margin-top: 1.4rem;
  padding-top: 1.1rem;
  border-top: 1px solid var(--color-border);
}
.nav-group-head {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}
.nav-group-name {
  font-family: var(--font-pixel);
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  line-height: 1.5;
  color: var(--color-primary);
}
.nav-group-badge {
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  padding: 0.15rem 0.4rem;
  background: var(--color-primary);
  color: var(--color-bg);
}
.nav-group-host {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: var(--color-text-muted);
}
.nav-group-host:hover,
.nav-group-host:focus-visible { color: var(--color-primary); }
.nav-group-blurb {
  font-size: 0.78rem;
  color: var(--color-text-muted);
  margin-top: 0.2rem;
}

.nav-group-list {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(12.5rem, 1fr));
  gap: 0 0.5rem;
  margin-top: 0.5rem;
}
.nav-group-list > li { min-width: 0; }
.nav-group-list a {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  min-height: 2.75rem; /* 손가락 목표 44px */
  padding: 0.35rem 0.5rem;
  color: var(--color-text-dim);
  font-size: 0.85rem;
  line-height: 1.35;
}
.nav-group-list a:hover,
.nav-group-list a:focus-visible {
  color: var(--color-primary);
  background: var(--color-bg-card);
}
.nav-group-list a[aria-current='page'] {
  color: var(--color-primary);
  font-weight: 600;
}
.nav-item-title { min-width: 0; }

/* 데스크톱에서는 줄 간격을 조인다. 44px 은 손가락 목표라 포인터가 정밀한 환경에는
   필요 없고, 그대로 두면 도구가 39개인 지금 세 번째 그룹이 제목만 남는다(실제로
   비디오 그룹의 도구가 한 개도 안 보였다). 열도 하나 더 들어가게 최소폭을 줄인다.
   모바일은 손대지 않는다 — 한 줄 배치라 스크롤이 자연스럽고, 목표 크기가 중요하다. */
@media (min-width: 40rem) and (pointer: fine) {
  .nav-group-list { grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr)); }
  .nav-group-list a {
    min-height: 2.1rem;
    padding: 0.25rem 0.5rem;
  }
}

/* 내용이 넘칠 때만 아래쪽에 페이드를 깔아 "더 있다"를 보이게 한다. 오버레이
   스크롤바만 있는 환경에서는 스크롤바가 안 보여서 잘린 게 아니라 끝난 것처럼
   읽힌다 — 실제로 그렇게 보였다. 넘치는지 여부는 SiteHeader 의 스크립트가
   재서 data-scrollable 로 알려준다(CSS 만으로는 알 수 없다). */
.site-nav-scroll[data-scrollable='true'] {
  mask-image: linear-gradient(to bottom, #000 calc(100% - 2.5rem), transparent 100%);
}
.nav-item-ext {
  /* 제목 바로 뒤에 붙인다. 오른쪽 끝으로 밀면(margin-left:auto) 넓은 칸에서
     화살표가 제목과 멀어져 무엇에 붙은 표시인지 읽히지 않는다. */
  flex: none;
  font-size: 0.7rem;
  color: var(--color-text-muted);
}
.nav-group-list a:hover .nav-item-ext,
.nav-group-list a:focus-visible .nav-item-ext { color: var(--color-primary); }

/* ── 테마 토글 ── */
.theme-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  flex: none;
  background: none;
  border: 1px solid var(--color-border);
  color: var(--color-text-dim);
  cursor: pointer;
  transition: color var(--t-color), border-color var(--t-color);
  -webkit-tap-highlight-color: transparent;
}
.theme-toggle:hover,
.theme-toggle:focus-visible {
  color: var(--color-primary);
  border-color: var(--color-primary);
}
/* 다크에서는 해(누르면 라이트), 라이트에서는 달(누르면 다크) */
.theme-toggle .icon-moon { display: none; }
:root[data-theme='light'] .theme-toggle .icon-sun { display: none; }
:root[data-theme='light'] .theme-toggle .icon-moon { display: block; }

.tool-main { flex: 1; padding: 2.5rem 0 4rem; }

.tool-title {
  font-family: var(--font-pixel);
  font-size: clamp(1rem, 3.4vw, 1.55rem);
  font-weight: 400;
  line-height: 1.5;
  color: var(--color-primary);
  margin-bottom: 1.25rem;
}

/* 브라우저 내 처리 고지 — microlab 도구의 상시 노출 요소 */
.privacy-notice {
  --ac-bg: var(--color-bg-alt);
  --ac-border-color: var(--color-border);
  padding: 0.7rem 1rem;
  font-size: 0.82rem;
  color: var(--color-text-dim);
  margin-bottom: 1.75rem;
}
.privacy-notice strong { color: var(--color-primary); font-weight: 600; }

/* 도구 아일랜드 영역과 본문 영역을 분리해 둔다. 나중에 광고 슬롯이 들어오면
   본문 영역 위/아래에만 붙이고 도구 영역은 건드리지 않는다. */
.tool-stage { margin-bottom: 3rem; }
.tool-doc { margin-bottom: 3rem; }

.tool-doc h2 {
  font-family: var(--font-pixel);
  font-size: 0.8rem;
  letter-spacing: 0.12em;
  color: var(--color-text-dim);
  text-transform: uppercase;
  margin: 2rem 0 0.9rem;
  font-weight: 400;
}
.tool-doc ol, .tool-doc ul { padding-left: 1.2rem; color: var(--color-text-dim); }
.tool-doc li { margin-bottom: 0.4rem; }
.tool-doc details {
  border-top: 1px solid var(--color-border);
  padding: 0.75rem 0;
}
.tool-doc summary { cursor: pointer; color: var(--color-text); }
.tool-doc details p { color: var(--color-text-dim); padding-top: 0.5rem; }

.tool-related { border-top: 1px solid var(--color-border); padding-top: 1.5rem; }
.tool-related h2 {
  font-family: var(--font-pixel);
  font-size: 0.7rem;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--color-text-dim);
  font-weight: 400;
  margin-bottom: 0.9rem;
}

/* 허브 */
.hub-intro { padding: 3rem 0 2rem; }
.hub-intro h1 {
  font-family: var(--font-pixel);
  font-size: clamp(1.1rem, 4vw, 1.8rem);
  font-weight: 400;
  line-height: 1.4;
  color: var(--color-primary);
  margin-bottom: 0.9rem;
}
.hub-intro p { color: var(--color-text-dim); max-width: 34rem; }

.tool-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: 1rem;
  padding-bottom: 4rem;
}
.tool-card { display: block; padding: 1.25rem; color: inherit; }
.tool-card h2 {
  font-size: 1rem;
  color: var(--color-primary);
  margin-bottom: 0.45rem;
  font-weight: 600;
}
.tool-card p { font-size: 0.85rem; color: var(--color-text-dim); }

.site-footer { padding: 2.5rem 0; margin-top: auto; text-align: center; }
