/* ==========================================================================
   KEMI8 — 단일 스타일시트 (손으로 씀. 프레임워크·빌드도구 없음)

   v3 비주얼 (2026-08-27) — 계획서 `plans/2026-08-27-landing-visual-v3.md`
      owner 판정이 "글씨 위주의 AI slop" 이었다. 팔레트·서체·리듬을 통째로 갈았다.

   금색은 강등됐다. 금색-검정은 운세 카테고리의 기본값이고, 이 제품이 파는 것은
      행운이 아니라 언제 빛이 드는가다. UI 강조는 찬 여명색(--accent)이고
      금색(--ember)은 변곡점 트랙의 세 구간이 켜질 때만 쓴다. 다른 데 쓰지 마라.

   모바일 우선 360~430px · 본문 최대폭 760px · 히어로/트랙 1180px
   대비: 본문/강조/보조 전부 WCAG AA(4.5:1) 이상. 아래 주석의 계산값을 지켜라.
   ========================================================================== */

:root {
  /* 배경 계열 — 먹이 마른 색 */
  --bg:        #0B0908;   /* 본 배경 */
  --bg-2:      #14110F;   /* 올라온 면. 광고 소재(docs/22)와 같은 값 */
  --bg-3:      #12100E;   /* 표 줄무늬 */
  --line:      #241F1B;   /* 경계선 */
  --line-2:    #342D26;

  /* 글자 — 배경 #0B0908 대비 (계산값) */
  --fg:        #F2EDE4;   /* 17.9:1 — 한지 */
  --fg-2:      #9E9689;   /*  6.4:1 — 보조 본문 */
  --fg-3:      #837B70;   /*  4.6:1 — 라벨. 이보다 어둡게 내리지 않는다 */

  /* 강조 — 여명(찬 빛). 예전 금색 자리다 */
  --accent:    #C6D4E4;   /* 12.8:1 — 링크·버튼·포커스 */
  --accent-2:  #E4EDF7;   /* hover */
  --ember:     #C8A44D;   /* 변곡점 발화 전용. 글자에 쓰지 않는다 */
  --warn:      #D08A6E;   /*  6.9:1 — 경고 "글자"용 */
  --warn-line: #B5674D;   /* 경고 "선"용. 이 색으로 본문 글자를 쓰지 않는다 */

  /* 서체 — 4역할 (계획서 §2.2)
     display 문학적 명조 · sans 기계적이고 정직한 얼굴 · mono 근거 칩(실제로 코드다)
     num     숫자 강조 전용. 본문 숫자에 확대하지 마라 — 서명이 장식이 된다 */
  --serif: 'Gowun Batang', 'Noto Serif KR', serif;
  --sans:  'IBM Plex Sans KR', system-ui, -apple-system, sans-serif;
  --mono:  'IBM Plex Mono', 'IBM Plex Sans KR', ui-monospace, SFMono-Regular, Menlo, monospace;
  --num:   'Instrument Serif', 'Gowun Batang', Georgia, serif;

  --wrap: 760px;
  --wrap-wide: 1180px;
  --pad: 22px;
  --bar-h: 58px;          /* 하단 고정 신원 바 높이 */
}

/* ==========================================================================
   메일 팔레트 — `--mail-*`  🔴 값의 원본은 여기다

   ⛔ **브라우저는 이 토큰을 쓰지 않는다.** 메일 전용이다. 그런데도 여기 두는 이유는
      `DESIGN.md` §0 — *"값의 원본은 app/static/app.css 의 :root 하나다"* — 때문이다.
      값 파일을 둘로 늘리면 그 규칙이 깨지고, 이 저장소는 이미 같은 실수로 다쳤다.

   왜 위 `:root` 토큰을 그냥 못 쓰나:
     ① 메일 클라이언트는 외부 CSS·`<style>` 을 안 읽는다 → 전부 **인라인**이어야 하고,
        그래서 파이썬(`app/mail_theme.py`)이 이 값을 읽어 문자열로 박는다.
     ② 위 팔레트는 **어두운 배경**(--bg #0B0908)이고 메일은 **밝은 배경**이다.
        받은편지함은 흰 바탕이라 어두운 팔레트를 그대로 쓸 수 없다. 역할은 같고 값이 다르다.

   표기는 **소문자로 통일**한다. 한 값에 두 표기가 있으면 grep 이 갈린다.
   대비 바닥선(4.5:1)은 `tests/test_mail_selftest.py` 가 이 토큰을 읽어 강제한다.
   ========================================================================== */
:root {
  /* 면 — 밝은 쪽에서 어두운 쪽으로 */
  --mail-canvas:     #f5f0e8;   /* 메일 바깥 바탕 */
  --mail-surface:    #ffffff;   /* 본문 카드 면 */
  --mail-raised:     #faf7f1;   /* 올라온 면 — 보관 안내 · 신원표시 */
  --mail-card:       #f7f3ea;   /* 트랙 카드 면 */
  --mail-chip:       #f2f0ed;   /* 근거 앵커 칩 면 */
  --mail-track-idle: #e4daca;   /* 타임라인 — 발화하지 않은 달 */

  /* 선 */
  --mail-border:      #e3ddd2;  /* 본문 카드 테두리 */
  --mail-rule:        #ece6db;  /* 구분선 */
  --mail-card-border: #ded4c4;  /* 트랙 카드 테두리 */

  /* 글자 — 전부 각자의 면 위에서 4.5:1 이상 */
  --mail-fg:        #14110f;    /* 본문 · 강조 */
  --mail-fg-title:  #17140f;    /* 트랙 카드 제목 */
  --mail-fg-notice: #3f3a34;    /* 보관 안내 */
  --mail-fg-label:  #5a5248;    /* 트랙 카드 라벨 · 축 · 범례 */
  --mail-fg-2:      #5b554e;    /* 보조 본문 · 앵커 칩 · 태그라인 */
  --mail-fg-track:  #3a2f18;    /* 타임라인 번호 ①②③ */

  /* 강조 — `--ember` 의 메일 짝 */
  --mail-ember:      #c8a44d;   /* ⛔ 선·칸 배경 전용. **글자에 쓰지 않는다** (DESIGN.md §1) */
  --mail-ember-text: #8a6d1f;   /* 글자용 변형 — 링크 · 주문번호. 흰 바탕 4.90:1 */
}


* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  padding-bottom: calc(var(--bar-h) + env(safe-area-inset-bottom, 0px));
  background: var(--bg);
  color: var(--fg);
  font-family: var(--sans);
  font-weight: 300;              /* Plex Sans KR 은 300 이 본문 무게다 */
  font-size: 16px;
  line-height: 1.8;
  letter-spacing: -0.006em;
  word-break: keep-all;      /* 한국어 어절 단위 줄바꿈 */
  overflow-wrap: break-word;
}

.wrap { width: 100%; max-width: var(--wrap); margin: 0 auto; padding: 0 var(--pad); }

/* ── 링크 · 포커스 ───────────────────────────────────────────────────────── */
a { color: var(--accent); text-underline-offset: 3px; }
a:hover { color: var(--accent-2); }

/* 🔴 포커스 링을 지우지 않는다 (키보드 사용자) */
:focus-visible {
  outline: 3px solid var(--accent-2);
  outline-offset: 2px;
  border-radius: 2px;
}

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--accent); color: var(--bg);
  padding: 10px 16px; font-weight: 700; text-decoration: none;
}
.skip-link:focus { left: 8px; top: 8px; }

.visually-hidden {
  position: absolute !important; width: 1px; height: 1px;
  margin: -1px; padding: 0; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* ── 헤더 ────────────────────────────────────────────────────────────────── */
.site-head {
  position: absolute; top: 0; left: 0; right: 0; z-index: 50;
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  max-width: var(--wrap-wide); margin: 0 auto; padding: 22px var(--pad);
  border-bottom: 0;
}
/* 🔴 헤더 전용 스크림 — 실측(390×844): 포스터 밝은 부분 위에서 브랜드 3.62:1,
   태그라인 **1.01:1** 이었다. 사실상 안 보인다.
   ⛔ 히어로 전체 스크림을 올려서 해결하지 마라 — 영상이 통째로 죽는다.
      헤더 뒤에만, 아래로 사라지는 그라디언트를 깐다. */
body[data-state="landing"] .site-head::before {
  content: ''; position: absolute; inset: -6px 0 -34px; z-index: -1;
  pointer-events: none;
  /* 🔴 글자가 앉는 구간(0~58%)은 농도를 **유지**하고, 그 아래에서만 사라진다.
     실측 절차: 브랜드/태그라인을 숨기고 배경만 찍어 최악 픽셀로 대비를 잰다.
     퍼센트를 눈으로 고치지 마라 — 재고 고쳐라. */
  background: linear-gradient(to bottom,
    rgba(11,9,8,.96) 0%, rgba(11,9,8,.95) 58%, rgba(11,9,8,.45) 80%, rgba(11,9,8,0) 100%);
}
/* 🔴 태그라인은 --fg-3(4.6:1 on --bg) 이라 **밝은 배경 위에서는 어떤 스크림으로도 AA 를 못 넘긴다.**
   랜딩에서만 한 단계 밝힌다. ⛔ --fg-3 로 되돌리지 마라 — 실측 2.26:1 이었다. */
body[data-state="landing"] .brand-sub { color: var(--fg-2); }

/* 랜딩만 헤더가 히어로 위에 뜬다. 나머지 화면은 예전처럼 고정 띠다. */
body:not([data-state="landing"]) .site-head {
  position: static; max-width: var(--wrap); padding: 14px var(--pad);
  border-bottom: 1px solid var(--line);
}
.brand { text-decoration: none; color: var(--fg); display: flex; align-items: baseline; gap: 8px; }
.brand-mark { font-family: var(--serif); font-weight: 600; font-size: 18px; letter-spacing: .06em; }
.brand-sub  { font-size: 12px; color: var(--fg-3); }
.head-right { display: flex; align-items: center; gap: 8px; min-height: 28px; }

/* ♪ 소리 토글 — app.js 가 음원 존재를 확인한 뒤에만 삽입한다 */
.bgm-toggle {
  background: transparent; color: var(--fg-2);
  border: 1px solid var(--line-2); border-radius: 999px;
  font: inherit; font-size: 12px; line-height: 1;
  padding: 7px 12px; cursor: pointer;
}
.bgm-toggle:hover { color: var(--accent); border-color: var(--accent); }
.bgm-toggle[aria-pressed="true"] { color: var(--accent); border-color: var(--accent); }

/* ── 섹션 · 표제 ─────────────────────────────────────────────────────────── */
.sec  { padding: 56px 0; border-top: 1px solid var(--line); }
.sec:first-of-type { border-top: 0; }
.sec-wide { max-width: var(--wrap-wide); margin: 0 auto; padding: 0 var(--pad); }

h1, h2, h3 { font-family: var(--serif); font-weight: 700; line-height: 1.38; margin: 0 0 16px; }
h1 { font-size: 28px; }
h2 { font-size: 24px; letter-spacing: -0.02em; }
h3 { font-size: 17px; margin-top: 28px; }

/* 숫자 강조 — 계획서 §2.2 서명 타이포.
   한글은 명조, 숫자만 이탤릭 세리프. 한 줄 안에서 두 활자 문화가 만난다.
   ⛔ 본문 숫자에까지 확대하지 마라. 확대하는 순간 서명이 장식이 된다. */
.num {
  font-family: var(--num); font-style: italic; font-weight: 400;
  font-size: 1.12em; letter-spacing: -0.02em; color: var(--fg);
}

/* 눈썹 라벨 — 근거 칩과 같은 목소리(mono). 장식이 아니라 출처 표시다 */
.eyebrow {
  font-family: var(--mono); font-size: 11.5px; font-weight: 400;
  letter-spacing: .16em; text-transform: uppercase;
  color: var(--fg-3); margin: 0 0 14px;
}

.lead { font-size: 17px; margin: 14px 0; color: var(--fg-2); }
.big  { font-size: 18px; }
.sub-note { font-size: 13px; color: var(--fg-3); margin-left: 6px; }
.state-line { color: var(--fg-2); font-size: 14px; }
.sep { color: var(--fg-3); padding: 0 2px; }

p { margin: 0 0 14px; }
strong { font-weight: 500; color: var(--fg); }
em { font-style: normal; color: var(--fg-2); }
code {
  font-family: var(--mono);
  font-size: .88em; background: var(--bg-3); border: 1px solid var(--line);
  border-radius: 2px; padding: 1px 5px; color: var(--fg);
}

/* ── 탭 타깃 최소 크기 (WCAG 2.2 AA · 2.5.8) ────────────────────────────
   🔴 실측(390×844): 링크 14개 중 9개가 높이 24px 미만이었다. 최악은 히어로의
      `전체 샘플 먼저 읽기` **15px** — 320px 에서 CTA 잘림을 고치려고 버튼을 텍스트
      링크로 낮추면서 생긴 **회귀**다.
   ⛔ 인라인 예외에 기대지 마라 — 그 예외는 **문장 안에 박힌 링크**에만 붙는다.
      독립 행동(히어로 보조 링크·정책 링크 행)은 대상이 아니다.
   🔴 해법은 **보이는 크기가 아니라 누를 수 있는 면적**을 넓히는 것이다.
      가상요소로 위아래를 밀어내면 레이아웃 높이는 0px 늘고 타깃만 커진다.
   ⛔ 인접 타깃과 겹치면 오탭이 는다. 가로로 붙어 있는 행은 좌우가 아니라 위아래만 넓힌다. */
.tap-target { position: relative; }
.tap-target::before {
  content: ''; position: absolute; left: 0; right: 0;
  top: 50%; height: 24px; transform: translateY(-50%);
}

/* ── 랜딩의 축은 하나다 ───────────────────────────────────────────────────
   히어로·트랙이 1180 이고 본문이 760 이면 왼쪽 축이 두 개가 되어 화면이 어긋난다.
   컨테이너는 하나로 넓히고, 읽는 폭은 문단 자체에 건다(measure).
   ⛔ 전역 .wrap 을 건드리지 마라 — 신청·주문 화면의 폼이 같이 늘어난다. */
body[data-state="landing"] .wrap { max-width: var(--wrap-wide); }
body[data-state="landing"] .sec p,
body[data-state="landing"] .sec .bullets,
body[data-state="landing"] .sec .notice,
body[data-state="landing"] .sec .qa,
body[data-state="landing"] .sec .chips { max-width: 62ch; }
/* ⛔ 읽는 폭 제한에서 빼야 하는 것 — 이건 문단이 아니라 **눈금**이다.
   실측: .track-scale 이 62ch 에 걸려 `12개월 뒤` 가 화면 중간에 섰다.
   🔴 `.sec p`(0,2,2) 가 `.track-scale`(0,2,1) 보다 세다. 타입까지 붙여야 이긴다.
   ⛔ !important 로 때우지 마라 — 다음 사람이 같은 함정에 다시 빠진다. */
body[data-state="landing"] .sec p.track-scale { max-width: none; }
/* 발췌는 읽는 글이다. 1180 을 다 쓰면 오른쪽이 비어 미완성으로 보인다 */
body[data-state="landing"] .sec .excerpt { max-width: 68ch; }
body[data-state="landing"] .hero-sub { max-width: 34ch; }

/* ── 필름 그레인 ─────────────────────────────────────────────────────────
   전면 오버레이 1장. SVG feTurbulence 를 data URI 로 굽는다 — 요청 0건.
   ⛔ opacity 를 올리지 마라. 보이기 시작하면 그건 노이즈지 그레인이 아니다. */
.grain {
  position: fixed; inset: 0; z-index: 100; pointer-events: none;
  opacity: .035; mix-blend-mode: screen;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ── 히어로 ──────────────────────────────────────────────────────────────
   풀블리드 배경(영상 또는 포스터) 위에 텍스트. 계획서 §5 충돌 3.
   🔴 전면 균일 오버레이를 쓰지 않는다 — 영상이 죽고 싸구려가 된다.
      대신 하단으로 가는 세로 그라디언트 스크림을 글자 뒤에만 깐다. */
.hero {
  position: relative; isolation: isolate;
  /* 🔴 순서가 뒤집히면 안 된다. CSS 는 **아는 선언 중 마지막**을 고른다 —
     svh 를 vh 앞에 두면 svh 를 아는 브라우저도 vh 를 쓴다(= svh 가 죽은 코드).
     모바일 주소창이 떠 있으면 100vh > 실제 보이는 높이라 CTA 가 접힌 아래로 밀린다.
     ⛔ 헤드리스 실측으로는 못 잡는다 — 주소창이 없어서 vh == svh 다. */
  min-height: 92vh; min-height: 92svh;
  display: flex; align-items: flex-end;
  padding: 96px 0 44px;
  overflow: hidden;
}
.hero-bg {
  position: absolute; inset: 0; z-index: -2;
  width: 100%; height: 100%; object-fit: cover;
  background: transparent;
  /* 🔴 확대 프레이밍. 원본 그대로 두면 먹 번짐의 **윤곽 전체**가 보여서 "물체"로 읽힌다.
     밀어 넣으면 화면을 채우는 **대기**가 된다. .hero 의 overflow:hidden 이 잘라낸다.
     ⛔ 배율을 낮추지 마라 — 윤곽이 다시 드러난다. 올리면 화질이 무너진다. */
  transform: scale(1.45);
  object-position: 58% 64%;
}
/* 자산이 없을 때의 히어로 — 여명이 지평선 위로 번지고, 열두 달이 세로 눈금으로 잠겨 있다.
   🔴 이건 "자리 채우기"가 아니라 아래 변곡점 트랙의 예고편이다.
   ⛔ 영상이 생겨도 지우지 마라 — 영상이 막히거나 실패하면 이 층이 그대로 남는다. */
.hero-atmos {
  position: absolute; inset: 0; z-index: -3;
  background:
    radial-gradient(124% 66% at 50% 106%,
      rgba(198,212,228,.14) 0%, rgba(198,212,228,.05) 36%, transparent 68%),
    repeating-linear-gradient(90deg,
      rgba(242,237,228,.045) 0 1px, transparent 1px calc(100% / 12)),
    var(--bg);
}
/* 스크림 — 아래 62% 만 어둡게. 위쪽(하늘·빛)은 그대로 보인다.
   🔴 이 값을 낮추면 첫 화면의 가격 표시가 AA 를 못 지킬 수 있다 (법정 표시다). */
.hero::after {
  content: ''; position: absolute; inset: 0; z-index: -1;
  background:
    linear-gradient(to bottom,
      rgba(11,9,8,.34) 0%, rgba(11,9,8,.12) 24%,
      rgba(11,9,8,.62) 44%, rgba(11,9,8,.84) 64%, rgba(11,9,8,.97) 100%);
}
.hero .wrap { max-width: var(--wrap-wide); }

.hero-h1 {
  font-size: clamp(34px, 7.4vw, 60px);
  font-weight: 700; line-height: 1.16; letter-spacing: -0.035em;
  margin: 0 0 18px; color: var(--fg);
  text-wrap: balance;
}
.hero-h1 .line { display: block; }
.hero-h1 .num { font-size: 1.06em; }

.hero-sub {
  color: var(--fg-2); margin: 0; max-width: 30em;
  font-size: clamp(15px, 1.9vw, 17px); line-height: 1.65;
}
.hero-sub strong { color: var(--fg); font-weight: 500; }

/* 배지 — 눈썹 자리. mono 라 "라벨"로 읽히고 광고 배지처럼 안 보인다 */
.badge {
  display: inline-flex; align-items: center; gap: 9px;
  margin: 0 0 20px; padding: 7px 13px 7px 11px;
  border: 1px solid var(--line-2); border-radius: 2px;
  background: rgba(20,17,15,.62);
  -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
  font-family: var(--mono); font-size: 11.5px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--fg-2);
}
.badge .dot {
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--ember); box-shadow: 0 0 8px rgba(200,164,77,.8);
}

