/* Reaction Benchmark — base + 공용 부품. 색은 전부 토큰에서만.
   방향: 계측 장비. 숫자는 고정폭·tabular, 라벨은 작은 대문자, 면은 얇은 격자 위에 앉는다. */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-text);
  font: var(--text-md)/1.65 var(--font-sans);
  /* 계기판 격자 — 아주 옅게, 배경에만 */
  background-image:
    linear-gradient(var(--color-grid) 1px, transparent 1px),
    linear-gradient(90deg, var(--color-grid) 1px, transparent 1px);
  background-size: 64px 64px, 64px 64px;
  background-position: -1px -1px;
}
img, canvas, svg { max-width: 100%; }
/* 모바일 탭 하이라이트 제거 — 탭마다 웹킷 기본 반투명 사각형이 번쩍인다(사장님 제보 2026-08-03).
   피드백은 우리 연출(팝·링·:active)이 담당. :hover 규칙은 전부 (hover: hover) 가드 — 터치에서
   탭 순간 hover 스타일이 번쩍 얹혔다 눌러붙는 것(sticky hover)도 같은 제보의 원인이었다. */
html { -webkit-tap-highlight-color: transparent; }
a { color: var(--color-link); text-decoration: none; }
/* 본문 속 링크는 색만으로 구분되면 안 된다(WCAG 1.4.1) — 밑줄을 기본으로 둔다. */
p a, li a, article a { text-decoration: underline; text-underline-offset: 3px; }
/* 행 전체가 링크인 곳은 밑줄을 끈다(텍스트 속 링크가 아니라 목록 항목이다) */
.test-list a, .records-grid a, .nav-links a, .brand { text-decoration: none; }
@media (hover: hover) { a:hover { text-decoration: underline; } }
:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }

/* 디테일 — 드래그 선택은 브랜드 앰버, 스크롤바는 배경 톤에 맞춘다(밝은 기본 스크롤바가 다크 판에서 튐) */
::selection { background: var(--color-primary); color: var(--color-on-primary); }
html { scrollbar-color: var(--color-outline) var(--color-bg); }

h1 { font-size: var(--text-xl); line-height: 1.2; margin: 0 0 var(--space-2); letter-spacing: -.01em; }
h2 { font-size: var(--text-lg); margin: var(--space-5) 0 var(--space-2); letter-spacing: -.01em; }
h3 { font-size: var(--text-md); margin: var(--space-4) 0 var(--space-2); }
p { margin: 0 0 var(--space-3); }
.muted { color: var(--color-text-muted); font-size: var(--text-sm); }
/* 데스크톱에서 내용이 화면 절반에 웅크리지 않게 판을 넓힌다(2026-08-02 개편).
   본문 산문은 아래 article 폭 제한이 따로 지킨다 — 판이 넓다고 줄이 길어지면 안 된다. */
.wrap { max-width: 960px; margin: 0 auto; padding: 0 var(--space-3); }
article > *, main.wrap > p { max-width: 76ch; }

/* 작은 대문자 라벨 — 계측기 눈금판의 글씨 */
.eyebrow {
  font: 600 var(--text-xs)/1 var(--font-mono);
  letter-spacing: .16em; text-transform: uppercase;
  color: var(--color-text-muted); margin: 0 0 var(--space-2);
}

/* nav */
.site-head { border-bottom: 1px solid var(--color-outline); background: var(--color-bg); }
.nav { max-width: 960px; margin: 0 auto; padding: var(--space-3);
  display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-3); align-items: center; }
.brand { font: 700 var(--text-md)/1 var(--font-mono); color: var(--color-text); letter-spacing: -.02em;
  display: inline-flex; align-items: center; gap: var(--space-2); }
.brand-mark { width: 22px; height: 22px; }
.brand b { font-weight: 400; color: var(--color-text-muted); }
.nav-links { display: flex; flex-wrap: wrap; gap: var(--space-1); margin-left: auto; }
.nav-links a { color: var(--color-text-muted); font: 500 var(--text-sm)/1 var(--font-mono);
  padding: var(--space-2); border-radius: var(--radius-sm); min-height: 44px;
  display: inline-flex; align-items: center; }
@media (hover: hover) { .nav-links a:hover { color: var(--color-text); background: var(--color-surface-raised); text-decoration: none; } }
.nav-run { color: var(--color-text) !important; font-weight: 700; }
/* ─── 모바일 네비(≤720px) — PC 상단 바를 구겨 넣지 않는다(사장님 2026-08-03 "각 버전에 최적화").
   1줄: 브랜드 + 언어 토글 · 2줄: 가로 스와이프 칩 바(알약 테두리 = 눌린다는 신호,
   끝에 반쯤 걸린 칩 = 더 있다는 신호). JS 0 — 앱들의 상단 카테고리 칩 관습. */
@media (max-width: 720px) {
  .nav { padding: var(--space-2) var(--space-3); row-gap: var(--space-2); }
  .nav-links { flex-wrap: nowrap; overflow-x: auto; margin-left: 0; flex: 1 1 100%;
    order: 3; gap: var(--space-2); scrollbar-width: none; }
  .nav-links::-webkit-scrollbar { display: none; }
  .nav-links a { white-space: nowrap; border: 1px solid var(--color-outline); border-radius: 999px;
    padding: 0 var(--space-3); min-height: 38px; font-size: var(--text-sm); }
  .nav-run { border-color: var(--color-primary) !important; }
  .lang-toggle { margin-left: auto; }
}
/* 언어 토글 — 다른 항목과 같은 줄 높이의 알약. 예전엔 큰 상자라 줄에서 삐죽 튀어나왔다. */
.lang-toggle { border: 1px solid var(--color-outline); border-radius: 999px;
  color: var(--color-text-muted) !important; margin-left: var(--space-2);
  padding: 0 var(--space-3) !important; min-height: 32px !important; align-self: center; }
@media (hover: hover) { .lang-toggle:hover { border-color: var(--color-primary); color: var(--color-text) !important; background: none !important; } }

main.wrap { padding-top: var(--space-5); padding-bottom: var(--space-6); }

/* footer — 브랜드 + 링크 그룹 + SNS 공유(뷰티듀프 구조를 우리 토큰으로 재구현) */
.site-foot { border-top: 1px solid var(--color-outline); padding-top: var(--space-5);
  padding-bottom: var(--space-6); margin-top: var(--space-6); font-size: var(--text-sm);
  color: var(--color-text-muted); }
.foot-brand { display: inline-flex; align-items: center; gap: var(--space-2);
  font: 700 var(--text-md)/1 var(--font-mono); color: var(--color-text); letter-spacing: -.02em; }