/* 오퍼줄 — 총액 표시. 🔴 등장 애니메이션을 걸지 않는다 (계획서 §7.1).
   숨겼다 보이면 price_seen(렌더 도달)이 안 보이는 것을 봤다고 센다.
   디자인으로도 맞다 — 가격은 연출하지 않는다. 그냥 거기 있다. */
.factbar {
  list-style: none; margin: 26px 0 0; padding: 0;
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px 0;
  font-family: var(--mono); font-size: 13px; color: var(--fg-2);
  letter-spacing: -0.01em;
}
.factbar li { position: relative; padding-right: 15px; margin-right: 15px; }
.factbar li:not(:last-child)::after {
  content: ''; position: absolute; right: 0; top: .1em; bottom: .1em;
  width: 1px; background: var(--line-2);
}
.factbar .price { color: var(--fg); font-size: 15px; font-weight: 500; }

/* ── 표 ─────────────────────────────────────────────────────────────────── */
table { width: 100%; border-collapse: collapse; margin: 14px 0 18px; font-size: 15px; }
caption { text-align: left; color: var(--fg-3); font-size: 13px; padding-bottom: 6px; }
th, td { text-align: left; vertical-align: top; padding: 11px 12px; border-bottom: 1px solid var(--line); }
thead th { color: var(--accent); font-weight: 500; font-size: 13px; letter-spacing: .04em; border-bottom-color: var(--line-2); }
tbody th { color: var(--fg-2); font-weight: 400; white-space: nowrap; width: 1%; }
td { color: var(--fg-2); }
td strong, th strong { color: var(--fg); }

.kv tbody th { width: 30%; }
.two-col td, .two-col th[scope="col"] { width: 50%; }
.two-col tbody th[scope="row"] { width: 22%; white-space: nowrap; }
.grid tbody tr:nth-child(odd) { background: var(--bg-3); }

/* ── 고지 블록 ───────────────────────────────────────────────────────────── */
.notice {
  background: var(--bg-2); border-left: 2px solid var(--line-2);
  padding: 16px 18px; margin: 18px 0;
}
.notice > :last-child { margin-bottom: 0; }
.notice h2, .notice h3 { margin-top: 0; font-size: 16px; }
.notice hr { border: 0; border-top: 1px solid var(--line); margin: 14px 0; }

.notice-hour       { border-left-color: var(--accent); }
.notice-sla        { border-left-color: var(--accent); }
.notice-warn       { border-left-color: var(--warn-line); }
.notice-warn strong { color: var(--warn); }

/* 🔴 청약철회 제한 — 화면⑤에서는 버튼 바로 위. 접거나 숨기지 않는다 */
.notice-withdrawal {
  border-left-color: var(--warn-line);
  border-top: 1px solid var(--line-2);
  border-right: 1px solid var(--line-2);
  border-bottom: 1px solid var(--line-2);
  background: #221B17;
}
.notice-withdrawal h2 { font-size: 17px; color: var(--fg); }
.notice-withdrawal h3 { color: var(--warn); }

/* "~하지 않습니다" 계열.
   🔴 예전엔 컬러 좌측보더였다. 같은 장치를 .notice-warn · .cta-recap 과 셋이 나눠 쓰면서
   **시각 문법이 흐려졌다** — 세 가지 다른 뜻이 같은 모양을 하고 있었다(codex 교차리뷰).
   좌측보더는 강한 경고(.notice-warn) 하나에만 예약하고, 여기는 타이포로 구분한다. */
.deny { color: var(--fg-2); }
.deny strong { color: var(--warn); font-weight: 500; }
.warn { color: var(--warn); }

.bullets { margin: 0 0 14px; padding-left: 20px; color: var(--fg-2); }
.bullets li { margin-bottom: 8px; }

/* 첫 화면 보조 링크 — CTA 버튼 아래. 버튼을 누르지 않는 사람에게 남기는 길 */
.hero-link { margin: 14px 0 0; font-size: 15px; }

/* 거래조건 6단계 흐름 — 한 줄. ⛔ 5단계로 줄이면 청약철회 경계가 사라진다 */
.steps { color: var(--fg-2); font-size: 15px; }
.steps strong { color: var(--fg); }

/* ── FAQ ────────────────────────────────────────────────────────────────── */
.qa { padding: 16px 0; border-bottom: 1px solid var(--line); }
.qa:last-child { border-bottom: 0; }
.qa .q { font-family: var(--serif); font-weight: 600; color: var(--fg); margin: 0 0 8px; }
.qa .a { color: var(--fg-2); margin: 0; }

/* ── CTA ────────────────────────────────────────────────────────────────── */
.sec-cta { border-top: 1px solid var(--line-2); }
.cta-recap {
  border-top: 1px solid var(--line);
  padding: 16px 0 0; margin: 0 0 22px;
  font-family: var(--mono); font-size: 12.5px; line-height: 1.85; color: var(--fg-2);
}
.cta-recap p { margin: 0 0 4px; }
.cta-recap p:last-child { margin: 0; }
.cta-wrap { margin: 22px 0 12px; }
.cta-after { font-size: 13.5px; color: var(--fg-3); }