.foot-brand b { font-weight: 400; color: var(--color-text-muted); }
.foot-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: var(--space-4) var(--space-5); margin-top: var(--space-4); }
.foot-col h3 { font: 600 var(--text-xs)/1 var(--font-mono); letter-spacing: .14em;
  text-transform: uppercase; color: var(--color-text-muted); margin: 0 0 var(--space-3); }
.foot-col ul { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-2); }
.foot-col a { color: var(--color-text-muted); text-decoration: none; transition: color .15s ease; }
@media (hover: hover) { .foot-col a:hover { color: var(--color-text); text-decoration: none; } }
/* SNS 원형 버튼 — 플랫폼 로고는 그쪽 브랜드색이 식별 신호라 예외적으로 색을 쓴다 */
.share-circles { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.sc { width: 38px; height: 38px; border-radius: 50%; border: 1px solid var(--color-outline);
  display: inline-flex; align-items: center; justify-content: center; cursor: pointer; padding: 0;
  transition: transform .15s ease; }
@media (hover: hover) { .sc:hover { transform: scale(1.1); } }
.sc:active { transform: scale(.95); }
.sc svg { width: 17px; height: 17px; display: block; }
.sc-x { background: var(--brand-x); color: var(--brand-on); }
.sc-fb { background: var(--brand-facebook); color: var(--brand-on); }
.sc-th { background: var(--brand-x); color: var(--brand-on); }
.sc-nv { background: var(--brand-naver); color: var(--brand-on); }
.sc-copy { background: var(--color-surface-raised); color: var(--color-text); }
.share-msg { display: block; margin-top: var(--space-2); font: 600 var(--text-xs)/1.4 var(--font-mono);
  color: var(--color-signal-text); min-height: 1.2em; }
.foot-copy { margin-top: var(--space-5); padding-top: var(--space-3);
  border-top: 1px solid var(--color-outline); }
/* 운영자 트래픽 제외 상태 표시(head.html의 notrack 스위치) */
.notrack-note { font: 600 var(--text-xs)/1.5 var(--font-mono); color: var(--color-signal-text); }

/* 버튼 4종 — 높이·곡률·크기는 여기서만 정한다 */
/* ★ hidden 속성이 항상 이긴다.
   브라우저 기본 [hidden]{display:none}은 특이도가 0이라, .btn-secondary처럼 display를 정하는
   클래스가 있으면 그쪽이 이긴다. 그래서 startBtn.hidden = true가 화면에 아무 효과가 없었고
   일곱 게임 전부에서 Start 버튼이 플레이 중에도 남아 있었다(2026-08-02, 사장님 신고).
   JS가 hidden을 켜면 반드시 사라져야 한다 — 여기서 못 박는다. */
[hidden] { display: none !important; }

.btn, .btn-secondary, .btn-quiet, .btn-danger {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  min-height: 44px; padding: 0 var(--space-4); border-radius: var(--radius-md);
  font: 600 var(--text-sm)/1 var(--font-mono); letter-spacing: .02em;
  cursor: pointer; border: 1px solid transparent; }
.btn { background: var(--color-primary); color: var(--color-on-primary); }
@media (hover: hover) { .btn:hover { filter: brightness(1.08); } }
.btn-secondary { background: none; border-color: var(--color-outline); color: var(--color-text); }
@media (hover: hover) { .btn-secondary:hover { border-color: var(--color-primary); } }
.btn-quiet { background: none; color: var(--color-text-muted); }
@media (hover: hover) { .btn-quiet:hover { color: var(--color-text); } }
.btn-danger { background: none; border-color: var(--color-danger); color: var(--color-danger); }

/* 디테일 — 상호작용 요소는 상태 변화가 뚝 끊기지 않게(색·테두리만, 레이아웃 속성 금지) */
.test-list a, .record, .daily-card, .btn, .btn-secondary, .btn-quiet, .mode-btn, .tile, .lang-toggle {
  transition: background-color .15s ease, border-color .15s ease, color .15s ease; }

/* 본문 표 — 비교표(순서↔시각 등)에 쓴다. 넘치면 표만 가로 스크롤. */
article table { border-collapse: collapse; width: 100%; margin: var(--space-3) 0;
  font-size: var(--text-sm); display: block; overflow-x: auto; }
article th, article td { border: 1px solid var(--color-outline); padding: var(--space-2) var(--space-3);
  text-align: left; vertical-align: top; }
article th { background: var(--color-surface); font-weight: 600; white-space: nowrap; }

/* 로딩(인라인) — currentColor라 어느 버튼에도 얹힌다 */
.spinner { width: 1em; height: 1em; border-radius: 50%;
  border: 2px solid currentColor; border-top-color: transparent;
  animation: spin .8s linear infinite; display: inline-block; }
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .spinner { animation: none; }
  *, *::before, *::after { transition: none !important; animation: none !important; }
}

/* 오류 표시 — 색만으로 전달 금지: 아이콘+테두리 동반 */
.error-note { border: 1px solid var(--color-danger); border-radius: var(--radius-md);
  padding: var(--space-2) var(--space-3); font-size: var(--text-sm); }
.error-note::before { content: "⚠ "; }

/* 카드 */
.card { background: var(--color-surface); border: 1px solid var(--color-outline);
  border-radius: var(--radius-lg); padding: var(--space-4); }

/* 홈 히어로 — 이 사이트의 주장을 먼저 말한다.
   넓은 화면에선 주장(왼쪽) + 명판(오른쪽) 2단: 계측기의 스펙 플레이트처럼.
   예전엔 좁은 기둥 하나라 1440px에서 오른쪽 절반이 죽은 공간이었다(2026-08-02 개편). */
.hero { border-bottom: 1px solid var(--color-outline); padding-bottom: var(--space-5); }
.hero .eyebrow { color: var(--color-signal-text); }
.hero h1 { font-size: var(--text-hero); max-width: 16ch; letter-spacing: -.02em; }
.hero-claim { font-size: var(--text-md); color: var(--color-text-muted); max-width: 52ch; }
.hero-cta { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-4);
  margin-top: var(--space-4); }
/* 설명은 히어로가 아니라 링크 뒤에 산다 — 후킹(버튼)과 방법(조용한 링크)의 자리 구분 */
.hero-how { font: 500 var(--text-xs)/1.4 var(--font-mono); letter-spacing: .04em;
  color: var(--color-text-muted); text-decoration-color: var(--color-outline); }