/* ── 버튼 — liquid glass (참조 스펙에서 가져온 언어) ───────────────────────
   ⛔ 금색 버튼으로 되돌리지 마라. 운세 카테고리의 기본값이다 (계획서 §2.1). */
.btn {
  position: relative; isolation: isolate; overflow: hidden;
  display: inline-flex; align-items: center; justify-content: center;
  text-align: center; text-decoration: none;
  font-family: var(--sans); font-size: 15px; font-weight: 500;
  letter-spacing: -0.02em; line-height: 1;
  padding: 0 22px; min-height: 52px; border-radius: 3px;
  cursor: pointer; border: 1px solid transparent; white-space: nowrap;
  transition: background .35s ease, border-color .35s ease, box-shadow .35s ease, color .35s ease;
}
/* 훑고 지나가는 빛 — hover 에서만. 아이들 상태에서 움직이지 않는다 */
.btn::after {
  content: ''; position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(115deg, transparent 20%, rgba(255,255,255,.42) 48%, transparent 76%);
  transform: translateX(-130%); transition: transform .65s ease;
}
.btn:hover::after { transform: translateX(130%); }
.btn > * { position: relative; z-index: 2; }

.btn-primary {
  width: 100%;
  background: linear-gradient(180deg, #FFFFFF 0%, #E6EBF2 48%, #C9D5E4 100%);
  color: #0B0908; border-color: #FFFFFF;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.95);
}
.btn-primary:hover {
  background: linear-gradient(180deg, #FFFFFF 0%, #F1F5FF 42%, #D3DFF2 100%);
  border-color: #F2F6FF; color: #0B0908;
  box-shadow: inset 0 1px 0 #fff, 0 0 26px rgba(186,208,255,.34), 0 8px 20px rgba(0,0,0,.4);
}
.btn-ghost {
  background: linear-gradient(135deg, rgba(255,255,255,.10), rgba(11,9,8,.5) 46%, rgba(150,170,200,.09));
  color: var(--fg); border-color: rgba(198,212,228,.34);
  -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.12);
}
.btn-ghost:hover {
  border-color: rgba(220,232,248,.8); color: var(--fg);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.22), 0 0 24px rgba(170,200,255,.24);
}

.linklike {
  background: none; border: 0; padding: 0; font: inherit;
  color: var(--accent); text-decoration: underline; text-underline-offset: 3px; cursor: pointer;
}
.linklike:hover { color: var(--accent-2); }

/* ══ 서명 요소 — 12개월 변곡점 트랙 ═══════════════════════════════════════
   계획서 §3. 이 페이지가 기억될 단 하나의 물건이다.
   🔴 숫자는 `samples/sample-02-비교2건.md` 의 실제 계산 결과다. 꾸민 값이 아니다.
   🔴 12칸은 장식이 아니라 12개월이다. 3개가 켜지는 것은 변곡점 3개다.
   ⛔ 캐러셀·차트 라이브러리로 만들지 마라. grid 12칸 + span 3개. 의존성 0.
   ⛔ 구간에 "좋다/나쁘다"를 쓰지 마라 — 결과 보증(ⓓ)으로 재분류된다. */
.track { margin: 30px 0 0; }
.track-rail {
  position: relative;
  display: grid; grid-template-columns: repeat(12, 1fr);
  gap: 3px; height: 64px;
  border-top: 1px solid var(--line-2); border-bottom: 1px solid var(--line-2);
  padding: 8px 0;
}
.track-cell {
  background: var(--bg-2); border-radius: 1px;
  box-shadow: inset 0 -1px 0 var(--line-2);   /* 잠긴 달에도 바닥선을 준다 — 12칸이 읽혀야 12개월이다 */
}
/* 켜진 구간 — 이 페이지에서 금색이 나오는 유일한 자리다 */
.track-span {
  position: relative; border-radius: 1px;
  background: linear-gradient(180deg, rgba(200,164,77,.16), rgba(200,164,77,.5));
  box-shadow: 0 0 22px rgba(200,164,77,.16), inset 0 -1px 0 var(--ember);
}
.track-span::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: -1px;
  height: 2px; background: var(--ember);
}
.track-scale {
  display: flex; justify-content: space-between;
  font-family: var(--mono); font-size: 11px; letter-spacing: .1em;
  color: var(--fg-3); margin-top: 10px; text-transform: uppercase;
}
/* 🔴 범례는 구간 **아래에 붙는다.** 독립된 동일폭 3열 + 01/02/03 이었는데,
   날짜와 레일이 이미 순서를 말하고 있어서 번호는 같은 말을 두 번 하는 장식이었다
   (그리고 그 형태가 "AI 가 만든 레이아웃" 1순위 패턴과 같다 — codex 교차리뷰).
   ⛔ 번호를 되살리지 마라. 순서를 말하는 것은 레일과 날짜다. */
.track-legend {
  display: grid; grid-template-columns: repeat(12, 1fr);
  gap: 0; margin: 14px 0 0; padding: 0; list-style: none;
}
.track-legend li { grid-row: 1; position: relative; padding: 12px 10px 0 0; }
/* 구간에서 라벨로 내려오는 선 — 어느 구간의 라벨인지 눈이 따라간다 */
.track-legend li::before {
  content: ''; position: absolute; left: 0; top: 0; width: 1px; height: 8px;
  background: var(--line-2);
}
.track-legend .t-when {
  font-family: var(--mono); font-size: 12.5px; color: var(--fg);
  display: block; line-height: 1.45;
}
.track-legend .t-what { font-size: 12.5px; color: var(--fg-3); }

/* 근거 칩 — 리포트 본문에 실제로 박히는 코드와 같은 얼굴 */
.chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 14px 0 0; padding: 0; list-style: none; }
.chips li {
  font-family: var(--mono); font-size: 11.5px; color: var(--fg-3);
  border: 1px solid var(--line); background: var(--bg-3);
  border-radius: 2px; padding: 3px 7px;
}

/* 실물 발췌 — 🔴 이 페이지는 "진짜 근거를 보여준다"고 말한다. 말만 하면 안 된다.
   문장은 `samples/sample-01-생시미상.md` 에서 **그대로** 가져온 것이고 칩도 거기 실제로 박힌 앵커다.
   ⛔ 여기 문장을 지어내지 마라. 지어내는 순간 이 블록이 페이지의 주장을 스스로 깬다. */
.excerpt {
  margin: 22px 0 0; padding: 20px 22px;
  background: var(--bg-2); border: 1px solid var(--line);
}
.excerpt > p:first-child {
  font-family: var(--serif); font-size: 18px; line-height: 1.7; color: var(--fg); margin: 0;
}
.excerpt-src {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  margin: 14px 0 0; font-size: 12px; color: var(--fg-3);
}
.excerpt-src span {
  font-family: var(--mono); font-size: 11px;
  border: 1px solid var(--line); background: var(--bg-3);
  border-radius: 2px; padding: 2px 6px; color: var(--fg-3);
}

/* 정책 링크 행 — 가로로 붙어 있어 히트 영역을 좌우로 넓히면 서로 겹친다. 위아래만 넓힌다 */
.policy-row a { display: inline-block; }

/* 약속 3줄 — 참조 스펙의 통계 자리. 🔴 지어낸 수가 아니라 계약이 보증하는 값이다 */
.promise {
  display: flex; flex-wrap: wrap; gap: 14px 34px; margin: 30px 0 0;
  padding: 0; list-style: none;
  font-family: var(--mono); font-size: 12.5px; color: var(--fg-2);
}
.promise li { display: inline-flex; align-items: baseline; gap: 9px; }
.promise .p-v { color: var(--fg); font-size: 15px; }

/* ── 등장 모션 ───────────────────────────────────────────────────────────
   🔴 쉬는 상태의 opacity 는 1 이다. JS 나 애니메이션이 죽어도 화면은 채워져 있다.
   ⛔ .factbar 와 CTA 에는 걸지 마라 — 계획서 §7.1 (비콘이 거짓말을 하게 된다). */
.appear {
  animation-duration: 1.05s; animation-fill-mode: both;
  animation-timing-function: cubic-bezier(.16, 1, .3, 1);
  animation-delay: var(--d, .08s);
}
.appear--soft { animation-name: in-soft; }
.appear--pop  { animation-name: in-pop; }
.appear--mask { animation-name: in-mask; }
.appear.is-in { animation: none; opacity: 1; transform: none; filter: none; }
@keyframes in-soft { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
@keyframes in-pop  { 0% { opacity: 0; transform: scale(.92); } 70% { transform: scale(1.02); } 100% { opacity: 1; transform: none; } }
@keyframes in-mask { from { opacity: 0; transform: translateY(38%); } to { opacity: 1; transform: none; } }

/* ── 폼 ─────────────────────────────────────────────────────────────────── */
.form { margin: 20px 0; }
.field { margin: 0 0 22px; padding: 0; border: 0; }
fieldset.field { border: 1px solid var(--line); padding: 14px 16px; }
legend { padding: 0 6px; color: var(--fg); font-weight: 500; font-size: 15px; }

label { display: block; margin-bottom: 7px; color: var(--fg); font-size: 15px; }
.req { color: var(--fg-3); font-size: 12px; font-weight: 400; margin-left: 4px; }

input[type="text"], input[type="email"], input[type="date"], input[type="time"] {
  width: 100%; font: inherit; font-size: 16px;   /* 16px 미만이면 iOS 가 확대한다 */
  color: var(--fg); background: var(--bg-3);
  border: 1px solid var(--line-2); border-radius: 3px;
  padding: 12px 12px; min-height: 48px;
}
input::placeholder { color: #948B80; }   /* AA 4.5:1 이상 (입력칸 배경 --bg-3 기준). ⛔ 더 어둡게 내리지 않는다 */
input:focus { border-color: var(--accent); }

.help { font-size: 13px; color: var(--fg-2); margin: 7px 0 0; }
.help.deny { margin-top: 9px; }

.radio, .check {
  display: flex; align-items: flex-start; gap: 10px;
  margin: 0 0 12px; font-size: 15px; color: var(--fg-2); cursor: pointer;
}
.radio input, .check input { margin: 4px 0 0; width: 20px; height: 20px; flex: 0 0 auto; accent-color: var(--accent); }
.radio span, .check span { flex: 1; }
.checks { border-top: 1px solid var(--line); padding-top: 16px; }

.grid-3 { display: flex; flex-wrap: wrap; gap: 10px; }
.sub-field { flex: 1 1 150px; display: block; }
.sub-field label { font-size: 13px; color: var(--fg-2); }

.errors {
  border: 1px solid var(--warn-line); border-left-width: 3px;
  background: #221B17; padding: 14px 16px; margin: 0 0 20px; color: var(--warn);
}
.errors ul { margin: 6px 0 0; padding-left: 20px; }
.err-title { font-weight: 500; margin: 0; }

/* ── 주문 화면 ──────────────────────────────────────────────────────────── */
.order-no { font-family: var(--serif); color: var(--accent); letter-spacing: .04em; }
.amount { font-family: var(--serif); font-size: 30px; color: var(--fg); margin: 0 0 18px; }
.bank code { font-size: 16px; letter-spacing: .04em; }
.copy-btn {
  margin-left: 8px; font: inherit; font-size: 12px;
  background: transparent; color: var(--accent);
  border: 1px solid var(--line-2); border-radius: 3px; padding: 4px 10px; cursor: pointer;
}
.copy-btn:hover { border-color: var(--accent); }

/* ── 문서 페이지 (/sample · /compare · /policy/*) ────────────────────────── */
.sec-doc { padding-top: 26px; }
.doc-banner {
  position: sticky; top: 0; z-index: 5;
  background: var(--bg-2); border-left: 2px solid var(--accent);
  padding: 12px 16px; margin: 0 0 22px; font-size: 14px;
}
.doc-banner p { margin: 0 0 4px; }
.doc-banner p:last-child { margin: 0; }

/* 🔴 .prose 와 .k8-report 를 한 선언에 묶는다.
   공개 샘플(/sample)과 납품물(order_done.html)이 **같아 보여야** 전자상거래법 시행령
   제21조의2 '시험 사용 상품' 요건이 선다 (docs/15 §2.10). 규칙을 둘로 두면 반드시 갈린다.
   실제로 /sample·/compare·/policy/* 는 .prose 안에 .k8-report 가 중첩돼 들어온다. */
.prose, .k8-report { color: var(--fg-2); }
.prose h1, .prose h2, .prose h3, .prose h4,
.k8-report h1, .k8-report h2, .k8-report h3, .k8-report h4 {
  font-family: var(--serif); color: var(--fg);
}
.prose h2, .k8-report h2 {
  margin-top: 32px; padding-top: 20px; border-top: 1px solid var(--line); font-size: 20px;
}
.prose h3, .k8-report h3 { margin-top: 24px; font-size: 17px; }
.prose strong, .k8-report strong { color: var(--fg); font-weight: 500; }
.prose em, .k8-report em { color: var(--fg-2); }
.prose blockquote, .k8-report blockquote {
  margin: 16px 0; padding: 12px 16px;
  background: var(--bg-2); border-left: 2px solid var(--line-2);
}
.prose blockquote > :last-child, .k8-report blockquote > :last-child { margin-bottom: 0; }
.prose ul, .prose ol, .k8-report ul, .k8-report ol { padding-left: 22px; }
.prose li, .k8-report li { margin-bottom: 7px; }
.prose hr, .k8-report hr { border: 0; border-top: 1px solid var(--line); margin: 26px 0; }
.prose table, .k8-report table { font-size: 14px; }
.prose code, .k8-report code { word-break: break-all; }
/* 중첩(.prose > .k8-report)일 때 위쪽 여백이 두 번 들어가지 않게 */
.prose > .k8-report > :first-child { margin-top: 0; }

/* ── 푸터 · 하단 고정 신원 바 (요건 5) ───────────────────────────────────── */
.site-foot {
  border-top: 1px solid var(--line); margin-top: 40px;
  padding: 26px 0 30px; font-size: 13px; color: var(--fg-2);
}
.site-foot p { margin: 0 0 6px; }
.foot-name { color: var(--fg); font-family: var(--serif); }
.foot-biz { margin-top: 12px; color: var(--fg-2); }
.foot-nav { margin-top: 12px; }
.foot-bgm { margin-top: 12px; color: var(--fg-3); font-size: 12px; }

.identity-bar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 20;
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 2px 10px; justify-content: center;
  min-height: var(--bar-h);
  padding: 8px 12px calc(8px + env(safe-area-inset-bottom, 0px));
  background: #0E0C0B; border-top: 1px solid var(--line);
  font-size: 12px; line-height: 1.5; color: var(--fg-2); text-align: center;
}
.identity-bar .ib-name { color: var(--fg); }
.identity-bar a { color: var(--accent); text-decoration: none; }
.identity-bar a:hover { text-decoration: underline; }
.identity-bar .ib-sla { color: var(--fg-3); }

/* 미기재 신원항목 — 조용히 비우지 않고 눈에 보이게 둔다 (전자상거래법 제10조).
   ⛔ dev 전용 신호다. prod 는 신원표시가 비면 공개 라우트가 통째로 막힌다(config.public_blocked). */
.unset { color: var(--warn); }

/* 전화를 owner 가 명시적으로 제외했을 때의 대체 문구 (KEMI8_ACK_NO_PHONE).
   연락 수단 자체가 없어 보이면 안 되므로 자리를 비우지 않는다. 본문과 같은 톤으로 둔다. */
.contact-alt { color: var(--fg-2); }

/* ── 감정 연출 C형 (docs/20 §15) ─────────────────────────────────────────
   🔴 초기값은 opacity:1 이다. JS 가       반대로 하면 JS 가 꺼진 브라우저·크롤러·심사관에게 빈 페이지가 된다. */

  opacity: 0;
  transition: opacity .7s ease;
}