@media (hover: hover) { .hero-how:hover { color: var(--color-text); } }
.hero-strip { display: flex; flex-wrap: wrap; gap: var(--space-3) var(--space-5);
  margin-top: var(--space-4); font: 500 var(--text-xs)/1.4 var(--font-mono);
  letter-spacing: .08em; text-transform: uppercase; color: var(--color-text-muted); }
.hero-strip b { display: block; font-size: var(--text-lg); letter-spacing: -.02em;
  text-transform: none; color: var(--color-text); font-variant-numeric: tabular-nums; }
@media (min-width: 860px) {
  .hero { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: var(--space-6); align-items: center; }
  .hero > * { grid-column: 1; }
  .hero > .hero-strip { grid-column: 2; grid-row: 1 / span 4; align-self: center;
    flex-direction: column; gap: var(--space-4); margin: 0;
    border-left: 1px solid var(--color-outline); padding-left: var(--space-5); }
  .hero-strip b { font-size: var(--text-xl); }
}

/* 테스트 목록 — 카드 격자가 아니라 계기 목록(순서가 아니라 종류다) */
.test-list { list-style: none; padding: 0; margin: var(--space-4) 0 0;
  border-top: 1px solid var(--color-outline); }
.test-list li { border-bottom: 1px solid var(--color-outline); }
.test-list a { display: grid; grid-template-columns: auto 1fr auto; align-items: center;
  gap: var(--space-3); padding: var(--space-3) var(--space-2); color: var(--color-text); }
@media (hover: hover) { .test-list a:hover { background: var(--color-surface); text-decoration: none; } }
/* 아이콘은 계기 눈금판 타일 — 크기·테두리를 통일해 글리프가 '디자인된 아이콘'으로 읽히게 한다 */
.test-list .t-icon { display: inline-flex; align-items: center; justify-content: center;
  width: 42px; height: 42px; border: 1px solid var(--color-outline); border-radius: var(--radius-md);
  background: var(--color-surface); color: var(--color-signal-text);
  font: 400 var(--text-lg)/1 var(--font-mono); }
.test-list .t-name { font-weight: 600; }
.test-list .t-desc { display: block; color: var(--color-text-muted); font-size: var(--text-sm); font-weight: 400; }
.test-list .t-meta { font: 500 var(--text-xs)/1.6 var(--font-mono); letter-spacing: .06em;
  text-transform: uppercase; color: var(--color-text-muted); text-align: right; white-space: nowrap; }
.test-list .t-meta b { display: block; color: var(--color-data); font-weight: 600; }
@media (max-width: 520px) {
  .test-list a { grid-template-columns: auto 1fr; }
  .test-list .t-meta { grid-column: 2; text-align: left; }
}

/* 버튼 + 설명 한 줄 — 단어 간격에 기대지 않는다(버튼과 글이 붙어 보이던 원인). */
.run-cta { display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--space-3) var(--space-4); margin: var(--space-4) 0 0; }
.run-cta .muted { max-width: 44ch; }

/* 오늘의 도전 — 하루 한 번의 사건. 앰버 스트라이프가 목록 위에서 오늘을 가리킨다. */
.daily-card { display: grid; grid-template-columns: auto 1fr auto;
  gap: var(--space-3) var(--space-4);
  align-items: center; margin: var(--space-5) 0 calc(-1 * var(--space-2));
  padding: var(--space-4); border: 1px solid var(--color-outline);
  border-left: 3px solid var(--color-primary); border-radius: var(--radius-lg);
  background: var(--color-surface); color: var(--color-text); text-decoration: none !important; }
@media (hover: hover) { .daily-card:hover { border-color: var(--color-primary); } }
.daily-card .eyebrow { margin: 0; color: var(--color-signal-text); }
.daily-main b { display: block; font-size: var(--text-lg); }
.daily-sub { display: block; color: var(--color-text-muted); font-size: var(--text-sm); }
.daily-count { font: 600 var(--text-xs)/1.4 var(--font-mono); letter-spacing: .06em;
  text-transform: uppercase; color: var(--color-text-muted); font-variant-numeric: tabular-nums; }
@media (max-width: 520px) {
  .daily-card { grid-template-columns: auto 1fr; }
  .daily-cta { grid-column: 2; }
}
/* 스테이지의 회차 스탬프(데일리 모드) */
.daily-badge { position: absolute; top: var(--space-2); left: var(--space-2); z-index: 1;
  font: 700 var(--text-xs)/1 var(--font-mono); letter-spacing: .12em; text-transform: uppercase;
  color: var(--color-signal-text); padding: var(--space-1) var(--space-2);
  border: 1px solid var(--color-outline); border-radius: var(--radius-sm); background: var(--color-bg); }
/* 종합 측정 유형 총평 — 일곱 개를 다 돌았을 때의 한 장 판정 */
.run-type { border: 1px solid var(--color-outline); border-left: 3px solid var(--color-primary);
  border-radius: var(--radius-lg); padding: var(--space-4); margin: var(--space-4) 0; }
.run-type .eyebrow { margin-bottom: var(--space-1); }
.run-type-title { font: 800 var(--text-xl)/1.3 var(--font-sans); margin: 0 0 var(--space-2); }
.run-type .muted { margin: 0; max-width: 60ch; }

/* 결과 패널의 데일리 블록 */
.daily-result { border: 1px solid var(--color-outline); border-left: 3px solid var(--color-primary);
  border-radius: var(--radius-md); padding: var(--space-2) var(--space-3);
  font-size: var(--text-sm); color: var(--color-text-muted); }

/* 업적 토스트(결과 화면) + 홈 마일스톤 배지 줄 */
.ach-toast { border: 1px solid var(--color-outline); border-left: 3px solid var(--color-success);
  border-radius: var(--radius-md); padding: var(--space-2) var(--space-3);
  font: 600 var(--text-sm)/1.5 var(--font-sans); color: var(--color-text);
  animation: tile-pop 200ms cubic-bezier(.34, 1.56, .64, 1); }
.ach-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2);
  margin-top: var(--space-3); }
.ach-label { font: 600 var(--text-xs)/1 var(--font-mono); letter-spacing: .12em;
  text-transform: uppercase; color: var(--color-text-muted); margin-right: var(--space-1); }
.ach-chip { display: inline-flex; align-items: center; gap: var(--space-1);
  border: 1px solid var(--color-outline); border-radius: 999px;
  padding: var(--space-1) var(--space-3); font-size: var(--text-xs);
  color: var(--color-text-muted); opacity: .45; }
.ach-chip.is-won { opacity: 1; color: var(--color-text); border-color: var(--color-primary); }
.ach-chip.is-won .ach-glyph { color: var(--color-signal-text); }
.daily-result b { color: var(--color-signal-text); font-family: var(--font-mono); }
/* 데일리 결과 글리프 줄 — 공유되는 모양 그대로 보여준다 */
.daily-grid { display: inline-block; margin-top: var(--space-1);
  font: 600 var(--text-md)/1.4 var(--font-mono); letter-spacing: .1em; color: var(--color-text); }

/* 테스트 스테이지 — 계측 패널 */
.test-stage { position: relative; background: var(--color-surface);
  border: 1px solid var(--color-outline); border-radius: var(--radius-lg);
  min-height: 360px; display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: var(--space-3); text-align: center;
  touch-action: manipulation; user-select: none; -webkit-user-select: none;
  cursor: pointer; padding: var(--space-4); overflow: hidden; }
/* 스테이지 색에는 전환을 걸지 않는다.
   반응속도 자극이 120ms에 걸쳐 서서히 나타나면 "언제 초록이 됐는가"가 흐려지고
   그 시간이 측정값에 얹힌다 — 측정 도구에서 눈요기보다 즉시성이 먼저다(2026-08-02). */
.test-stage .stage-msg { font: 700 var(--text-xl)/1.2 var(--font-sans); margin: 0; max-width: 100%; overflow-wrap: anywhere; }
/* 외워야 할 숫자 — 고정폭으로, 화면 폭에 맞춰 줄어든다.
   고정 크기로 두면 16자리부터 좁은 화면에서 잘려 나갔다(2026-08-02 실측). */
.test-stage .stage-msg.is-digits {
  font: 800 clamp(1.4rem, 7vw, 2.2rem)/1.2 var(--font-mono);
  font-variant-numeric: tabular-nums; letter-spacing: .06em; }
.test-stage .stage-sub { color: var(--color-text-muted); font: 500 var(--text-xs)/1 var(--font-mono);
  letter-spacing: .12em; text-transform: uppercase; margin: 0; }
/* 계측 프레임 — 뷰파인더식 모서리 눈금. 빈 상자가 아니라 측정 시야라는 뜻을 준다.
   재생 중(is-wait/is-go)에는 배경이 신호색이 되므로 눈금을 치운다. */
.test-stage::before { content: ""; position: absolute; inset: 10px; pointer-events: none;
  background:
    linear-gradient(var(--color-text-muted), var(--color-text-muted)) top left / 14px 1px,
    linear-gradient(var(--color-text-muted), var(--color-text-muted)) top left / 1px 14px,
    linear-gradient(var(--color-text-muted), var(--color-text-muted)) top right / 14px 1px,
    linear-gradient(var(--color-text-muted), var(--color-text-muted)) top right / 1px 14px,
    linear-gradient(var(--color-text-muted), var(--color-text-muted)) bottom left / 14px 1px,
    linear-gradient(var(--color-text-muted), var(--color-text-muted)) bottom left / 1px 14px,
    linear-gradient(var(--color-text-muted), var(--color-text-muted)) bottom right / 14px 1px,
    linear-gradient(var(--color-text-muted), var(--color-text-muted)) bottom right / 1px 14px;
  background-repeat: no-repeat; opacity: .5; }
.test-stage.is-wait { background: var(--color-stage-wait); border-color: var(--color-stage-wait); }
.test-stage.is-go { background: var(--color-stage-go); border-color: var(--color-stage-go); }
.test-stage.is-wait::before, .test-stage.is-go::before { content: none; }
.test-stage.is-wait .stage-msg, .test-stage.is-go .stage-msg,
.test-stage.is-wait .stage-sub, .test-stage.is-go .stage-sub { color: var(--color-on-stage); }
.test-stage > .btn, .test-stage > .btn-secondary { position: relative; z-index: 1; }
/* 스테이지 아래 도구 줄 — 판 안에는 게임만. 왼쪽 난이도, 오른쪽 다시하기·소리. */
.stage-tools { display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-3); margin-top: var(--space-3); min-height: 40px; }
.stage-tools-side { display: flex; align-items: center; gap: var(--space-2); }
.stage-tools-side:last-child { margin-left: auto; }
.stage-tool { width: 40px; min-height: 40px; padding: 0; font-size: var(--text-lg);
  color: var(--color-text-muted); position: relative; }
@media (hover: hover) { .stage-tool:hover { color: var(--color-text); } }
/* 소리 끔 상태는 사선+흐림 (컬러 이모지 🔊는 흑백 글리프 통일 원칙에 어긋나 쓰지 않는다) */
.sound-toggle.is-off { opacity: .55; }
.sound-toggle.is-off::after { content: ''; position: absolute; left: 9px; right: 9px;
  top: 50%; height: 2px; background: currentColor; transform: rotate(-45deg); }
/* 소리 설정 패널 — ♪ 아래에 떠서 효과음·배경 음악을 각각 조절 */
.stage-tools-side { position: relative; }
.sound-panel { position: absolute; top: 44px; right: 0; z-index: 5;
  background: var(--color-surface); border: 1px solid var(--color-outline);
  border-radius: var(--radius-md); padding: var(--space-3); display: grid; gap: var(--space-2);
  box-shadow: var(--shadow-pop); }
.sound-row { display: grid; grid-template-columns: auto 64px 110px; align-items: center;
  gap: var(--space-2); font: 500 var(--text-xs)/1 var(--font-mono); color: var(--color-text);
  white-space: nowrap; cursor: pointer; }
.sound-row input[type="range"] { width: 110px; accent-color: var(--color-primary); }
.sound-row input[type="checkbox"] { accent-color: var(--color-primary); width: 16px; height: 16px; }

/* 에임 타깃 — 크기는 난이도가 인라인으로 정한다(보통 48px) */
.aim-target { position: absolute; width: 48px; height: 48px; border-radius: 50%;
  background: var(--color-primary); border: 2px solid var(--color-on-primary); cursor: crosshair; }