/* ⛔ 카운트다운·고조 연출 없음. opacity 전환만 쓴다 (docs/20 §15) */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    transition-duration: .001ms !important;
  }
      /* 🔴 등장 모션이 꺼져도 화면은 완전해야 한다. 빈 화면이 남으면 그건 고장이다 */
  .appear { opacity: 1 !important; transform: none !important; animation: none !important; }
  /* 그레인은 정지 이미지라 남겨도 되지만, 움직임에 민감한 사람에게는 잡음이다 */
  .grain { display: none; }
}

/* ── 데스크톱 ───────────────────────────────────────────────────────────── */
@media (min-width: 721px) {
  body { font-size: 17px; }
  .hero { padding: 120px 0 56px; }
  h1 { font-size: 31px; }
  h2 { font-size: 28px; }
  .sec { padding: 76px 0; }
  .btn-primary { width: auto; min-width: 260px; }
  .hero-actions { display: flex; gap: 12px; align-items: center; }
  .track-rail { height: 88px; }
}

/* 아주 좁은 화면(구형 최소 320px) — 여기서도 첫 화면 CTA 는 요건이다.
   🔴 실측 순서: 320×568 에서 CTA 아래끝이 하단 신원 바 위에 있어야 한다.
      숫자를 바꿀 때마다 다시 재라. 눈으로 판단하지 마라. */
@media (max-width: 380px) {
  .hero { padding-top: 46px; padding-bottom: 24px; }
  .badge { margin-bottom: 10px; padding: 6px 11px 6px 9px; }
  .hero-h1 { font-size: 30px; }
  .factbar { margin-top: 14px; font-size: 12.5px; }
  .hero-sub { font-size: 14.5px; }
}

/* 좁은 화면 — 트랙 범례가 3열로 눌리면 못 읽는다. 세로로 푼다 */
@media (max-width: 640px) {
  .track-legend { grid-template-columns: 1fr; gap: 16px; }
  .track-rail { height: 54px; }
  .promise { gap: 10px 22px; font-size: 12px; }

  /* 🔴 320×568 실측: 버튼 2개를 세로로 쌓으면 CTA 가 하단 신원 바에 49px 잘렸다.
     첫 화면 CTA 노출은 요건이라 협상 대상이 아니다 → 보조 동작을 **텍스트 링크로 낮춘다.**
     ⛔ 버튼 높이를 줄여서 맞추지 마라 — 터치 타깃 44px 아래로 내려간다. */
  .hero { padding: 74px 0 30px; min-height: 88vh; min-height: 88svh; }  /* vh 먼저, svh 나중 */
  .badge { margin-bottom: 14px; }
  .factbar { margin-top: 20px; }
  .hero-actions { display: block; }
  .hero-actions .btn-primary { width: 100%; }
  .hero-actions .btn-ghost {
    display: inline-block; width: auto; min-height: 0;
    margin-top: 14px; padding: 0; border: 0; background: none; box-shadow: none;
    -webkit-backdrop-filter: none; backdrop-filter: none;
    color: var(--accent); font-size: 15px;
    text-decoration: underline; text-underline-offset: 4px;
  }
  .hero-actions .btn-ghost::after { content: none; }
  /* 🔴 .btn 의 overflow:hidden 이 히트 영역(::before)을 **잘라낸다.**
     실측: ±5px 만 눌렸다(11px). 버튼 모양이 아닌 여기서는 클리핑이 필요 없다. */
  .hero-actions .btn-ghost { overflow: visible; }
  .hero-actions .btn-ghost:hover { box-shadow: none; color: var(--accent-2); }
}


/* ── 납품물 열람 (order_done.html) ────────────────────────────────────────
   app/report_render.py 의 to_html() 이 만든 마크업을 그대로 받는다.
     래퍼   <div class="k8-report">
     앵커칩 <code class="k8-anchor">   ← 웹 경로에는 인라인 style 이 없다(색은 여기서 정한다)

   색은 **테마를 아는 쪽**(여기)이 정한다. report_render 는 웹 경로에 인라인 style 을 박지 않는다
   (메일 경로 `inline_style=True` 만 인라인 — 메일 클라이언트는 외부 CSS 를 안 읽으니까).
   ⛔ 앵커를 숨기거나 지우지 않는다 — 공개 샘플(samples/sample-01)과 같아야
      전자상거래법 시행령 제21조의2 '시험 사용 상품' 요건이 선다 (docs/15 §2.10). */
.sec-report { border-top: 1px solid var(--line-2); }

/* 근거 앵커 칩 — 지우지 않고 시각적 무게만 낮춘다. 대비 7.48:1 (AA 이상) */
code.k8-anchor {
  font-family: var(--mono);
  font-size: .78em;
  color: #B8AE9F;
  background: #231F1B;
  border: 1px solid var(--line);
  border-radius: 3px;
  padding: 0 .3em;
  white-space: nowrap;
}

/* dev 전용 상자 — 실운영에서는 dev_mode 가 꺼져 출력되지 않는다 */
.k8-devbox { margin: 24px auto; max-width: var(--wrap); padding: 0 var(--pad); font-size: 12px; color: var(--fg-3); }

/* SLA 고지 줄 — 송금 화면·정보입력 화면에서 "언제 받나"를 결정 순간에 보여준다.
   ⛔ 카운트다운이 아니다. 숫자가 줄어드는 UI 는 불안을 만들고, 우리가 늦으면
   그 숫자가 우리를 고발한다 (계획서 2026-08-28 §4). */
.sla-line {
  margin: 1rem 0;
  padding: .75rem 1rem;
  border-left: 3px solid var(--ember);
  background: var(--bg-2);
  color: var(--fg);
  font-size: .95rem;
  line-height: 1.6;
}
.sla-line strong { color: var(--accent-2); }

/* 12개월 트랙 카드 — 리포트·샘플 맨 위. 랜딩이 그림으로 약속한 것을 결과물에서 갚는다.
   ⛔ 메일 판(인라인 style)과 마크업이 같다. 여기만 고치면 갈린다 —
      app/report_render.py:track_card_html 의 두 분기를 같이 본다. */
.track-card {
  margin: 0 0 2.5rem;
  padding: 1.6rem 1.5rem;
  background: var(--bg-2);
  border: 1px solid rgba(198,212,228,.16);
  border-radius: 14px;
}
.tc-eyebrow {
  margin: 0 0 .3rem; font-size: .72rem; letter-spacing: .16em;
  color: var(--fg-3); text-transform: uppercase; font-weight: 600;
}
.tc-title { margin: 0 0 1rem; font-family: var(--serif); font-size: 1.25rem; color: var(--fg); }
.tc-table { width: 100%; border-collapse: collapse; }
.tc-table td { padding: .38rem 0; vertical-align: top; }
.tc-mark  { font-family: var(--num); font-size: 1.05rem; color: var(--ember); padding-right: .75rem !important; white-space: nowrap; }
.tc-when  { font-weight: 600; color: var(--fg); padding-right: 1.1rem !important; white-space: nowrap; }
.tc-what  { color: var(--fg-2); }
.tc-foot  { margin: .9rem 0 0; font-size: .85rem; color: var(--fg-3); }
@media (max-width: 480px) {
  .tc-when, .tc-what { white-space: normal; }
  .tc-table td { display: block; padding: .1rem 0 !important; }
  .tc-mark { display: none !important; }
  .tc-when { padding-top: .7rem !important; }
}

/* 타임라인 막대 — 12개월 축 위에 구간을 실제 위치로 칠한다.
   ⛔ 메일 판(인라인 style)과 같은 마크업이다. 한쪽만 고치면 갈린다 —
      app/report_render.py:track_card_html 의 두 분기를 같이 본다.
   ⛔ 점수·기여도는 그리지 않는다. 본문이 일부러 피하는 정밀도를 그림이 주장하면 안 된다. */
.tc-bar { width: 100%; table-layout: fixed; border-collapse: collapse; margin: 0 0 .2rem; }
.tc-bar td {
  height: 26px; text-align: center; border-right: 1px solid var(--bg-2);
  font: 700 .72rem/26px var(--sans);
}
.tc-bar td.on  { background: var(--ember); color: #2A2110; }
.tc-bar td.off { background: rgba(255,255,255,.08); }
.tc-bar tr.tc-axis td {
  height: auto; background: none; border: 0; padding-top: .35rem;
  font: 400 .66rem/1.3 var(--sans); color: var(--fg-3);
  /* 🔴 라벨이 칸보다 넓다(2026.10 = 7자 / 칸 = 축의 1/12).
     옆 칸이 비어 있으므로 넘쳐도 겹치지 않는다 — 자르지 말고 넘치게 둔다.
     ⛔ overflow:hidden 을 넣으면 연도가 잘려 owner 가 지적한 문제로 되돌아간다. */
  white-space: nowrap; overflow: visible;
}
@media (max-width: 480px) {
  .tc-bar td { height: 20px; font-size: .62rem; line-height: 20px; }
  /* 폰에서는 칸이 ~25px 라 `2026.10` 이 두 칸을 먹는다. 글자를 더 줄이고
     자간을 좁혀 옆 라벨과 부딪히지 않게 한다. */
  .tc-bar tr.tc-axis td { font-size: .5rem; letter-spacing: -.02em; }
}