/* 난이도 선택 — 도구 줄 왼쪽에 산다. 데일리·종합 측정 중에는 아예 만들지 않는다(page.js). */
.mode-select { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.mode-btn { min-height: 36px; padding: 0 var(--space-3); border-radius: var(--radius-md);
  font: 600 var(--text-xs)/1 var(--font-mono); letter-spacing: .04em;
  background: none; border: 1px solid var(--color-outline); color: var(--color-text-muted); cursor: pointer; }
@media (hover: hover) { .mode-btn:hover { color: var(--color-text); border-color: var(--color-primary); } }
.mode-btn[aria-pressed="true"] { color: var(--color-signal-text); border-color: var(--color-primary);
  background: var(--color-bg); font-weight: 700; }

/* 격자(순서·색) */
/* 칸 크기는 src/js/lib/grid.js가 --cols/--tile로 정한다(SSOT).
   여기서 min-width로 따로 바닥을 깔면 트랙보다 타일이 커져 서로 겹친다 — 실제로 겪었다. */
.tile-grid { display: grid; gap: var(--space-2); margin: 0 auto;
  grid-template-columns: repeat(var(--cols, 3), var(--tile, 44px)); }
.tile { width: var(--tile, 44px); height: var(--tile, 44px); border-radius: var(--radius-md);
  background: var(--color-surface-raised); border: 1px solid var(--color-outline);
  cursor: pointer; position: relative; }
.tile.is-lit { background: var(--color-primary); border-color: var(--color-on-primary); }
@keyframes tile-pop { from { transform: scale(.82); } }
@keyframes tile-shake { 25% { transform: translateX(-3px); } 75% { transform: translateX(3px); } }
/* 정답 탭 손맛 — 얇은 링 하나가 퍼지고 끝(transform/opacity만 애니메이트, 무끊김 원칙).
   번쩍이는 색 반전 대신 미니멀한 파동으로 "맞았다"를 준다. */
@keyframes hit-ring { from { transform: scale(.92); opacity: .9; } to { transform: scale(1.18); opacity: 0; } }
.tile.is-hit { animation: tile-pop 160ms cubic-bezier(.34, 1.56, .64, 1); }
.tile.is-hit::before { content: ""; position: absolute; inset: -3px; border-radius: inherit;
  border: 2px solid var(--color-primary); pointer-events: none;
  animation: hit-ring 340ms ease-out forwards; }
/* 침팬지: 맞힌 칸은 조용히 물러난다 — 표식을 얹는 대신 무대에서 빠지는 쪽이 차분하다 */
.tile.is-done { opacity: .22; transition: opacity 160ms ease-out; }
.tile.is-answer { animation: tile-pop 120ms ease-out; }
.tile.is-wrong { animation: tile-shake 160ms ease-in-out; }
/* 정답 표식(✓) — 색만으로 알리지 않기 위한 접근성 장치. 톤은 낮춘다(번쩍임 금지). */
.tile.is-answer { outline: 2px solid var(--color-success); outline-offset: -2px; position: relative; }
.tile.is-answer::after { content: "✓"; position: absolute; inset: 0; display: flex;
  align-items: center; justify-content: center; color: var(--color-success); opacity: .9;
  font: 600 var(--text-sm)/1 var(--font-mono); }
.tile.is-wrong { outline: 2px solid var(--color-danger); outline-offset: -2px; }

/* ─── 침팬지 스테이지 연출(2026-08-03) — 판의 세 박자: 숫자 깔림·가림·판 통과.
   transform만 쓴다: 시간제 노출(0.65초)에서 opacity 연출은 숫자 판독 시간을 깎는다.
   깔림은 전 타일 동시 팝 — 순서대로 시차를 주면 순서 정보가 시간축으로 새서 과제가 쉬워진다(측정 동등성). */
/* 2차(같은 날): "티가 잘 안 난다"(사장님) — 전부 크고 길게. 1차의 소심한 수치(스케일 .86~1.07,
   170~320ms)는 44px 타일에서 안 읽혔다. 시간제 모드만 짧게 유지(판독 시간 보호). */
@media (prefers-reduced-motion: no-preference) {
  .tile.is-enter { animation: tile-enter 280ms cubic-bezier(.34, 1.56, .64, 1); }
  .tile-grid.is-timed .tile.is-enter { animation-duration: 120ms; }
  .tile.is-mask { animation: tile-mask 300ms ease-in-out; } /* 세로 블링크 — "닫혔다"가 보인다 */
  .tile-grid.is-clear { animation: grid-clear 420ms cubic-bezier(.2, .9, .3, 1.4); }
  .tile-grid.is-clear .tile.is-done { animation: tile-clear-pop 420ms ease-out; }
}
@keyframes tile-enter { from { transform: scale(.45); } 62% { transform: scale(1.12); } }
@keyframes tile-mask { 45% { transform: scaleY(.08); } }
@keyframes grid-clear { 30% { transform: translateY(-6px) scale(1.03); } 60% { transform: translateY(0) scale(.99); } }
@keyframes tile-clear-pop { 25% { opacity: .75; transform: scale(1.22); } 100% { opacity: .22; } }

/* ─── 타자 스테이지 — 한국 타자연습 정석 2줄 대응: 제시문 배너 + 바로 아래 보이는 입력줄.
   숨은 입력(1px·투명, Monkeytype식)은 한글 IME에서 공식 고장이라 폐기(research-2026-08-03-typing-ux.md).
   치는 글자가 입력줄에 그대로 보여 조용한 죽음이 구조적으로 불가능하다. */
.type-line { position: relative; font: 600 var(--text-lg)/1.8 var(--font-sans); max-width: 44ch;
  margin: var(--space-4) auto 0; padding: var(--space-3) var(--space-4);
  background: var(--color-surface-raised); border: 1px solid var(--color-outline);
  border-radius: var(--radius-md); text-align: left; user-select: none;
  color: var(--color-text-muted); }
.type-line .t-ok { color: var(--color-text); }
.type-line .t-bad { color: var(--color-danger); text-decoration: underline; text-underline-offset: 3px; }
/* IME 조합 중 글자 — 판정 전이지만 "입력이 들어오고 있다"를 즉시 보여준다 */
.type-line .t-composing { color: var(--color-text); border-bottom: 2px dotted var(--color-primary); }
/* 미끄러지는 캐럿 — 현재 글자 위치로 transition(프리미엄 감의 절반은 이 장치 하나) */
.type-caret { position: absolute; width: 2px; background: var(--color-primary); pointer-events: none; }
@media (prefers-reduced-motion: no-preference) {
  .type-caret { transition: left 80ms ease-out, top 80ms ease-out; animation: caret-blink 1.1s step-end infinite; }
}
@keyframes caret-blink { 50% { opacity: .25; } }
/* 유령 페이스 캐럿 — 최고 기록 속도가 달리는 청록 바 + ▾ 표식(깜빡임 없음 — 진짜 캐럿과 구분).
   1차(회색 점선만)는 "버그 같다" 판정(사장님) — 표식 없는 유령은 유령이 아니라 얼룩이다. */
.type-ghost { background: none; border-left: 2px solid var(--color-data); width: 0; opacity: .6; animation: none; }
.type-ghost::before { content: "▾"; position: absolute; top: -1em; left: -0.34em;
  color: var(--color-data); font-size: .72em; line-height: 1; opacity: .95; }
@media (prefers-reduced-motion: no-preference) {
  .type-ghost { transition: left .24s linear, top .24s linear; }
}
/* 허브의 게임별 순위판 그리드 — rank-box 부품 재사용, 폭 제한만 해제 */
.boards-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: var(--space-3); margin-top: var(--space-3); }
.boards-grid .rank-box { margin-top: 0; max-width: none; }

/* 결과 타수-시간 그래프 — 이번 판 곡선 + 최고 기록 점선 */
.typing-graph { margin: var(--space-3) 0 0; }
.typing-graph svg { width: 100%; max-width: 320px; height: 64px; display: block; }
.typing-graph .g-pace { stroke: var(--color-data); stroke-width: 2; fill: none; }
.typing-graph .g-best { stroke: var(--color-outline); stroke-width: 1.5; stroke-dasharray: 5 4; }
.typing-graph figcaption { font: var(--text-xs)/1.5 var(--font-mono); color: var(--color-text-muted);
  margin-top: 2px; }

/* 입력줄 — 밑줄형(한컴 계열). 포커스는 밑줄 색으로 말한다(기본 outline도 유지). */
.type-input { display: block; width: 100%; max-width: 44ch; margin: var(--space-3) auto 0;
  padding: var(--space-2) 2px; font: 500 var(--text-lg)/1.5 var(--font-sans);
  color: var(--color-text); background: none; border: 0; border-radius: 0;
  border-bottom: 2px solid var(--color-outline); }
.type-input:focus { border-bottom-color: var(--color-primary); }
/* 다음 문장 미리보기 — 전환이 끊기지 않게 반 박자 먼저 보여준다 */
.type-next { font: var(--text-sm)/1.6 var(--font-sans); color: var(--color-text-muted);
  max-width: 44ch; margin: var(--space-3) auto 0; text-align: left; opacity: .65; }

/* 에임 명중 링 — 타깃이 사라진 자리에서 파동 하나 */
.hit-ring { position: absolute; border-radius: 50%; border: 2px solid var(--color-primary);
  pointer-events: none; animation: hit-ring 340ms ease-out forwards; }
.tile.is-lit::after { content: attr(data-step); position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  color: var(--color-on-primary); font: 700 var(--text-md)/1 var(--font-mono); }

/* 입력 */
.field { display: flex; gap: var(--space-2); justify-content: center; flex-wrap: wrap; max-width: 100%; }
.field input { background: var(--color-bg); color: var(--color-text);
  border: 1px solid var(--color-outline); border-radius: var(--radius-md);
  min-height: 44px; padding: 0 var(--space-3);
  font: 700 var(--text-xl)/1 var(--font-mono); font-variant-numeric: tabular-nums;
  width: min(12ch, 100%); text-align: center; letter-spacing: .08em; }

/* 결과 판독부 */
#result { margin-top: var(--space-4); }
.readout { border-color: var(--color-outline); }
.result-value { font: 800 var(--text-readout)/1 var(--font-mono);
  font-variant-numeric: tabular-nums; letter-spacing: -.03em; margin: 0; }
.result-pct { color: var(--color-text-muted); margin: var(--space-2) 0 var(--space-3);
  font-size: var(--text-sm); }
.result-pct b { color: var(--color-data); font-family: var(--font-mono);
  font-variant-numeric: tabular-nums; }
.result-actions { display: flex; flex-wrap: wrap; gap: var(--space-3); margin: var(--space-4) 0 var(--space-3); }
/* 한 줄 판정 — 점수 밑의 펀치라인. 큰 숫자(고정폭) 다음에 오는 사람 말이라 산세리프로 구분한다. */
.verdict { font: 600 var(--text-md)/1.5 var(--font-sans); color: var(--color-text);
  margin: var(--space-2) 0 0; max-width: 52ch;
  white-space: pre-line; /* page.js가 문장 사이에 \n을 넣는다 — 문장 단위 두 줄 표시(사장님 지적: 중간 끊김 가독성) */ }
/* 상황 부제(도박·신기록 격려·재시도·새벽) — 티어 멘트를 대체하지 않고 아래 작은 줄로 얹는다 */
.verdict-sub { font: var(--text-sm)/1.5 var(--font-sans); color: var(--color-text-muted);
  margin: 4px 0 0; max-width: 52ch; }
/* 등급명 배지 — 판정 문장 위의 한 단어 해석층(신기록 .badge와 같은 칩 결, 색만 링크 계열로 구분) */
.tier-chip { display: inline-block; border: 1px solid var(--color-link); color: var(--color-link);
  border-radius: var(--radius-sm); margin: var(--space-2) 0 0; padding: 2px var(--space-2);
  font: 700 var(--text-xs)/1.4 var(--font-mono); letter-spacing: .1em; }
/* 한국어는 단어(어절) 단위로만 줄을 꺾는다 — 기본값은 "골든타/임"처럼 아무 글자에서나 자른다. */
:root:lang(ko) { word-break: keep-all; overflow-wrap: break-word; }
/* 데일리 리더보드 — 계기판 전광판. 순위·점수는 고정폭, 이름과 점수는 점선 리더로 잇는다.
   메달색(금=신호 앰버·은·동)은 Pro Max 리더보드 관례를 토큰으로 이식(--rank-*). */
.rank-box { margin-top: var(--space-4); border: 1px solid var(--color-outline);
  border-radius: var(--radius-lg); padding: var(--space-3) var(--space-4) var(--space-4);
  background: var(--color-surface); max-width: 38ch; }
.rank-head { display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-3); }
.rank-title { margin: 0; font: 700 var(--text-xs)/1.6 var(--font-mono); color: var(--color-signal-text);
  text-transform: uppercase; letter-spacing: .08em; }
.rank-title a { color: inherit; text-decoration: none; }
@media (hover: hover) { .rank-title a:hover { text-decoration: underline; } }
.rank-more { display: inline-block; margin-top: var(--space-3);
  font: 600 var(--text-sm)/1.4 var(--font-mono); color: var(--color-link); text-decoration: none; }
@media (hover: hover) { .rank-more:hover { text-decoration: underline; } }
.rank-total { font: 600 var(--text-xs)/1.6 var(--font-mono); color: var(--color-text-muted);
  font-variant-numeric: tabular-nums; }
.rank-list { list-style: none; margin: var(--space-3) 0 0; padding: 0; }
.rank-list li { display: flex; align-items: baseline; gap: var(--space-2);
  padding: 6px 0; font: var(--text-sm)/1.5 var(--font-mono); font-variant-numeric: tabular-nums; }
.rank-list li + li { border-top: 1px solid var(--color-grid); }
.rank-no { min-width: 2ch; text-align: right; font-weight: 700; color: var(--color-text-muted); }
/* 닉네임은 전부 보인다 — 8자 제한(한글 모노폭 ≈ 16ch)이 18ch 안에 항상 들어온다.
   말줄임은 제한이 12자였던 시절의 옛 기록용 안전망일 뿐이다(사장님 "풀네임" 2026-08-03). */
.rank-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 18ch; }
.rank-list li i { flex: 1; border-bottom: 1px dotted var(--color-grid); transform: translateY(-4px); }
.rank-list li b { font-weight: 600; }
.rank-list li:nth-child(1) .rank-no, .rank-list li.is-first b { color: var(--rank-gold); }
.rank-list li:nth-child(2) .rank-no { color: var(--rank-silver); }
.rank-list li:nth-child(3) .rank-no { color: var(--rank-bronze); }
.rank-list li.is-ghost { color: var(--color-text-muted); opacity: .5; }
.rank-list li.is-ghost .rank-no { color: inherit; }
.rank-note { margin: var(--space-2) 0 0; font: var(--text-sm)/1.5 var(--font-sans); color: var(--color-text-muted); }
.rank-note.is-you { color: var(--color-signal-text); font: 700 var(--text-sm)/1.5 var(--font-mono); }
.rank-form { justify-content: flex-start; margin-top: var(--space-3); }
.home-rank { margin: var(--space-3) 0 var(--space-2); max-width: none; }
/* 행 등장 — 8px 떠오름 + 50ms 스태거(툴킷 모션 규칙: transform/opacity만·감속 이징·reduced-motion 존중) */
@media (prefers-reduced-motion: no-preference) {
  .rank-list li { animation: rank-in .4s cubic-bezier(.2, .7, .3, 1) backwards; }
  .rank-list li:nth-child(2) { animation-delay: .05s; }
  .rank-list li:nth-child(3) { animation-delay: .1s; }
  .rank-list li:nth-child(4) { animation-delay: .15s; }
  .rank-list li:nth-child(5) { animation-delay: .2s; }
}
@keyframes rank-in { from { opacity: 0; transform: translateY(8px); } }

/* ─── 결과 보상 연출(2026-08-03) — transform/opacity만, reduced-motion 존중 ─── */
#result { position: relative; }
.rb-mascot { position: absolute; top: var(--space-3); right: var(--space-4);
  width: 72px; height: 72px; pointer-events: none; } /* 얼굴 마크판 — 풀바디는 AI 아트로 재도전(사장님 퀄 판정) */
.rb-mascot svg { width: 100%; height: 100%; display: block; }
.rb-mascot[data-mood="smug"] svg { transform: rotate(-6deg); }
@media (prefers-reduced-motion: no-preference) {
  /* 1차는 "빨라서 효과가 있는지도 모르겠다"(사장님) — 전부 길고 크게.
     2차(같은 날): 등장 후에도 상시 미세 모션 — 멈춘 마스코트는 스티커지 캐릭터가 아니다. */
  .rb-mascot svg { transform-origin: 50% 92%; } /* 스쿼시&스트레치의 축 = 발바닥 */
  .rb-mascot .m-eyes { transform-box: fill-box; transform-origin: 50% 50%;
    animation: mascot-blink 3.4s ease-in-out infinite; } /* 깜빡임 — 살아 있음의 최소 신호 */
  .rb-mascot[data-mood="wow"] svg { animation: mascot-pop .8s cubic-bezier(.2, .9, .3, 1.45), mascot-bounce 1.7s .9s cubic-bezier(.4, 0, .3, 1) infinite; }
  .rb-mascot[data-mood="wow"] .m-banana { transform-box: fill-box; transform-origin: 50% 95%;
    animation: banana-wave 1s .35s cubic-bezier(.4, 0, .3, 1.3) 3; }
  .rb-mascot .m-arm-l { transform-box: fill-box; transform-origin: 85% 10%;
    animation: arm-swing 2.9s ease-in-out infinite; } /* 만세 팔 미세 스윙 */
  .rb-mascot[data-mood="smug"] .m-banana-floor { transform-box: fill-box; transform-origin: 50% 50%;
    animation: banana-drop .6s .25s cubic-bezier(.35, 0, .8, 1) both; } /* 집어던진 바나나 낙하 */
  .rb-mascot[data-mood="smug"] svg { animation: mascot-tilt .7s ease-out, mascot-sway 3.2s .8s ease-in-out infinite; }
  .rb-mascot[data-mood="base"] svg { animation: mascot-breathe 3s ease-in-out infinite; }
  /* 결과 요소 순차 등장 — 14px 떠오름, 스태거 ≤6 */
  #result.is-reveal > * { animation: result-rise .5s cubic-bezier(.2, .7, .3, 1) backwards; }
  #result.is-reveal > :nth-child(2) { animation-delay: .07s; }
  #result.is-reveal > :nth-child(3) { animation-delay: .14s; }
  #result.is-reveal > :nth-child(4) { animation-delay: .21s; }
  #result.is-reveal > :nth-child(5) { animation-delay: .28s; }
  #result.is-reveal > :nth-child(6) { animation-delay: .35s; }
  .badge { animation: badge-pop .65s cubic-bezier(.2, .9, .3, 1.6); }
}
@keyframes mascot-pop { 0% { transform: scale(.3); } 55% { transform: scale(1.25); } 100% { transform: scale(1); } }
@keyframes mascot-tilt { from { transform: rotate(14deg); } to { transform: rotate(-6deg); } }
/* 스쿼시&스트레치 바운스 — 착지에서 눌리고 뜰 때 늘어난다(애니메이션 기본기, 밋밋한 상하이동 금지) */
@keyframes mascot-bounce {
  0%, 100% { transform: translateY(0) scale(1, 1); }
  28% { transform: translateY(-9px) scale(.97, 1.05); }
  46% { transform: translateY(0) scale(1.07, .9); }
  62% { transform: translateY(-4px) scale(.99, 1.02); }
  76% { transform: translateY(0) scale(1.03, .96); }
}
@keyframes mascot-sway { 0%, 100% { transform: rotate(-7deg) translateX(0); } 50% { transform: rotate(-1deg) translateX(1.5px); } }
@keyframes mascot-breathe { 0%, 100% { transform: translateY(0) scale(1); } 50% { transform: translateY(-2.5px) scale(1.025, 1.035); } }
@keyframes banana-wave { 0%, 100% { transform: rotate(0); } 45% { transform: rotate(-26deg); } 70% { transform: rotate(6deg); } }
@keyframes mascot-blink { 0%, 91%, 100% { transform: scaleY(1); } 94.5% { transform: scaleY(.08); } 98% { transform: scaleY(1); } }
@keyframes arm-swing { 0%, 100% { transform: rotate(0); } 50% { transform: rotate(7deg); } }
@keyframes banana-drop {
  0% { transform: translate(-16px, -42px) rotate(110deg); }
  70% { transform: translate(0, 0) rotate(0); }
  84% { transform: translate(1px, -4px) rotate(-8deg); }
  100% { transform: translate(0, 0) rotate(0); }
}
@keyframes result-rise { from { opacity: 0; transform: translateY(14px); } }
@keyframes badge-pop { from { transform: scale(.3); } 55% { transform: scale(1.3); } to { transform: scale(1); } }
/* 신기록 스파크 — 앰버 점 12개가 크게 흩어지며 사라진다(1회성, blur 없음) */
#result-value { position: relative; }
.spark-burst { position: absolute; left: 1.2em; top: .5em; width: 0; height: 0; pointer-events: none; }
.spark-burst i { position: absolute; width: 9px; height: 9px; border-radius: 50%;
  background: var(--color-primary); animation: spark-fly 1.05s cubic-bezier(.2, .7, .4, 1) forwards; }
@keyframes spark-fly { from { opacity: 1; transform: translate(0, 0) scale(1.1); }
  to { opacity: 0; transform: translate(var(--dx), var(--dy)) scale(.15); } }
@media (max-width: 520px) { .rb-mascot { width: 56px; height: 56px; } }
/* 등급 구간 — 분포에서 유도한 값이라 백분위가 있을 때만 나온다.
   색만으로 뜻을 전하지 않게 글자를 함께 쓴다. */
.band { display: inline-block; vertical-align: middle; margin-left: var(--space-2);
  border: 1px solid var(--color-outline); border-radius: var(--radius-sm);
  padding: 2px var(--space-2); font: 700 var(--text-xs)/1.4 var(--font-mono);
  letter-spacing: .08em; color: var(--color-text-muted); cursor: help; }
.band-top, .band-strong { color: var(--color-data); border-color: var(--color-data); }
@keyframes stamp { from { transform: scale(1.7); opacity: 0; } }
.badge { animation: stamp 220ms ease-out; display: inline-block; vertical-align: middle; border: 1px solid var(--color-success);
  color: var(--color-success); border-radius: var(--radius-sm); margin-left: var(--space-2);
  padding: 2px var(--space-2); font: 700 var(--text-xs)/1.4 var(--font-mono); letter-spacing: .1em; }
.meta-line { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.history { list-style: none; padding: 0; margin: 0; font: 400 var(--text-sm)/1 var(--font-mono);
  font-variant-numeric: tabular-nums; color: var(--color-text-muted); }
.history li { padding: var(--space-2) 0; border-bottom: 1px solid var(--color-outline); }

/* 라운드 상세 — 중앙값이 어디서 나왔는지 */
.rounds { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2);
  margin: var(--space-3) 0 var(--space-2); }
.rounds-label { font: 600 var(--text-xs)/1 var(--font-mono); letter-spacing: .16em;
  text-transform: uppercase; color: var(--color-text-muted); }
.round-chip { font: 500 var(--text-xs)/1 var(--font-mono); font-variant-numeric: tabular-nums;
  color: var(--color-text-muted); border: 1px solid var(--color-outline);
  border-radius: var(--radius-sm); padding: var(--space-1) var(--space-2); }
.round-chip.is-median { color: var(--color-text); border-color: var(--color-primary); font-weight: 700; }

/* 다음 테스트 고리 */
.next-up { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3);
  margin: var(--space-4) 0 0; padding-top: var(--space-3); border-top: 1px solid var(--color-outline); }
.next-up .eyebrow { margin: 0; }
.next-link { text-decoration: none !important; }

/* 홈 — 내 기록 */
#records { margin-top: var(--space-6); }
.records-head { display: flex; align-items: baseline; gap: var(--space-3); flex-wrap: wrap; }
.records-head h2 { margin: 0; }
.records-streak { font: 600 var(--text-xs)/1 var(--font-mono); letter-spacing: .1em;
  text-transform: uppercase; color: var(--color-signal-text); margin: 0; }
.records-grid { list-style: none; padding: 0; margin: var(--space-3) 0 var(--space-2);
  display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: var(--space-2); }
.record { display: flex; flex-direction: column; gap: var(--space-1);
  border: 1px solid var(--color-outline); border-radius: var(--radius-md);
  padding: var(--space-3); color: var(--color-text); }
@media (hover: hover) { .record:hover { border-color: var(--color-primary); text-decoration: none; } }
.record-name { font-size: var(--text-sm); color: var(--color-text-muted); }
.record-value { font: 700 var(--text-lg)/1 var(--font-mono); font-variant-numeric: tabular-nums; }
.record-value.is-empty { color: var(--color-text-muted); font-size: var(--text-sm); font-weight: 400; }

/* 시그니처: 분포 곡선 — 결과 화면의 주인공답게 굵고 또렷하게(2026-08-03 개편).
   창 크기가 바뀌어 SVG가 늘어나도 선 굵기는 유지된다(vector-effect). */
.curve-wrap { margin: var(--space-3) 0 var(--space-2); }
.curve { width: 100%; height: 132px; display: block; }
.curve-line, .curve-axis, .curve-tick, .curve-you { vector-effect: non-scaling-stroke; }
.curve-line { fill: none; stroke: var(--color-data); stroke-width: 2.5; stroke-linejoin: round; }
.curve-area { fill: var(--color-data-fill); stroke: none; }
.curve-axis { stroke: var(--color-outline); stroke-width: 1; }
.curve-tick { stroke: var(--color-text-muted); stroke-width: 1.5; }
.curve-dot { fill: var(--color-data); opacity: .8; }
.curve-you { stroke: var(--color-primary); stroke-width: 2.5; }
.curve-you-dot { fill: var(--color-primary); stroke: var(--color-surface); stroke-width: 2; }
.curve-you-label, .curve-label { fill: var(--color-text-muted);
  font: 700 11px var(--font-mono); letter-spacing: .08em; text-transform: uppercase; }
.curve-you-label { fill: var(--color-primary); }
.curve-caption { color: var(--color-text-muted); font-size: var(--text-xs);
  font-family: var(--font-mono); margin: 0; }

/* 본문 아티클 */
article { margin-top: var(--space-6); border-top: 1px solid var(--color-outline); padding-top: var(--space-4); }
article ul { padding-left: var(--space-4); }
article h2:first-of-type { margin-top: var(--space-3); }

.lives { font-size: var(--text-md); }
